BigMarker-抽奖前置规则过滤

需求

在我们的流程设计中,用户执行抽奖时会判断是否已经超过N积分,如果超过N积分则可以在限定范围内进行抽奖。同时如果用户是黑名单范围的羊毛党用户,则只返回固定的奖品ID

模型

  1. 整个规则来说,分为抽奖前、抽奖中、抽奖后,三个阶段执行。本节我们先来处理抽奖前的规则。
  2. 在工程分包上,需要添加 rule 来处理抽奖规则,在添加 raffle 处理抽奖过程。

前置规则判断根据现有的积分决定能抽到什么,以及黑名单

新增实体

RaffleAwardEntity:抽奖结束后要返回一个奖品直接返回一些key交给后续Award有关的列进行处理

RaffleFactorEntity:抽奖因子(参数)抽奖策略接口的参数

RaffleActionEntity:返回一个对象实体,用于你抽奖前后的操作,如抽奖之前是否有解锁,

分为抽奖前过滤规则,抽奖中过滤规则,抽奖后过滤规则(如抽到了但未解锁,返回随机积分)

定义了一个名为RuleActionEntity的泛型类,其中泛型类型T必须是RuleActionEntity.RaffleEntity的子类。同时,该类内部还定义了四个静态内部类:RaffleEntityRaffleBeforeEntityRaffleCenterEntityRaffleAfterEntity,它们都是RaffleEntity的子类。

这些类用于表示不同的抽奖阶段或状态。,RaffleBeforeEntity表示抽奖开始前的状态,RaffleCenterEntity表示抽奖进行中的状态,而RaffleAfterEntity表示抽奖结束后的状态。

重新回答

||

RuleMatterRntity: 用于过滤和过滤接口配合使用

过滤接口

抽奖策略接口——传入因子放回奖品key

RaffleActionEntity:放回一些要用到的参数如权重值策略id还有用于黑名单的奖品id100

@Getter
@AllArgsConstructor
public enum RuleLogicCheckTypeVO {ALLOW("0000", "放行;执行后续的流程,不受规则引擎影响"),TAKE_OVER("0001","接管;后续的流程,受规则引擎执行结果影响"),;private final String code;private final String info;}

控制如何进行下一步这是一个Java枚举类,名为RuleLogicCheckTypeVO。它有两个枚举值:ALLOW和TAKE_OVER。每个枚举值都有一个对应的code和info属性。这个枚举类用于表示规则引擎的逻辑检查类型

public interface ILogicFilter<T extends RuleActionEntity.RaffleEntity> {RuleActionEntity<T> filter(RuleMatterEntity ruleMatterEntity);}

这里抽奖规则过滤接口 用RuleActionEntity要注意基础应为RuleActionEntity规定了,这样就可以返回一个RuleActionEntity的对象,具体是什么取决于具体场景

建立一个工厂方便规则,以及接口实现  annotation方便注入

完整代码详细理解

package org.example.domain.strategy.model.entity;import lombok.*;
import org.example.domain.strategy.model.vo.RuleLogicCheckTypeVO;/*** @author xy* @description 返回一个对象实体,用于返回之后的操作*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class RuleActionEntity<T extends RuleActionEntity.RaffleEntity> {private String code= RuleLogicCheckTypeVO.ALLOW.getCode();private String info=RuleLogicCheckTypeVO.ALLOW.getInfo();private String ruleModel;private T data;static public class RaffleEntity{}@EqualsAndHashCode(callSuper = true)@Data@AllArgsConstructor@NoArgsConstructor@Builder/**抽奖前*/static public class RaffleBeforeEntity extends RaffleEntity{/**策略id*/private Long strategyId;/**权重值:用于抽奖可以选择权重*/private String ruleWeightValueKey;/**奖品ID*/private Integer awardId;}/**抽奖中*/static public class RaffleCenterEntity extends RaffleEntity{}/**抽奖后*/static public class RaffleAfterEntity extends RaffleEntity{}}

包含了一些属性和方法。这个类使用了Lombok库来简化代码,提供了@Data、@AllArgsConstructor、@NoArgsConstructor和@Builder注解。这个类还定义了一个内部类RaffleEntity,以及三个继承自RaffleEntity的内部类:RaffleBeforeEntity、RaffleCenterEntity和RaffleAfterEntity。这些内部类分别表示抽奖前、抽奖中和抽奖后的操作。还规定了泛型,还有code和info用来输出到控制台以及后续的筛查

