提交 070b7cdd 编写于 作者: H hudingrong

before_filter_prule

上级 d9161499
...@@ -24,5 +24,12 @@ ...@@ -24,5 +24,12 @@
from strategy_rule from strategy_rule
where strategy_id = #{strategyId} and rule_model = #{ruleModel} where strategy_id = #{strategyId} and rule_model = #{ruleModel}
</select> </select>
<select id="queryStrategyRuleValue" parameterType="cn.bugstack.infrastructure.persistent.po.StrategyRule" resultType="java.lang.String">
select rule_value from strategy_rule
where strategy_id = #{strategyId} and rule_model = #{ruleModel}
<if test="awardId != null">
and award_id = #{awardId}
</if>
</select>
</mapper> </mapper>
...@@ -16,4 +16,11 @@ public class ApiTest { ...@@ -16,4 +16,11 @@ public class ApiTest {
log.info("测试完成"); log.info("测试完成");
} }
@Test
public void test1() {
String testSplit = "abc 123";
String[] s = testSplit.split("d");
System.out.println(s[0]);
}
} }
package cn.bugstack.test.domain;
import cn.bugstack.domain.strategy.model.entity.RaffleAwardEntity;
import cn.bugstack.domain.strategy.model.entity.RaffleFactorEntity;
import cn.bugstack.domain.strategy.service.IRaffleStrategy;
import cn.bugstack.domain.strategy.service.rule.impl.RuleWeightLogicFilter;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.util.ReflectionTestUtils;
import javax.annotation.Resource;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 抽奖策略测试
* @create 2024-01-06 13:28
*/
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class RaffleStrategyTest {
@Resource
private IRaffleStrategy raffleStrategy;
@Resource
private RuleWeightLogicFilter ruleWeightLogicFilter;
@Before
public void setUp() {
ReflectionTestUtils.setField(ruleWeightLogicFilter, "userScore", 40500L);
}
@Test
public void test_performRaffle() {
RaffleFactorEntity raffleFactorEntity = RaffleFactorEntity.builder()
.userId("xiaofuge")
.strategyId(100001L)
.build();
RaffleAwardEntity raffleAwardEntity = raffleStrategy.performRaffle(raffleFactorEntity);
log.info("请求参数:{}", JSON.toJSONString(raffleFactorEntity));
log.info("测试结果:{}", JSON.toJSONString(raffleAwardEntity));
}
@Test
public void test_performRaffle_blacklist() {
RaffleFactorEntity raffleFactorEntity = RaffleFactorEntity.builder()
.userId("user003") // 黑名单用户 user001,user002,user003
.strategyId(100001L)
.build();
RaffleAwardEntity raffleAwardEntity = raffleStrategy.performRaffle(raffleFactorEntity);
log.info("请求参数:{}", JSON.toJSONString(raffleFactorEntity));
log.info("测试结果:{}", JSON.toJSONString(raffleAwardEntity));
}
}
package cn.bugstack.domain.strategy.model.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @description: 策略结果实体
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.model.entity
* @DATE: 2024/4/12
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AwardEntity {
/** 用户ID */
private String userId;
/** 奖品ID */
private Integer awardId;
}
package cn.bugstack.domain.strategy.model.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @description: 抽奖奖品实体
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.model.entity
* @DATE: 2024/4/12
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RaffleAwardEntity {
/**
* 策略Id
*/
private Long strategyId;
/**
* 奖品ID
*/
private Integer awardId;
/**
* 奖品对接标识 - 每一个都是一个对应的发奖策略
*/
private String awardKey;
/**
* 奖品配置信息
*/
private String awardConfig;
/**
* 奖品内容描述
*/
private String awardDesc;
}
package cn.bugstack.domain.strategy.model.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @description: 抽奖因子实体
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.model.entity
* @DATE: 2024/4/12
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RaffleFactorEntity {
/** 用户ID */
private String userId;
/** 策略ID */
private Long strategyId;
}
package cn.bugstack.domain.strategy.model.entity;
import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO;
import lombok.*;
/**
* @description: 规则动作实体
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.model.entity
* @DATE: 2024/4/12
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
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
@Builder
@AllArgsConstructor
@NoArgsConstructor
static public class RaffleBeforeEntity extends RaffleEntity {
/**
* 策略ID
*/
private Long strategyId;
/**
* 权重值Key;用于抽奖时可以选择权重抽奖。
*/
private String ruleWeightValueKey;
/**
* 奖品ID;
*/
private Integer awardId;
}
// 抽奖之中
static public class RaffleCenterEntity extends RaffleEntity {
}
// 抽奖之后
static public class RaffleAfterEntity extends RaffleEntity {
}
}
package cn.bugstack.domain.strategy.model.entity;
import lombok.Data;
/**
* @description: 规则物料实体对象,用于过滤规则的必要参数信息。
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.model.entity
* @DATE: 2024/4/12
*/
@Data
public class RuleMatterEntity {
/** 用户ID */
private String userId;
/** 策略ID */
private Long strategyId;
/** 抽奖奖品ID【规则类型为策略,则不需要奖品ID】 */
private Integer awardId;
/** 抽奖规则类型【rule_random - 随机值计算、rule_lock - 抽奖几次后解锁、rule_luck_award - 幸运奖(兜底奖品)】 */
private String ruleModel;
}
package cn.bugstack.domain.strategy.model.valobj;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @description: 规则过滤校验类型值对象
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.model.entity.valobj
* @DATE: 2024/4/12
*/
@Getter
@AllArgsConstructor
public enum RuleLogicCheckTypeVO {
ALLOW("0000", "放行;执行后续的流程,不受规则引擎影响"),
TAKE_OVER("0001","接管;后续的流程,受规则引擎执行结果影响"),
;
private final String code;
private final String info;
}
...@@ -67,4 +67,13 @@ public interface IStrategyRepository { ...@@ -67,4 +67,13 @@ public interface IStrategyRepository {
* @return * @return
*/ */
int getRateRange(String key); int getRateRange(String key);
/**
* 查询策略规则值
* @param strategyId 策略id
* @param awardId 奖品id
* @param ruleModel 规则模型
* @return
*/
String queryStrategyRuleValue(Long strategyId, Integer awardId, String ruleModel);
} }
package cn.bugstack.domain.strategy.service;
import cn.bugstack.domain.strategy.model.entity.RaffleAwardEntity;
import cn.bugstack.domain.strategy.model.entity.RaffleFactorEntity;
/**
* @description: 抽奖策略接口
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service
* @DATE: 2024/4/11
*/
public interface IRaffleStrategy {
/**
* 执行抽奖:用抽奖影子入参,执行抽奖计算,返回奖品信息
* @param raffleFactorEntity 抽奖因子实体
* @return 抽奖的奖品
*/
RaffleAwardEntity performRaffle(RaffleFactorEntity raffleFactorEntity);
}
package cn.bugstack.domain.strategy.service.annotation;
import cn.bugstack.domain.strategy.service.rule.factory.DefaultLogicFactory;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 策略自定义枚举
* @create 2023-12-31 11:29
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogicStrategy {
DefaultLogicFactory.LogicModel logicMode();
}
package cn.bugstack.domain.strategy.service.raffle;
import cn.bugstack.domain.strategy.model.entity.RaffleAwardEntity;
import cn.bugstack.domain.strategy.model.entity.RaffleFactorEntity;
import cn.bugstack.domain.strategy.model.entity.RuleActionEntity;
import cn.bugstack.domain.strategy.model.entity.StrategyEntity;
import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO;
import cn.bugstack.domain.strategy.repository.IStrategyRepository;
import cn.bugstack.domain.strategy.service.IRaffleStrategy;
import cn.bugstack.domain.strategy.service.armory.IStrategyDispatch;
import cn.bugstack.domain.strategy.service.rule.factory.DefaultLogicFactory;
import cn.bugstack.domain.strategy.service.rule.impl.RuleBackListLogicFilter;
import cn.bugstack.types.enums.ResponseCode;
import cn.bugstack.types.exception.AppException;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
/**
* @description:
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.raffle
* @DATE: 2024/4/12
*/
@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;
}
@Override
public 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. 策略查询
StrategyEntity strategy = repository.queryStrategyEntityByStrategyId(strategyId) ;
// 3. 抽奖前 - 规则过滤
RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> ruleActionEntity = this.doCheckRaffleBeforeLogic(RaffleFactorEntity.builder()
.userId(userId)
.strategyId(strategyId)
.build(), strategy.ruleModels());
log.info("ruleActionEntity:{}", JSON.toJSONString(ruleActionEntity));
if (RuleLogicCheckTypeVO.TAKE_OVER.getCode().equals(ruleActionEntity.getCode())) {
if (DefaultLogicFactory.LogicModel.RULE_BLACKLIST.getCode().equals(ruleActionEntity.getRuleModel())) {
// 黑名单返回固定的奖品ID
return RaffleAwardEntity.builder()
.awardId(ruleActionEntity.getData().getAwardId())
.build();
} else if (DefaultLogicFactory.LogicModel.RULE_WIGHT.getCode().equals(ruleActionEntity.getRuleModel())) {
// 权重根据返回的信息进行抽奖
System.out.println("权重抽奖");
RuleActionEntity.RaffleBeforeEntity raffleBeforeEntity = ruleActionEntity.getData();
String ruleWeightValueKey = raffleBeforeEntity.getRuleWeightValueKey();
Integer awardId = strategyDispatch.getRandomAwardId(strategyId,ruleWeightValueKey);
return RaffleAwardEntity.builder()
.awardId(awardId)
.build();
}
}
// 4. 默认抽奖流程
System.out.println("默认抽奖");
Integer awardId = strategyDispatch.getRandomAwardId(strategyId);
return RaffleAwardEntity.builder()
.awardId(awardId)
.build();
}
protected abstract RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> doCheckRaffleBeforeLogic(RaffleFactorEntity factorEntity, String... logics);
}
package cn.bugstack.domain.strategy.service.raffle;
import cn.bugstack.domain.strategy.model.entity.RaffleFactorEntity;
import cn.bugstack.domain.strategy.model.entity.RuleActionEntity;
import cn.bugstack.domain.strategy.model.entity.RuleMatterEntity;
import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO;
import cn.bugstack.domain.strategy.repository.IStrategyRepository;
import cn.bugstack.domain.strategy.service.armory.IStrategyDispatch;
import cn.bugstack.domain.strategy.service.rule.ILogicFilter;
import cn.bugstack.domain.strategy.service.rule.factory.DefaultLogicFactory;
import com.alibaba.fastjson.JSON;
import com.sun.deploy.security.ruleset.RuleAction;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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;
/**
* @description:
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.raffle
* @DATE: 2024/4/12
*/
@Slf4j
@Service
public class DefaultRaffleStrategy extends AbstractRaffleStrategy{
@Resource
private DefaultLogicFactory logicFactory;
public DefaultRaffleStrategy(IStrategyRepository repository, IStrategyDispatch strategyDispatch) {
super(repository, strategyDispatch);
}
@Override
protected RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> doCheckRaffleBeforeLogic(RaffleFactorEntity raffleFactorEntity, String... logics) {
log.info("raffleFactorEntity:{},logics:{}", JSON.toJSONString(raffleFactorEntity),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(str-> !str.contains(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());
// todo 数据不对
ruleMatterEntity.setAwardId(ruleMatterEntity.getAwardId());
ruleMatterEntity.setStrategyId(raffleFactorEntity.getStrategyId());
ruleMatterEntity.setRuleModel(ruleModel);
ruleActionEntity = logicFilter.filter(ruleMatterEntity);
log.info("ruleActionEntity:{}",JSON.toJSONString(ruleActionEntity));
log.info("抽奖前规则过滤 userId: {} ruleModel: {} code: {} info: {}", raffleFactorEntity.getUserId(), ruleModel, ruleActionEntity.getCode(), ruleActionEntity.getInfo());
if (!RuleLogicCheckTypeVO.ALLOW.getCode().equals(ruleActionEntity.getCode())) {
return ruleActionEntity;
}
}
return ruleActionEntity;
}
}
package cn.bugstack.domain.strategy.service.rule;
import cn.bugstack.domain.strategy.model.entity.RuleActionEntity;
import cn.bugstack.domain.strategy.model.entity.RuleMatterEntity;
/**
* @description: 抽奖规则过滤接口
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule
* @DATE: 2024/4/12
*/
public interface ILogicFilter<T extends RuleActionEntity.RaffleEntity> {
RuleActionEntity<T> filter(RuleMatterEntity ruleMatterEntity);
}
package cn.bugstack.domain.strategy.service.rule.factory;
import cn.bugstack.domain.strategy.model.entity.RuleActionEntity;
import cn.bugstack.domain.strategy.service.annotation.LogicStrategy;
import cn.bugstack.domain.strategy.service.rule.ILogicFilter;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @description: 规则工厂
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule.factory
* @DATE: 2024/4/12
*/
@Service
public class DefaultLogicFactory {
public Map<String, ILogicFilter<?>> logicFilterMap = new ConcurrentHashMap<>();
public DefaultLogicFactory(List<ILogicFilter<?>> logicFilters) {
logicFilters.forEach(logic -> {
LogicStrategy strategy = AnnotationUtils.findAnnotation(logic.getClass(), LogicStrategy.class);
if (null != strategy) {
logicFilterMap.put(strategy.logicMode().getCode(), logic);
}
});
}
public <T extends RuleActionEntity.RaffleEntity> Map<String, ILogicFilter<T>> openLogicFilter() {
return (Map<String, ILogicFilter<T>>) (Map<?, ?>) logicFilterMap;
}
@Getter
@AllArgsConstructor
public enum LogicModel {
RULE_WIGHT("rule_weight","【抽奖前规则】根据抽奖权重返回可抽奖范围KEY"),
RULE_BLACKLIST("rule_blacklist","【抽奖前规则】黑名单规则过滤,命中黑名单则直接返回"),
;
private final String code;
private final String info;
}
}
package cn.bugstack.domain.strategy.service.rule.impl;
import cn.bugstack.domain.strategy.model.entity.RuleActionEntity;
import cn.bugstack.domain.strategy.model.entity.RuleMatterEntity;
import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO;
import cn.bugstack.domain.strategy.repository.IStrategyRepository;
import cn.bugstack.domain.strategy.service.annotation.LogicStrategy;
import cn.bugstack.domain.strategy.service.rule.ILogicFilter;
import cn.bugstack.domain.strategy.service.rule.factory.DefaultLogicFactory;
import cn.bugstack.types.common.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @description: [抽奖前规则]黑名单用户过滤规则
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule.impl
* @DATE: 2024/4/12
*/
@Slf4j
@Component
@LogicStrategy(logicMode = DefaultLogicFactory.LogicModel.RULE_BLACKLIST)
public class RuleBackListLogicFilter implements ILogicFilter<RuleActionEntity.RaffleBeforeEntity> {
@Resource
private IStrategyRepository repository;
@Override
public RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> filter(RuleMatterEntity ruleMatterEntity) {
log.info("规则过滤-黑名单 userId:{} strategyId:{} ruleModel:{}", ruleMatterEntity.getUserId(), ruleMatterEntity.getStrategyId(), ruleMatterEntity.getRuleModel());
String userId = ruleMatterEntity.getUserId();
// 100:user001,user002,user003
// 查询规则值配置
String ruleValue = repository.queryStrategyRuleValue(ruleMatterEntity.getStrategyId(), ruleMatterEntity.getAwardId(), ruleMatterEntity.getRuleModel());
String[] splitRuleValue = ruleValue.split(Constants.COLON);
//
Integer awardId = Integer.parseInt(splitRuleValue[0]);
// 过滤其他规则
String[] userBlackIds = splitRuleValue[1].split(Constants.SPLIT);
for (String userBlackId : userBlackIds) {
if (userId.equals(userBlackId)) {
return RuleActionEntity.<RuleActionEntity.RaffleBeforeEntity>builder()
.ruleModel(DefaultLogicFactory.LogicModel.RULE_BLACKLIST.getCode())
.data(RuleActionEntity.RaffleBeforeEntity.builder()
.strategyId(ruleMatterEntity.getStrategyId())
.awardId(awardId)
.build())
.code(RuleLogicCheckTypeVO.TAKE_OVER.getCode())
.info(RuleLogicCheckTypeVO.TAKE_OVER.getInfo())
.build();
}
}
return RuleActionEntity.<RuleActionEntity.RaffleBeforeEntity>builder()
.code(RuleLogicCheckTypeVO.ALLOW.getCode())
.info(RuleLogicCheckTypeVO.ALLOW.getInfo())
.build();
}
}
package cn.bugstack.domain.strategy.service.rule.impl;
import cn.bugstack.domain.strategy.model.entity.RuleActionEntity;
import cn.bugstack.domain.strategy.model.entity.RuleMatterEntity;
import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO;
import cn.bugstack.domain.strategy.repository.IStrategyRepository;
import cn.bugstack.domain.strategy.service.annotation.LogicStrategy;
import cn.bugstack.domain.strategy.service.rule.ILogicFilter;
import cn.bugstack.domain.strategy.service.rule.factory.DefaultLogicFactory;
import cn.bugstack.types.common.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
/**
* @description: [抽奖前规则] 根据抽奖鉴权重返可抽奖范围key
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule.impl
* @DATE: 2024/4/12
*/
@Slf4j
@Component
@LogicStrategy(logicMode = DefaultLogicFactory.LogicModel.RULE_WIGHT)
public class RuleWeightLogicFilter implements ILogicFilter<RuleActionEntity.RaffleBeforeEntity> {
@Resource
private IStrategyRepository repository;
public Long userScore = 4500L;
/**
* 1. 权重规则格式;4000:102,103,104,105 5000:102,103,104,105,106,107 6000:102,103,104,105,106,107,108,109
* 2. 解析数据格式;判断哪个范围符合用户的特定抽奖范围
* @param ruleMatterEntity
* @return
*/
@Override
public RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> filter(RuleMatterEntity ruleMatterEntity) {
log.info("规则过滤-权重范围 userId:{} strategyId:{} ruleModel:{}", ruleMatterEntity.getUserId(), ruleMatterEntity.getStrategyId(), ruleMatterEntity.getRuleModel());
String userId = ruleMatterEntity.getUserId();
Long strategyId = ruleMatterEntity.getStrategyId();
String ruleValue = repository.queryStrategyRuleValue(ruleMatterEntity.getStrategyId(), ruleMatterEntity.getAwardId(), ruleMatterEntity.getRuleModel());
// 1. 根据用户ID查询用户抽奖消耗的积分值,本章节我们先写死为固定的值。后续需要从数据库中查询。
Map<Long, String> analyticalValueGroup = getAnalyticalValue(ruleValue);
if (null == analyticalValueGroup || analyticalValueGroup.isEmpty()) {
return RuleActionEntity.<RuleActionEntity.RaffleBeforeEntity>builder()
.code(RuleLogicCheckTypeVO.ALLOW.getCode())
.info(RuleLogicCheckTypeVO.ALLOW.getInfo())
.build();
}
// 2. 转换Keys值,并默认排序
List<Long> analyticalSortedKeys = new ArrayList<>(analyticalValueGroup.keySet());
Collections.sort(analyticalSortedKeys);
// 3. 找出最小符合的值,也就是【4500 积分,能找到 4000:102,103,104,105】、【5000 积分,能找到 5000:102,103,104,105,106,107】
Long nextValue = analyticalSortedKeys.stream()
.filter(key -> userScore >= key)
.findFirst()
.orElse(null);
if (null != nextValue) {
return RuleActionEntity.<RuleActionEntity.RaffleBeforeEntity>builder()
.data(RuleActionEntity.RaffleBeforeEntity.builder()
.strategyId(strategyId)
.ruleWeightValueKey(analyticalValueGroup.get(nextValue))
.build())
.ruleModel(DefaultLogicFactory.LogicModel.RULE_WIGHT.getCode())
.code(RuleLogicCheckTypeVO.TAKE_OVER.getCode())
.info(RuleLogicCheckTypeVO.TAKE_OVER.getInfo())
.build();
}
return RuleActionEntity.<RuleActionEntity.RaffleBeforeEntity>builder()
.code(RuleLogicCheckTypeVO.ALLOW.getCode())
.info(RuleLogicCheckTypeVO.ALLOW.getInfo())
.build();
}
private Map<Long, String> getAnalyticalValue(String ruleValue) {
String[] ruleValueGroups = ruleValue.split(Constants.SPACE);
Map<Long,String> ruleValueMap = new HashMap<>();
for (String ruleValueGroup : ruleValueGroups) {
// 检查驶入是否为空
if (ruleValueGroup == null || ruleValueGroup.isEmpty()) {
return ruleValueMap;
}
// 分割字符串以获取键和值
String[] parts = ruleValueGroup.split(Constants.COLON);
if (parts.length < 2) {
throw new IllegalArgumentException("rule_weight rule_rule invalid input format" + ruleValueGroup);
}
ruleValueMap.put(Long.parseLong(parts[0]),ruleValueGroup);
}
return ruleValueMap;
}
}
...@@ -21,4 +21,11 @@ public interface IStrategyRuleDao { ...@@ -21,4 +21,11 @@ public interface IStrategyRuleDao {
* @return * @return
*/ */
StrategyRule queryStrategyRule(StrategyRule strategyRuleReq); StrategyRule queryStrategyRule(StrategyRule strategyRuleReq);
/**
* 查询规则值
* @param strategyRule
* @return
*/
String queryStrategyRuleValue(StrategyRule strategyRule);
} }
...@@ -143,4 +143,13 @@ public class StrategyRepository implements IStrategyRepository { ...@@ -143,4 +143,13 @@ public class StrategyRepository implements IStrategyRepository {
return redisService.getValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + key); return redisService.getValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + key);
} }
@Override
public String queryStrategyRuleValue(Long strategyId, Integer awardId, String ruleModel) {
StrategyRule strategyRule = new StrategyRule();
strategyRule.setStrategyId(strategyId);
strategyRule.setRuleModel(ruleModel);
strategyRule.setAwardId(awardId);
return strategyRuleDao.queryStrategyRuleValue(strategyRule);
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册