From caf38ce3777f8ac8ffcec2f276730eebcb257d2c Mon Sep 17 00:00:00 2001
From: hudingrong <1649576115@qq.com>
Date: Tue, 16 Apr 2024 21:03:41 +0800
Subject: [PATCH] rule_model_center
---
.../cn/bugstack/config/RedisClientConfig.java | 6 +-
.../mybatis/mapper/strategy_award_mapper.xml | 4 ++
.../test/domain/RaffleStrategyTest.java | 40 ++++++++++++-
.../model/entity/RaffleFactorEntity.java | 2 +
.../strategy/model/entity/StrategyEntity.java | 7 ++-
.../valobj/StrategyAwardRuleModelVO.java | 50 ++++++++++++++++
.../repository/IStrategyRepository.java | 9 +++
.../service/armory/StrategyArmory.java | 4 +-
.../raffle/AbstractRaffleStrategy.java | 23 +++++++-
.../service/raffle/DefaultRaffleStrategy.java | 30 ++++++++++
.../rule/factory/DefaultLogicFactory.java | 16 +++++-
.../rule/impl/RuleLockLogicFilter.java | 54 ++++++++++++++++++
.../persistent/dao/IStrategyAwardDao.java | 7 +++
.../infrastructure/persistent/po/Award.java | 1 +
.../persistent/redis/RedisService.java | 1 +
.../repository/StrategyRepository.java | 57 +++++++++++++------
16 files changed, 283 insertions(+), 28 deletions(-)
create mode 100644 xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/StrategyAwardRuleModelVO.java
create mode 100644 xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/impl/RuleLockLogicFilter.java
diff --git a/xfg-frame-archetype-lite-app/src/main/java/cn/bugstack/config/RedisClientConfig.java b/xfg-frame-archetype-lite-app/src/main/java/cn/bugstack/config/RedisClientConfig.java
index 703a0ec..53d2906 100644
--- a/xfg-frame-archetype-lite-app/src/main/java/cn/bugstack/config/RedisClientConfig.java
+++ b/xfg-frame-archetype-lite-app/src/main/java/cn/bugstack/config/RedisClientConfig.java
@@ -11,6 +11,7 @@ import org.redisson.api.RedissonClient;
import org.redisson.client.codec.BaseCodec;
import org.redisson.client.protocol.Decoder;
import org.redisson.client.protocol.Encoder;
+import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
@@ -32,8 +33,9 @@ public class RedisClientConfig {
public RedissonClient redissonClient(ConfigurableApplicationContext applicationContext, RedisClientConfigProperties properties) {
Config config = new Config();
// 根据需要可以设定编解码器;https://github.com/redisson/redisson/wiki/4.-%E6%95%B0%E6%8D%AE%E5%BA%8F%E5%88%97%E5%8C%96
- config.setCodec(new RedisCodec());
-
+ // 需要手动从json转pojo
+ //config.setCodec(new RedisCodec());
+ config.setCodec(new JsonJacksonCodec());
config.useSingleServer()
.setAddress("redis://" + properties.getHost() + ":" + properties.getPort())
.setPassword(properties.getPassword())
diff --git a/xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_award_mapper.xml b/xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_award_mapper.xml
index 67ee57e..003960e 100644
--- a/xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_award_mapper.xml
+++ b/xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_award_mapper.xml
@@ -28,5 +28,9 @@
from strategy_award
where strategy_id = #{strategyId}
+
diff --git a/xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/RaffleStrategyTest.java b/xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/RaffleStrategyTest.java
index 1595037..002af8d 100644
--- a/xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/RaffleStrategyTest.java
+++ b/xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/RaffleStrategyTest.java
@@ -3,6 +3,9 @@ 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.armory.IStrategyArmory;
+import cn.bugstack.domain.strategy.service.armory.StrategyArmory;
+import cn.bugstack.domain.strategy.service.rule.impl.RuleLockLogicFilter;
import cn.bugstack.domain.strategy.service.rule.impl.RuleWeightLogicFilter;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
@@ -25,17 +28,35 @@ import javax.annotation.Resource;
@SpringBootTest
public class RaffleStrategyTest {
+ @Resource
+ private IStrategyArmory strategyArmory;
@Resource
private IRaffleStrategy raffleStrategy;
-
@Resource
private RuleWeightLogicFilter ruleWeightLogicFilter;
+ @Resource
+ private RuleLockLogicFilter ruleLockLogicFilter;
@Before
public void setUp() {
+ // 策略装配 100001、100002、100003
+ log.info("测试结果:{}", strategyArmory.assembleLotteryStrategy(100001L));
+ log.info("测试结果:{}", strategyArmory.assembleLotteryStrategy(100002L));
+ log.info("测试结果:{}", strategyArmory.assembleLotteryStrategy(100003L));
+
+ // 通过反射 mock 规则中的值
ReflectionTestUtils.setField(ruleWeightLogicFilter, "userScore", 40500L);
+ ReflectionTestUtils.setField(ruleLockLogicFilter, "userRaffleCount", 10L);
+ }
+
+ @Test
+ public void test() {
+ log.info("测试结果:{}", strategyArmory.assembleLotteryStrategy(100001L));
+ log.info("测试结果:{}", strategyArmory.assembleLotteryStrategy(100002L));
+ log.info("测试结果:{}", strategyArmory.assembleLotteryStrategy(100003L));
}
+
@Test
public void test_performRaffle() {
RaffleFactorEntity raffleFactorEntity = RaffleFactorEntity.builder()
@@ -62,4 +83,21 @@ public class RaffleStrategyTest {
log.info("测试结果:{}", JSON.toJSONString(raffleAwardEntity));
}
+ /**
+ * 次数错校验,抽奖n次后解锁。100003 策略,你可以通过调整 @Before 的 setUp 方法中个人抽奖次数来验证。比如最开始设置0,之后设置10
+ * ReflectionTestUtils.setField(ruleLockLogicFilter, "userRaffleCount", 10L);
+ */
+ @Test
+ public void test_raffle_center_rule_lock(){
+ RaffleFactorEntity raffleFactorEntity = RaffleFactorEntity.builder()
+ .userId("xiaofuge")
+ .strategyId(100003L)
+ .build();
+
+ RaffleAwardEntity raffleAwardEntity = raffleStrategy.performRaffle(raffleFactorEntity);
+
+ log.info("请求参数:{}", JSON.toJSONString(raffleFactorEntity));
+ log.info("测试结果:{}", JSON.toJSONString(raffleAwardEntity));
+ }
+
}
diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/RaffleFactorEntity.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/RaffleFactorEntity.java
index 04c2a20..bdc10b4 100644
--- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/RaffleFactorEntity.java
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/RaffleFactorEntity.java
@@ -22,4 +22,6 @@ public class RaffleFactorEntity {
private String userId;
/** 策略ID */
private Long strategyId;
+ /** 奖品ID */
+ private Integer awardId;
}
diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyEntity.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyEntity.java
index dfa2ee2..4bcc8c8 100644
--- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyEntity.java
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyEntity.java
@@ -7,6 +7,8 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
+import java.io.Serializable;
+
/**
* @description: 策略实体
* @author: hdr
@@ -17,7 +19,7 @@ import org.apache.commons.lang3.StringUtils;
@Builder
@AllArgsConstructor
@NoArgsConstructor
-public class StrategyEntity {
+public class StrategyEntity implements Serializable {
/** 抽奖策略ID */
private Long strategyId;
@@ -33,6 +35,9 @@ public class StrategyEntity {
public String getRuleWeight() {
String[] ruleModels = this.ruleModels();
+ if (ruleModels == null) {
+ return null;
+ }
for (String ruleModel : ruleModels) {
if ("rule_weight".equals(ruleModel)) return ruleModel;
}
diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/StrategyAwardRuleModelVO.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/StrategyAwardRuleModelVO.java
new file mode 100644
index 0000000..a1e56e5
--- /dev/null
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/StrategyAwardRuleModelVO.java
@@ -0,0 +1,50 @@
+package cn.bugstack.domain.strategy.model.valobj;
+
+import cn.bugstack.domain.strategy.service.rule.factory.DefaultLogicFactory;
+import cn.bugstack.types.common.Constants;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @description: 抽奖策略规则规则值对象;值对象,没有唯一ID,仅限于从数据库查询对象
+ * @author: hdr
+ * @PACKAGE_NAME: cn.bugstack.domain.strategy.model.valobj
+ * @DATE: 2024/4/16
+ */
+@Getter
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class StrategyAwardRuleModelVO {
+
+ private String ruleModels;
+
+ /**
+ * 获取抽奖中规则;或者使用 lambda 表达式
+ *
+ * List ruleModelList = Arrays.stream(ruleModels.split(Constants.SPLIT))
+ * .filter(DefaultLogicFactory.LogicModel::isCenter)
+ * .collect(Collectors.toList());
+ * return ruleModelList;
+ *
+ * List collect = Arrays.stream(ruleModelValues).filter(DefaultLogicFactory.LogicModel::isCenter).collect(Collectors.toList());
+ */
+
+ public String[] raffleCenterRuleModelList() {
+ List ruleModelList = new ArrayList<>();
+ String[] ruleModeValues = ruleModels.split(Constants.SPLIT);
+ Arrays.stream(ruleModeValues).forEach(item-> {
+ if (DefaultLogicFactory.LogicModel.isCenter(item)) {
+ ruleModelList.add(item);
+ }
+ });
+
+ return ruleModelList.toArray(new String[0]);
+ }
+}
diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/repository/IStrategyRepository.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/repository/IStrategyRepository.java
index 4e5d633..fd918a8 100644
--- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/repository/IStrategyRepository.java
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/repository/IStrategyRepository.java
@@ -3,6 +3,7 @@ package cn.bugstack.domain.strategy.repository;
import cn.bugstack.domain.strategy.model.entity.StrategyAwardEntity;
import cn.bugstack.domain.strategy.model.entity.StrategyEntity;
import cn.bugstack.domain.strategy.model.entity.StrategyRuleEntity;
+import cn.bugstack.domain.strategy.model.valobj.StrategyAwardRuleModelVO;
import java.math.BigDecimal;
import java.util.HashMap;
@@ -76,4 +77,12 @@ public interface IStrategyRepository {
* @return
*/
String queryStrategyRuleValue(Long strategyId, Integer awardId, String ruleModel);
+
+ /**
+ * 查询 ruleModel
+ * @param strategyId
+ * @param awardId
+ * @return
+ */
+ StrategyAwardRuleModelVO queryStrategyAwardRuleModelVO(Long strategyId, Integer awardId);
}
diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/StrategyArmory.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/StrategyArmory.java
index 280c2ae..9470d83 100644
--- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/StrategyArmory.java
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/StrategyArmory.java
@@ -8,6 +8,7 @@ import cn.bugstack.types.enums.ResponseCode;
import cn.bugstack.types.exception.AppException;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -44,8 +45,7 @@ public class StrategyArmory implements IStrategyArmory, IStrategyDispatch {
// 2. 权重策略陪住 - 使用于 rule_weight 权重规则配置
StrategyEntity strategyEntity = repository.queryStrategyEntityByStrategyId(strategy);
- System.out.println(JSONObject.toJSONString(strategyEntity));
- if (null == strategyEntity.getRuleWeight()||null == strategyEntity) return true;
+ if (StringUtils.isEmpty(strategyEntity.getRuleWeight())) return true;
String ruleWeight = strategyEntity.getRuleWeight();
// 2.2 查询策略规则
StrategyRuleEntity strategyRuleEntity = repository.queryStrategyRule(strategy, ruleWeight);
diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/AbstractRaffleStrategy.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/AbstractRaffleStrategy.java
index bdba2ba..795c79d 100644
--- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/AbstractRaffleStrategy.java
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/AbstractRaffleStrategy.java
@@ -5,6 +5,7 @@ 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.model.valobj.StrategyAwardRuleModelVO;
import cn.bugstack.domain.strategy.repository.IStrategyRepository;
import cn.bugstack.domain.strategy.service.IRaffleStrategy;
import cn.bugstack.domain.strategy.service.armory.IStrategyDispatch;
@@ -53,7 +54,6 @@ public abstract class AbstractRaffleStrategy implements IRaffleStrategy {
.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())) {
@@ -63,7 +63,6 @@ public abstract class AbstractRaffleStrategy implements IRaffleStrategy {
.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);
@@ -74,13 +73,31 @@ public abstract class AbstractRaffleStrategy implements IRaffleStrategy {
}
// 4. 默认抽奖流程
- System.out.println("默认抽奖");
Integer awardId = strategyDispatch.getRandomAwardId(strategyId);
+ // 5. 查询奖品规则「抽奖中(拿到奖品ID时,过滤规则)、抽奖后(扣减完奖品库存后过滤,抽奖中拦截和无库存则走兜底)」
+ StrategyAwardRuleModelVO strategyAwardRuleModelVO = repository.queryStrategyAwardRuleModelVO(strategyId, awardId);
+
+ // 6. 抽奖中 - 规则过滤
+ RuleActionEntity ruleActionCenterEntity = this.doCheckRaffleCenterLogic(RaffleFactorEntity.builder()
+ .userId(userId)
+ .strategyId(strategyId)
+ .awardId(awardId)
+ .build(), strategyAwardRuleModelVO.raffleCenterRuleModelList());
+
+ if (RuleLogicCheckTypeVO.TAKE_OVER.getCode().equals(ruleActionCenterEntity.getCode())){
+ log.info("【临时日志】中奖中规则拦截,通过抽奖后规则 rule_luck_award 走兜底奖励。");
+ return RaffleAwardEntity.builder()
+ .awardDesc("中奖中规则拦截,通过抽奖后规则 rule_luck_award 走兜底奖励。")
+ .build();
+ }
+
return RaffleAwardEntity.builder()
.awardId(awardId)
.build();
}
+ protected abstract RuleActionEntity doCheckRaffleCenterLogic(RaffleFactorEntity raffleFactorEntity, String... logics);
+
protected abstract RuleActionEntity doCheckRaffleBeforeLogic(RaffleFactorEntity factorEntity, String... logics);
}
diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/DefaultRaffleStrategy.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/DefaultRaffleStrategy.java
index 9ae0dcb..db13df1 100644
--- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/DefaultRaffleStrategy.java
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/DefaultRaffleStrategy.java
@@ -36,9 +36,39 @@ public class DefaultRaffleStrategy extends AbstractRaffleStrategy{
public DefaultRaffleStrategy(IStrategyRepository repository, IStrategyDispatch strategyDispatch) {
super(repository, strategyDispatch);
}
+
+ @Override
+ protected RuleActionEntity doCheckRaffleCenterLogic(RaffleFactorEntity raffleFactorEntity, String... logics) {
+ if (logics == null || 0 == logics.length) return RuleActionEntity.builder()
+ .code(RuleLogicCheckTypeVO.ALLOW.getCode())
+ .info(RuleLogicCheckTypeVO.ALLOW.getInfo())
+ .build();
+
+ Map> logicFilterGroup = logicFactory.openLogicFilter();
+
+ RuleActionEntity ruleActionEntity = null;
+ for (String ruleModel : logics) {
+ ILogicFilter logicFilter = logicFilterGroup.get(ruleModel);
+ RuleMatterEntity ruleMatterEntity = new RuleMatterEntity();
+ ruleMatterEntity.setUserId(raffleFactorEntity.getUserId());
+ ruleMatterEntity.setAwardId(raffleFactorEntity.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;
+ }
+
@Override
protected RuleActionEntity doCheckRaffleBeforeLogic(RaffleFactorEntity raffleFactorEntity, String... logics) {
+ if (logics == null || 0 == logics.length) return RuleActionEntity.builder()
+ .code(RuleLogicCheckTypeVO.ALLOW.getCode())
+ .info(RuleLogicCheckTypeVO.ALLOW.getInfo())
+ .build();
log.info("raffleFactorEntity:{},logics:{}", JSON.toJSONString(raffleFactorEntity),logics);
Map> logicFilterGroup = logicFactory.openLogicFilter();
diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/factory/DefaultLogicFactory.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/factory/DefaultLogicFactory.java
index 4cabdff..19f9bf4 100644
--- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/factory/DefaultLogicFactory.java
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/factory/DefaultLogicFactory.java
@@ -40,13 +40,23 @@ public class DefaultLogicFactory {
@AllArgsConstructor
public enum LogicModel {
- RULE_WIGHT("rule_weight","【抽奖前规则】根据抽奖权重返回可抽奖范围KEY"),
- RULE_BLACKLIST("rule_blacklist","【抽奖前规则】黑名单规则过滤,命中黑名单则直接返回"),
-
+ RULE_WIGHT("rule_weight", "【抽奖前规则】根据抽奖权重返回可抽奖范围KEY", "before"),
+ RULE_BLACKLIST("rule_blacklist", "【抽奖前规则】黑名单规则过滤,命中黑名单则直接返回", "before"),
+ RULE_LOCK("rule_lock", "【抽奖中规则】抽奖n次后,对应奖品可解锁抽奖", "center"),
+ RULE_LUCK_AWARD("rule_luck_award", "【抽奖后规则】抽奖n次后,对应奖品可解锁抽奖", "after"),
;
private final String code;
private final String info;
+ private final String type;
+
+ public static boolean isCenter(String code){
+ return "center".equals(LogicModel.valueOf(code.toUpperCase()).type);
+ }
+
+ public static boolean isAfter(String code){
+ return "after".equals(LogicModel.valueOf(code.toUpperCase()).type);
+ }
}
diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/impl/RuleLockLogicFilter.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/impl/RuleLockLogicFilter.java
new file mode 100644
index 0000000..b7e619b
--- /dev/null
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/impl/RuleLockLogicFilter.java
@@ -0,0 +1,54 @@
+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 lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * @description: 用户抽奖n次后,对应奖品可解锁抽奖
+ * @author: hdr
+ * @PACKAGE_NAME: cn.bugstack.domain.strategy.service.raffle
+ * @DATE: 2024/4/16
+ */
+@Slf4j
+@Component
+@LogicStrategy(logicMode = DefaultLogicFactory.LogicModel.RULE_LOCK)
+public class RuleLockLogicFilter implements ILogicFilter {
+
+ @Resource
+ private IStrategyRepository repository;
+
+ // 测试数据
+ private Long userRaffleCount = 0L;
+
+ @Override
+ public RuleActionEntity filter(RuleMatterEntity ruleMatterEntity) {
+ log.info("规则过滤-次数锁 userId:{} strategyId:{} ruleModel:{}", ruleMatterEntity.getUserId(), ruleMatterEntity.getStrategyId(), ruleMatterEntity.getRuleModel());
+
+ // 查询规则值配置;当前奖品ID,抽奖中规则对应的校验值。如;1、2、6
+ String ruleValue = repository.queryStrategyRuleValue(ruleMatterEntity.getStrategyId(), ruleMatterEntity.getAwardId(), ruleMatterEntity.getRuleModel());
+ long raffleCount = Long.parseLong(ruleValue);
+
+ // 用户抽奖次数大于规则限定值,规则放行
+ if (userRaffleCount>= raffleCount) {
+ return RuleActionEntity.builder()
+ .code(RuleLogicCheckTypeVO.ALLOW.getCode())
+ .info(RuleLogicCheckTypeVO.ALLOW.getInfo())
+ .build();
+ }
+
+ // 用户抽奖次数小于规则限定值,规则拦截
+ return RuleActionEntity.builder()
+ .code(RuleLogicCheckTypeVO.TAKE_OVER.getCode())
+ .info(RuleLogicCheckTypeVO.TAKE_OVER.getInfo())
+ .build();
+ }
+}
diff --git a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyAwardDao.java b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyAwardDao.java
index 67b6bb4..bab0f42 100644
--- a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyAwardDao.java
+++ b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyAwardDao.java
@@ -22,4 +22,11 @@ public interface IStrategyAwardDao {
* @return
*/
List queryStrategyAwardListByStrategyId(@Param("strategyId") Long strategyId);
+
+ /**
+ * 查询ruleModels
+ * @param strategyAward
+ * @return
+ */
+ String queryStrategyAwardRuleModels(StrategyAward strategyAward);
}
diff --git a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/Award.java b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/Award.java
index 70a34e7..df8a66f 100644
--- a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/Award.java
+++ b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/Award.java
@@ -12,6 +12,7 @@ import java.util.Date;
*/
@Data
public class Award {
+
/** 自增ID */
private Long id;
/** 抽奖奖品ID - 内部流转使用 */
diff --git a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/redis/RedisService.java b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/redis/RedisService.java
index 74352dc..878819e 100644
--- a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/redis/RedisService.java
+++ b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/redis/RedisService.java
@@ -102,6 +102,7 @@ public class RedisService implements IRedisService {
return redissonClient.getMap(key);
}
+ @Override
public void addToMap(String key, String field, String value) {
RMap map = redissonClient.getMap(key);
map.put(field, value);
diff --git a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/repository/StrategyRepository.java b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/repository/StrategyRepository.java
index 6df15a9..061e84a 100644
--- a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/repository/StrategyRepository.java
+++ b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/repository/StrategyRepository.java
@@ -3,6 +3,7 @@ package cn.bugstack.infrastructure.persistent.repository;
import cn.bugstack.domain.strategy.model.entity.StrategyAwardEntity;
import cn.bugstack.domain.strategy.model.entity.StrategyEntity;
import cn.bugstack.domain.strategy.model.entity.StrategyRuleEntity;
+import cn.bugstack.domain.strategy.model.valobj.StrategyAwardRuleModelVO;
import cn.bugstack.domain.strategy.repository.IStrategyRepository;
import cn.bugstack.infrastructure.persistent.dao.IStrategyAwardDao;
import cn.bugstack.infrastructure.persistent.dao.IStrategyDao;
@@ -16,6 +17,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
@@ -55,9 +57,10 @@ public class StrategyRepository implements IStrategyRepository {
public List queryStrategyAwardList(Long strategy) {
// 1. 查询redis中是否有保存策略数据有的话直接返回
String cacheKey = Constants.RedisKey.STRATEGY_AWARD_KEY + strategy;
- Object json = redisService.getValue(cacheKey);
- List strategyAwardEntities = JSON.parseArray(json.toString(), StrategyAwardEntity.class);
- if (strategyAwardEntities != null && !strategyAwardEntities.isEmpty()) {
+ List strategyAwardEntities = redisService.getValue(cacheKey);
+
+ if (strategyAwardEntities != null && strategyAwardEntities.size() != 0) {
+// List strategyAwardEntities = JSON.parseArray(json.toString(), StrategyAwardEntity.class);
return strategyAwardEntities;
}
@@ -75,7 +78,7 @@ public class StrategyRepository implements IStrategyRepository {
// 2.1 保存到redis中
-// redisService.setValue(cacheKey, strategyAwardEntityList);
+ redisService.setValue(cacheKey, strategyAwardEntityList);
return strategyAwardEntityList;
}
@@ -103,21 +106,33 @@ public class StrategyRepository implements IStrategyRepository {
public StrategyEntity queryStrategyEntityByStrategyId(Long strategyId) {
// 1. 优先从缓存获取
String cacheKey = Constants.RedisKey.STRATEGY_KEY + strategyId;
- Map maps = redisService.getValue(cacheKey);
- StrategyEntity strategyEntity = StrategyEntity.builder()
- .strategyId(Long.parseLong(maps.get("strategyId").toString()))
- .strategyDesc((String) maps.get("strategyDesc"))
- .ruleModels((String) maps.get("ruleModels"))
- .build();
- if (null != strategyEntity) return strategyEntity;
+
+ StrategyEntity strategyEntity = new StrategyEntity();
+ StrategyEntity maps = redisService.getValue(cacheKey);
+ if (null != maps){
+// strategyEntity = StrategyEntity.builder()
+// .strategyId(Long.parseLong(maps.get("strategyId").toString()))
+// .strategyDesc((String) maps.get("strategyDesc"))
+// .ruleModels((String) maps.get("ruleModels"))
+// .build();
+ return maps;
+ }
// 2. 没有数据从数据库获取
Strategy strategy = strategyDao.queryStrategyByStrategyId(strategyId);
- strategyEntity = StrategyEntity.builder()
- .strategyId(strategy.getStrategyId())
- .strategyDesc(strategy.getStrategyDesc())
- .ruleModels(strategy.getRuleModels())
- .build();
+ strategyEntity.setStrategyId(strategy.getStrategyId());
+ if (StringUtils.isNotBlank(strategy.getRuleModels())) {
+ strategyEntity.setRuleModels(strategy.getRuleModels());
+ }
+ strategyEntity.setStrategyDesc(strategy.getStrategyDesc());
+// = StrategyEntity.builder()
+// .strategyId(strategy.getStrategyId())
+// .strategyDesc(strategy.getStrategyDesc())
+// .ruleModels(strategy.getRuleModels())
+// .build();
+
+
// 3. 写入缓存
+ log.info("strategyEntity:{}",strategyEntity);
redisService.setValue(cacheKey,strategyEntity);
return strategyEntity;
}
@@ -152,4 +167,14 @@ public class StrategyRepository implements IStrategyRepository {
return strategyRuleDao.queryStrategyRuleValue(strategyRule);
}
+ @Override
+ public StrategyAwardRuleModelVO queryStrategyAwardRuleModelVO(Long strategyId, Integer awardId) {
+ StrategyAward strategyAward = new StrategyAward();
+ strategyAward.setStrategyId(strategyId);
+ strategyAward.setAwardId(awardId);
+ String ruleModels = strategyAwardDao.queryStrategyAwardRuleModels(strategyAward);
+
+ return StrategyAwardRuleModelVO.builder().ruleModels(ruleModels).build();
+ }
+
}
--
GitLab