@EqualsAndHashCode(callSuper = true)
//,用于自动生成 equals 和 hashCode 方法。当一个类继承了另一个类时,
// 如果想让子类的 equals 和 hashCode 方法同时考虑父类的属性,就需要在子类上使用这个注解
//将callSuper属性设置为true。这样,在生成的equals和hashCode方法中,会先调用父类的相应方法,然后再考虑子类的字段

/*** @author xy* @description*/
@Slf4j
public abstract class AbstractRaffleStrategy implements IRaffleStrategy {//策略仓储服务-》domain层像一个大厨,仓储层提供米面油盐protected IStrategyRepository repository;//策略调度服务-》只负责抽奖处理,通过调用接口的方式,隔离职责,不需要使用方关心或者调用抽奖的初始化protected IStrategyDispatch strategyDispatch;public AbstractRaffleStrategy(IStrategyRepository repository, IStrategyDispatch strategyDispatch) {this.repository = repository;this.strategyDispatch = strategyDispatch;}@Overridepublic RaffleAwardEntity performRaffle(RaffleFactorEntity raffleFactorEntity) {// 1. 参数校验String userId = raffleFactorEntity.getUserId();Long strategyId = raffleFactorEntity.getStrategyId();if (null == strategyId || StringUtils.isBlank(userId)) {throw new AppException(ResponseCode.ILLEGAL_PARAMETER.getCode(), ResponseCode.ILLEGAL_PARAMETER.getInfo());}// 2. 策略查询 得到了 id 模型 即strategy策略表的内容StrategyEntity strategy = repository.queryStrategyEntityByStrategyId(strategyId);// 3. 抽奖前 - 规则过滤RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> ruleActionEntity = this.doCheckRaffleBeforeLogic(RaffleFactorEntity.builder().userId(userId).strategyId(strategyId).build(), strategy.ruleModels());if (RuleLogicCheckTypeVO.TAKE_OVER.getCode().equals(ruleActionEntity.getCode())) {if (DefaultLogicFactory.LogicModel.RULE_BLACKLIST.getCode().equals(ruleActionEntity.getRuleModel())) {// 黑名单返回固定的奖品IDreturn RaffleAwardEntity.builder().awardId(ruleActionEntity.getData().getAwardId()).build();} else if (DefaultLogicFactory.LogicModel.RULE_WIGHT.getCode().equals(ruleActionEntity.getRuleModel())) {// 权重根据返回的信息进行抽奖RuleActionEntity.RaffleBeforeEntity raffleBeforeEntity = ruleActionEntity.getData();String ruleWeightValueKey = raffleBeforeEntity.getRuleWeightValueKey();Integer awardId = strategyDispatch.getRandomAwardId(strategyId, ruleWeightValueKey);return RaffleAwardEntity.builder().awardId(awardId).build();}}// 4. 默认抽奖流程Integer awardId = strategyDispatch.getRandomAwardId(strategyId);return RaffleAwardEntity.builder().awardId(awardId).build();}protected abstract RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> doCheckRaffleBeforeLogic(RaffleFactorEntity build, String ...logics);
}

AbstractRaffleStrategy,实现了IRaffleStrategy接口。它主要用于处理抽奖策略的逻辑。在这个类中,定义了一些成员变量,如repositorystrategyDispatch,分别用于存储策略数据和执行抽奖操作。同时,提供了一个构造函数,用于初始化这两个成员变量。

performRaffle方法是这个类的核心方法,用于执行抽奖操作。它首先对输入参数进行校验,然后查询策略信息,接着根据策略规则进行过滤。如果满足某些条件,可以直接返回奖品ID;否则,按照默认的抽奖流程进行抽奖。最后,返回抽奖结果。

在这个Java代码中,使用protected关键字来修饰成员变量(如repositorystrategyDispatch)和方法(如doCheckRaffleBeforeLogicprotected关键字允许子类和同一个包中的其他类访问这些成员。这意味着,当我们创建一个继承自AbstractRaffleStrategy的子类时,这个子类可以直接访问父类中的protected成员,而无需通过公共接口(即public方法)。

package org.example.domain.strategy.service.raffle;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.example.domain.strategy.model.entity.RaffleFactorEntity;
import org.example.domain.strategy.model.entity.RuleActionEntity;
import org.example.domain.strategy.model.entity.RuleMatterEntity;
import org.example.domain.strategy.model.vo.RuleLogicCheckTypeVO;
import org.example.domain.strategy.repository.IStrategyRepository;
import org.example.domain.strategy.service.amory.IStrategyDispatch;
import org.example.domain.strategy.service.rule.ILogicFilter;
import org.example.domain.strategy.service.rule.factory.DefaultLogicFactory;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;/*** @author xy* @description*/
@Slf4j
@Service
public class DefaultRaffleStrategy extends AbstractRaffleStrategy{@Resourceprivate DefaultLogicFactory logicFactory;public DefaultRaffleStrategy(IStrategyRepository repository, IStrategyDispatch strategyDispatch) {super(repository, strategyDispatch);}@Overrideprotected RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> doCheckRaffleBeforeLogic(RaffleFactorEntity raffleFactorEntity, String... logics) {Map<String, ILogicFilter<RuleActionEntity.RaffleBeforeEntity>> logicFilterGroup = logicFactory.openLogicFilter();// 黑名单规则优先过滤String ruleBackList = Arrays.stream(logics).filter(str -> str.contains(DefaultLogicFactory.LogicModel.RULE_BLACKLIST.getCode())).findFirst().orElse(null);if (StringUtils.isNotBlank(ruleBackList)) {ILogicFilter<RuleActionEntity.RaffleBeforeEntity> logicFilter = logicFilterGroup.get(DefaultLogicFactory.LogicModel.RULE_BLACKLIST.getCode());RuleMatterEntity ruleMatterEntity = new RuleMatterEntity();ruleMatterEntity.setUserId(raffleFactorEntity.getUserId());ruleMatterEntity.setAwardId(ruleMatterEntity.getAwardId());ruleMatterEntity.setStrategyId(raffleFactorEntity.getStrategyId());ruleMatterEntity.setRuleModel(DefaultLogicFactory.LogicModel.RULE_BLACKLIST.getCode());RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> ruleActionEntity = logicFilter.filter(ruleMatterEntity);if (!RuleLogicCheckTypeVO.ALLOW.getCode().equals(ruleActionEntity.getCode())) {return ruleActionEntity;}}// 顺序过滤剩余规则List<String> ruleList = Arrays.stream(logics).filter(s -> !s.equals(DefaultLogicFactory.LogicModel.RULE_BLACKLIST.getCode())).collect(Collectors.toList());RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> ruleActionEntity = null;for (String ruleModel : ruleList) {ILogicFilter<RuleActionEntity.RaffleBeforeEntity> logicFilter = logicFilterGroup.get(ruleModel);RuleMatterEntity ruleMatterEntity = new RuleMatterEntity();ruleMatterEntity.setUserId(raffleFactorEntity.getUserId());ruleMatterEntity.setAwardId(ruleMatterEntity.getAwardId());ruleMatterEntity.setStrategyId(raffleFactorEntity.getStrategyId());ruleMatterEntity.setRuleModel(ruleModel);ruleActionEntity = logicFilter.filter(ruleMatterEntity);// 非放行结果则顺序过滤log.info("抽奖前规则过滤 userId: {} ruleModel: {} code: {} info: {}", raffleFactorEntity.getUserId(), ruleModel, ruleActionEntity.getCode(), ruleActionEntity.getInfo());if (!RuleLogicCheckTypeVO.ALLOW.getCode().equals(ruleActionEntity.getCode())) return ruleActionEntity;}return ruleActionEntity;}
}

这段代码是一个名为`DefaultRaffleStrategy`的Java类,它继承了`AbstractRaffleStrategy`抽象类。这个类主要用于处理抽奖策略的逻辑。在这个类中,定义了一个名为`doCheckRaffleBeforeLogic`的方法,该方法接收一个`RaffleFactorEntity`对象和一个可变参数`logics`,用于检查抽奖前的逻辑。

方法首先创建一个名为`logicFilterGroup`的映射,用于存储不同类型的逻辑过滤器。然后,它会检查传入的`logics`数组中是否包含黑名单规则(`RULE_BLACKLIST`),如果包含,则使用相应的逻辑过滤器对用户进行过滤。如果过滤结果不是允许(`ALLOW`),则直接返回过滤结果。

接下来,方法会过滤剩余的规则,并依次应用这些规则。对于每个规则,它会从`logicFilterGroup`中获取相应的逻辑过滤器,然后使用该过滤器对用户进行过滤。如果过滤结果不是允许(`ALLOW`),则立即返回过滤结果。

最后,如果所有规则都通过了过滤,方法将返回最后一个规则的过滤结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3246500.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

无人机之机型区别与应用领域

一、多旋翼无人机 特点&#xff1a;多旋翼无人机依靠产生升力以平衡飞行器的重力&#xff0c;通过改变每个旋翼的转速来控制飞行姿态&#xff0c;能够悬停和垂直起降。他们具备体积小、重量轻、噪音小、隐蔽性好的特点&#xff0c;操作灵活且易于维护。 应用&#xff1a;多旋…

数据库(创建数据库和表)

目录 一&#xff1a;创建数据库 二&#xff1a;创建表 2.1&#xff1a;创建employees表 2.2&#xff1a;创建orders表 2.3&#xff1a;创建invoices表 一&#xff1a;创建数据库 mysql> create database mydb6_product; Query OK, 1 row affected (0.01 sec) mysql&g…

排序——归并排序及排序章节总结

前面的文章中 我们详细介绍了排序的概念&#xff0c;插入排序&#xff0c;交换排序与选择排序&#xff0c;大家可以通过下面的链接再去学习&#xff1a; ​​​​​​排序的概念及插入排序 交换排序 选择排序 这篇文章就详细介绍一下另一种排序算法&#xff1a;归并排序以及…

鼠标宏编辑有什么作用?通用鼠标宏软件下载

你知道鼠标宏编辑吗&#xff1f;鼠标宏编辑是电脑鼠标连点器内一种常用功能。用户通过鼠标宏编辑可以很好提高效率。本文将深入探讨鼠标宏编辑的定义、作用及其在不同领域的应用&#xff0c;带您了解它的重要性和实际价值。并整理了2024年最新款的6大好用鼠标宏软件&#xff0c…

FPGA实训报告DAY 1(Verilog HDL)

实习日志与总结 日期&#xff1a;2024 年 7 月 10 日 星期三 姓名&#xff1a;XXX 一、实习日志 上午 9:00 - 9:30 按时到达工位&#xff0c;参加部门早会&#xff0c;了解了今天的实习任务和目标&#xff0c;即初步学习 FPGA 简介和 Verilog 基础语法知识。 9:30 - 10:30…

大数据基础:Doris重点架构原理

文章目录 Doris重点架构原理 一、Apache Doris介绍 二、Apache Doris使用场景 三、Apache Doris架构原理 四、Apache Doris 特点 Doris重点架构原理 一、Apache Doris介绍 基于 MPP 架构的高性能、实时的分析型数据库&#xff0c;以极速易用的特点被人们所熟知&#xff…

嵌入式人工智能(7-树莓派4B的IIC总线连接OLED显示中文与图片)

1、IIC总线 IIC总线&#xff08;Inter-Integrated Circuit&#xff09;是一种串行通信总线&#xff0c;也被称为I2C总线。它由飞利浦&#xff08;Philips&#xff09;公司在1980年代开发&#xff0c;用于连接微处理器和外部设备。 IIC总线使用两根信号线&#xff1a;SDA&…

【JavaScript 算法】树的遍历:前序、中序与后序

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、前序遍历&#xff08;Preorder Traversal&#xff09;前序遍历的步骤前序遍历的JavaScript实现 二、中序遍历&#xff08;Inorder Traversal&#xff09;中序遍历的步骤中序遍历的JavaScript实现 三、后序遍历&#xff…

朴素模式匹配算法与KMP算法(非重点)

目录 一. 朴素模式匹配算法1.1 什么是字符串的匹配模式1.2 朴素模式匹配算法1.3 通过数组下标实现朴素模式匹配算法 二. KMP算法2.1 算法分析2.2 用代码实现&#xff08;只会出现在选择题&#xff0c;考察代码的概率不大&#xff09; 三. 手算next数组四. KMP算法的进一步优化4…

springboot2.x AOP 默认使用Cglib 源码

一、背景 在 SpringBoot 2.x AOP中会默认使用Cglib来实现&#xff0c;但是Spring5中默认还是使用jdk动态代理。Spring AOP 默认使用 JDK 动态代理&#xff0c;如果对象没有实现接口&#xff0c;则使用 CGLIB 代理。也可以强制使用 CGLIB 代理。springboot默认使用cglib实现代码…

在GPU上运行PyTorch

文章目录 1、查看GPU的CUDA版本2、下载CUDA版本3、安装cuDNN4、配置CUDA环境变量5、安装配置Anaconda6、使用Anaconda7、pycharm导入虚拟环境8、安装带GPU的PyTorch⭐9、总结 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#x…

使用assembly插件来将外部文件夹打进jar包

目录&#xff1a; 1、pom文件的配置2、新建assembly的描述文件3、maven打包 1、pom文件的配置 <!--maven构建--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</ar…

python自动化之用flask校验接口token(把token作为参数)

用到的库&#xff1a;flask 实现效果: 写一个接口&#xff0c;需要token正确才能登录 代码&#xff1a; # 导包 from flask import Flask,request,jsonify,json # 创建一个服务 appFlask(__name__) # post请求&#xff0c;路径&#xff1a;/query app.route(/query, met…

ESP32部署TensorFlow Lite

本来是想找一篇中文教程&#xff0c;不过只看到一个英文官方的&#xff0c;也行吧&#xff0c;虽然效率会慢丢丢。 GitHub - espressif/esp-tflite-micro: TensorFlow Lite Micro for Espressif Chipsets 看了一圈&#xff0c;有个中文的&#xff1a; esp-dl/README_cn.md a…

C语言 ——— 编写代码,判断 整型数组 是否 有序

目录 题目要求 代码实现 题目要求 判断 整型数组 是否有序 如果 整型数组 有序输出 sorted&#xff1b;否则输出 unsorted 代码实现 #include<stdio.h> int main() {int arr[10] { 0 };int sz sizeof(arr) / sizeof(arr[0]);//输入for (int i 0; i < sz; i){s…

5个超牛的Java开源OA项目(强烈推荐)

1. O2OA ——开源地址&#xff1a;https://gitee.com/o2oa/O2OA 概述&#xff1a; O2OA 是一款真正全代码&#xff08;包含服务器、安卓以及IOS客户端&#xff09;开源的企业应用定制化开发平台&#xff0c;适用于企业OA、协同办公类信息化系统的建设和开发。技术&#xff1a;…

【JavaScript 算法】栈与队列:解决括号匹配问题

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、算法原理二、算法实现三、应用场景四、总结 在编程中&#xff0c;括号匹配问题是一类常见的算法题&#xff0c;通常用于验证括号的正确性&#xff0c;即检查括号是否成对出现且嵌套正确。栈&#xff08;Stack&#xff0…

Uniapp基础篇(持续更新)

1. Uni-app常用内置组件 view 视图容器 scroll-view 可滚动视图区域&#xff0c;用于区域滚动。需注意在webview渲染的页面中&#xff0c;区域滚动的性能不及页面滚动。 swiper 滑块视图容器。一般用于左右滑动或上下滑动&#xff0c;比如banner轮播图。 image uniapp官方iam…

软件测试——非功能测试

工作职责&#xff1a; 1.负责产品系统测试&#xff0c;包括功能测试、性能测试、稳定性测试、用户场景测试、可靠性测试等。 2.负责测试相关文档的编写&#xff0c;包括测试计划、测试用例、测试报告等。 3.负责自动化测试框架、用例的维护。 岗位要求&#xff1a; 1.熟练…

微软的vscode和vs2022快捷键官网链接

vscode官方文档:https://code.visualstudio.com/docs/ vscode快捷键官方文档:https://code.visualstudio.com/docs/getstarted/keybindings vs2022官方文档:https://learn.microsoft.com/zh-cn/visualstudio/ide/?viewvs-2022 vscode快捷键官方文档:https://learn.microsoft.c…