diff --git a/xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_mapper.xml b/xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_mapper.xml
index 33ec1d55f69557e3e517e52f21cf8ee29e0a3984..c60fd389fc057c25b91d4744a11a38881ec19fb1 100644
--- a/xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_mapper.xml
+++ b/xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_mapper.xml
@@ -6,6 +6,7 @@
+
@@ -15,5 +16,10 @@
from strategy
limit 10
+
diff --git a/xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_rule_mapper.xml b/xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_rule_mapper.xml
index 4b3556bffdfddce8db02ae2fcad6295e3f7f3bd2..f160d79406c368130a8559f118816bbb0e182ba4 100644
--- a/xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_rule_mapper.xml
+++ b/xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_rule_mapper.xml
@@ -19,5 +19,10 @@
from strategy_rule
limit 10
+
diff --git a/xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/StrategyTest.java b/xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/StrategyTest.java
index 665bde5f83a12899b85bef9379605b562dd321c2..0cd9ee11cd4e089b44d951ca79402e1451e75527 100644
--- a/xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/StrategyTest.java
+++ b/xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/StrategyTest.java
@@ -1,8 +1,10 @@
package cn.bugstack.test.domain;
import cn.bugstack.domain.strategy.service.armory.IStrategyArmory;
+import cn.bugstack.domain.strategy.service.armory.IStrategyDispatch;
import cn.bugstack.infrastructure.persistent.redis.IRedisService;
import lombok.extern.slf4j.Slf4j;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.api.RMap;
@@ -25,21 +27,34 @@ public class StrategyTest {
@Resource
private IStrategyArmory strategyArmory;
+ @Resource
+ private IStrategyDispatch strategyDispatch;
+
/**
* 策略ID;100001L、100002L 装配的时候创建策略表写入到 Redis Map 中
*/
@Test
public void test_strategyArmory() {
- strategyArmory.assembleLotteryStrategy(100002L);
- log.info("测试结果:{}");
+ boolean success = strategyArmory.assembleLotteryStrategy(100001L);
+ log.info("测试结果:{}", success);
}
/**
* 从装配的策略中随机获取奖品ID值
*/
@Test
- public void test_getAssembleRandomVal() {
- log.info("测试结果:{} - 奖品ID值", strategyArmory.getRandomAwardId(100002L));
+ public void test_getRandomAwardId() {
+ log.info("测试结果:{} - 奖品ID值", strategyDispatch.getRandomAwardId(100001L));
+ }
+
+ /**
+ * 根据策略ID+权重值,从装配的策略中随机获取奖品ID值
+ */
+ @Test
+ public void test_getRandomAwardId_ruleWeightValue() {
+ log.info("测试结果:{} - 4000 策略配置", strategyDispatch.getRandomAwardId(100001L, "4000:102,103,104,105"));
+ log.info("测试结果:{} - 5000 策略配置", strategyDispatch.getRandomAwardId(100001L, "5000:102,103,104,105,106,107"));
+ log.info("测试结果:{} - 6000 策略配置", strategyDispatch.getRandomAwardId(100001L, "6000:102,103,104,105,106,107,108,109"));
}
@Resource
@@ -90,4 +105,5 @@ public class StrategyTest {
}
}
+
}
diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyAwardEntity.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyAwardEntity.java
index 85416c3d410e3acf26e6a7ecad37d4a0ab21c637..d05e8caad1aa3b5bed52435f1a6f6e86f15c0581 100644
--- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyAwardEntity.java
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyAwardEntity.java
@@ -5,6 +5,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
+import java.io.Serializable;
import java.math.BigDecimal;
/**
@@ -17,7 +18,7 @@ import java.math.BigDecimal;
@Builder
@AllArgsConstructor
@NoArgsConstructor
-public class StrategyAwardEntity {
+public class StrategyAwardEntity implements Serializable {
/** 抽奖策略ID */
private Long strategyId;
/** 抽奖奖品ID - 内部流转使用 */
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
new file mode 100644
index 0000000000000000000000000000000000000000..dfa2ee2a26daf2a369be566ef5f1c1b067596113
--- /dev/null
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyEntity.java
@@ -0,0 +1,42 @@
+package cn.bugstack.domain.strategy.model.entity;
+
+import cn.bugstack.types.common.Constants;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * @description: 策略实体
+ * @author: hdr
+ * @PACKAGE_NAME: cn.bugstack.domain.strategy.model.entity
+ * @DATE: 2024/4/9
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class StrategyEntity {
+
+ /** 抽奖策略ID */
+ private Long strategyId;
+ /** 抽奖策略描述 */
+ private String strategyDesc;
+ /** 抽奖规则模型 rule_weight,rule_blacklist */
+ private String ruleModels;
+
+ public String[] ruleModels() {
+ if (StringUtils.isBlank(ruleModels)) return null;
+ return ruleModels.split(Constants.SPLIT);
+ }
+
+ public String getRuleWeight() {
+ String[] ruleModels = this.ruleModels();
+ for (String ruleModel : ruleModels) {
+ if ("rule_weight".equals(ruleModel)) return ruleModel;
+ }
+ return null;
+ }
+
+}
diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyRuleEntity.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyRuleEntity.java
new file mode 100644
index 0000000000000000000000000000000000000000..748d3645e89d9f93d6ff63c02f1df66f2cd9b1b2
--- /dev/null
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyRuleEntity.java
@@ -0,0 +1,70 @@
+package cn.bugstack.domain.strategy.model.entity;
+
+import cn.bugstack.types.common.Constants;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @description:
+ * @author: hdr
+ * @PACKAGE_NAME: cn.bugstack.domain.strategy.model.entity
+ * @DATE: 2024/4/9
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class StrategyRuleEntity {
+
+ /** 抽奖策略ID */
+ private Long strategyId;
+ /** 抽奖奖品ID【规则类型为策略,则不需要奖品ID】 */
+ private Integer awardId;
+ /** 抽象规则类型;1-策略规则、2-奖品规则 */
+ private Integer ruleType;
+ /** 抽奖规则类型【rule_random - 随机值计算、rule_lock - 抽奖几次后解锁、rule_luck_award - 幸运奖(兜底奖品)】 */
+ private String ruleModel;
+ /** 抽奖规则比值 */
+ private String ruleValue;
+ /** 抽奖规则描述 */
+ private String ruleDesc;
+
+ /**
+ * 获取权重值
+ * 数据案例;4000:102,103,104,105 5000:102,103,104,105,106,107 6000:102,103,104,105,106,107,108,109
+ */
+ public Map> getRuleWeightValues() {
+ if (!"rule_weight".equals(ruleModel)) return null;
+ String[] ruleValueGroups = ruleValue.split(Constants.SPACE);
+ Map> resultMap = new HashMap<>();
+ for (String ruleValueGroup : ruleValueGroups) {
+ // 检查输入是否为空
+ if (ruleValueGroup == null || ruleValueGroup.isEmpty()) {
+ return resultMap;
+ }
+ // 分割字符串以获取键和值
+ String[] parts = ruleValueGroup.split(Constants.COLON);
+ if (parts.length != 2) {
+ throw new IllegalArgumentException("rule_weight rule_rule invalid input format" + ruleValueGroup);
+ }
+ // 解析值
+ String[] valueStrings = parts[1].split(Constants.SPLIT);
+ List values = new ArrayList<>();
+ for (String valueString : valueStrings) {
+ values.add(Integer.parseInt(valueString));
+ }
+ // 将键和值放入Map中
+ resultMap.put(ruleValueGroup, values);
+ }
+
+ return resultMap;
+ }
+
+}
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 07d3a95f6fc30c18a0c56ac578252e4f83bb4731..d0908f65aa14649979a548576955427d069c5d0e 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
@@ -1,6 +1,8 @@
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 java.math.BigDecimal;
import java.util.HashMap;
@@ -23,11 +25,11 @@ public interface IStrategyRepository {
List queryStrategyAwardList(Long strategy);
/**
- * @param strategyId 策略id
+ * @param key 策略id
* @param rateRange 概率
* @param shuffleStrategyAwardSearchRateTables 所有保存的概率
*/
- void storeStrategyAwardSearchRateTables(Long strategyId, Integer rateRange, HashMap shuffleStrategyAwardSearchRateTables);
+ void storeStrategyAwardSearchRateTables(String key, Integer rateRange, HashMap shuffleStrategyAwardSearchRateTables);
/**
*
@@ -37,10 +39,32 @@ public interface IStrategyRepository {
int getRandomAwardId(Long strategyId);
/**
- * 获取哦奖品id
- * @param strategyId
+ * 获取奖品id
+ * @param key
* @param nextInt
* @return
*/
- Integer getStrategyAwardAssemble(Long strategyId, int nextInt);
+ Integer getStrategyAwardAssemble(String key, int nextInt);
+
+ /**
+ * 获取抽奖策略
+ * @param strategy 策略id
+ * @return
+ */
+ StrategyEntity queryStrategyEntityByStrategyId(Long strategy);
+
+ /**
+ * 查询抽奖策略规则
+ * @param strategy 策略id
+ * @param ruleWeight 策略id
+ * @return
+ */
+ StrategyRuleEntity queryStrategyRule(Long strategyId, String ruleWeight);
+
+ /**
+ * 获取概率值
+ * @param key
+ * @return
+ */
+ int getRateRange(String key);
}
diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/IStrategyArmory.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/IStrategyArmory.java
index de41f534bee6d750d1a472d59b430e22ffc0f868..afce43cd820d55f6af1c75192eac21213b0972b5 100644
--- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/IStrategyArmory.java
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/IStrategyArmory.java
@@ -12,12 +12,7 @@ public interface IStrategyArmory {
* 抽奖策略
* @param strategy
*/
- void assembleLotteryStrategy(Long strategy);
+ boolean assembleLotteryStrategy(Long strategy);
+
- /**
- * 获取随机奖品id
- * @param strategyId
- * @return
- */
- Integer getRandomAwardId(Long strategyId);
}
diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/IStrategyDispatch.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/IStrategyDispatch.java
new file mode 100644
index 0000000000000000000000000000000000000000..da2be9f729328805c59e91f6d32ad8e2e1eb5602
--- /dev/null
+++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/IStrategyDispatch.java
@@ -0,0 +1,24 @@
+package cn.bugstack.domain.strategy.service.armory;
+
+/**
+ * @description: 策略抽奖调度
+ * @author: hdr
+ * @PACKAGE_NAME: cn.bugstack.domain.strategy.service.armory
+ * @DATE: 2024/4/8
+ */
+public interface IStrategyDispatch {
+ /**
+ * 获取随机奖品id
+ * @param strategyId
+ * @return
+ */
+ Integer getRandomAwardId(Long strategyId);
+
+ /**
+ * 随机获取奖品
+ * @param strategyId
+ * @param ruleWeightValue
+ * @return
+ */
+ Integer getRandomAwardId(Long strategyId, String ruleWeightValue);
+}
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 437338011ea6bf9f3ea1196e5d18d733290fe0af..280c2aec68f9c19c060873863281711e172e303d 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
@@ -1,7 +1,12 @@
package cn.bugstack.domain.strategy.service.armory;
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.repository.IStrategyRepository;
+import cn.bugstack.types.enums.ResponseCode;
+import cn.bugstack.types.exception.AppException;
+import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -10,7 +15,6 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.SecureRandom;
import java.util.*;
-import java.util.stream.Collectors;
/**
* @description:
@@ -20,28 +24,60 @@ import java.util.stream.Collectors;
*/
@Slf4j
@Service
-public class StrategyArmory implements IStrategyArmory {
+public class StrategyArmory implements IStrategyArmory, IStrategyDispatch {
@Autowired
private IStrategyRepository repository;
+ public static void main(String[] args) {
+ StrategyArmory strategyArmory = new StrategyArmory();
+ strategyArmory.assembleLotteryStrategy(100001L);
+ }
+
@Override
- public void assembleLotteryStrategy(Long strategy) {
+ public boolean assembleLotteryStrategy(Long strategy) {
// 1. 查询策略配置
List awardEntityList = repository.queryStrategyAwardList(strategy);
+ assembleLotteryStrategy(String.valueOf(strategy),awardEntityList);
+
+ // 2. 权重策略陪住 - 使用于 rule_weight 权重规则配置
+ StrategyEntity strategyEntity = repository.queryStrategyEntityByStrategyId(strategy);
+
+ System.out.println(JSONObject.toJSONString(strategyEntity));
+ if (null == strategyEntity.getRuleWeight()||null == strategyEntity) return true;
+ String ruleWeight = strategyEntity.getRuleWeight();
+ // 2.2 查询策略规则
+ StrategyRuleEntity strategyRuleEntity = repository.queryStrategyRule(strategy, ruleWeight);
+ if (null == strategyRuleEntity) {
+ throw new AppException(ResponseCode.STRATEGY_RULE_WEIGHT_IS_NULL.getCode(), ResponseCode.STRATEGY_RULE_WEIGHT_IS_NULL.getInfo());
+ }
+ Map> ruleWeightValueMap = strategyRuleEntity.getRuleWeightValues();
+ Set keys = ruleWeightValueMap.keySet();
+ // 2.3 将获取到的所有 规则写入缓存
+ for (String key : keys) {
+ List ruleWeightValues = ruleWeightValueMap.get(key);
+ ArrayList strategyAwardEntitiesClone = new ArrayList<>(awardEntityList);
+ strategyAwardEntitiesClone.removeIf(entity -> !ruleWeightValues.contains(entity.getAwardId()));
+ assembleLotteryStrategy(String.valueOf(strategy).concat("_").concat(key), strategyAwardEntitiesClone);
+ }
+ return true;
- // 2. 获取最小概率值
- BigDecimal minAwardRate = awardEntityList.stream().map(StrategyAwardEntity::getAwardRate)
+ }
+
+ private void assembleLotteryStrategy(String key,List awardEntityList) {
+ // 1. 获取最小概率值
+ BigDecimal minAwardRate = awardEntityList.stream()
+ .map(StrategyAwardEntity::getAwardRate)
.min(BigDecimal::compareTo)
.orElse(BigDecimal.ZERO);
- // 3. 获取概率值总和
+ // 2. 获取概率值总和
BigDecimal totalAwardRate = awardEntityList.stream()
.map(StrategyAwardEntity::getAwardRate)
.reduce(BigDecimal.ZERO, BigDecimal::add);
- // 4. 用 1% 0.001获取概率范围,百分位、千分位、万分位
+ // 3. 用 1% 0.001获取概率范围,百分位、千分位、万分位
BigDecimal rateRange = totalAwardRate.divide(minAwardRate, 0, RoundingMode.CEILING);
@@ -50,34 +86,37 @@ public class StrategyArmory implements IStrategyArmory {
Integer awardId = strategyAwardEntity.getAwardId();
BigDecimal awardRate = strategyAwardEntity.getAwardRate();
- // 5. 计算出每个概率值需要存储到查找表的数量,循环填充
-
- log.info("rateRange.multiply(awardRate).setScale(0, RoundingMode.CEILING).intValue()"+rateRange.multiply(awardRate).setScale(0, RoundingMode.CEILING).intValue());
+ // 4. 计算出每个概率值需要存储到查找表的数量,循环填充
for (int i = 0; i < rateRange.multiply(awardRate).setScale(0, RoundingMode.CEILING).intValue(); i++) {
strategyAwardSearchRateTables.add(awardId);
}
- // 6. 乱序
+ // 5. 乱序
Collections.shuffle(strategyAwardSearchRateTables);
- // 7.
+ // 6. 组装抽奖表
HashMap shuffleStrategyAwardSearchRateTables = new HashMap<>();
for (int i = 0; i < strategyAwardSearchRateTables.size(); i++) {
shuffleStrategyAwardSearchRateTables.put(i, (Integer) strategyAwardSearchRateTables.get(i));
}
- log.info(shuffleStrategyAwardSearchRateTables.size()+"");
- // 8. 存储到 redis中
- repository.storeStrategyAwardSearchRateTables(strategy,shuffleStrategyAwardSearchRateTables.size(), shuffleStrategyAwardSearchRateTables);
+ // 7. 存储到 redis中
+ repository.storeStrategyAwardSearchRateTables(key,shuffleStrategyAwardSearchRateTables.size(), shuffleStrategyAwardSearchRateTables);
}
-
-
-
}
@Override
public Integer getRandomAwardId(Long strategyId) {
int rateRange = repository.getRandomAwardId(strategyId);
- return repository.getStrategyAwardAssemble(strategyId,new SecureRandom().nextInt(rateRange));
+ return repository.getStrategyAwardAssemble(String.valueOf(strategyId),new SecureRandom().nextInt(rateRange));
+ }
+
+ @Override
+ public Integer getRandomAwardId(Long strategyId, String ruleWeightValue) {
+ String key = String.valueOf(strategyId).concat("_").concat(ruleWeightValue);
+ // 分布式部署下,不一定为当前应用做的策略装配。也就是值不一定会保存到本应用,而是分布式应用,所以需要从 Redis 中获取。
+ int rateRange = repository.getRateRange(key);
+ // 通过生成的随机值,获取概率值奖品查找表的结果
+ return repository.getStrategyAwardAssemble(key, new SecureRandom().nextInt(rateRange));
}
}
diff --git a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyDao.java b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyDao.java
index 4d2cc6cf0e01ea2f0bb630bc6b40184e77e7ba13..4159f8c0d573431132d1e6172cd77e564070a2e2 100644
--- a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyDao.java
+++ b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyDao.java
@@ -2,6 +2,7 @@ package cn.bugstack.infrastructure.persistent.dao;
import cn.bugstack.infrastructure.persistent.po.Strategy;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -15,4 +16,10 @@ public interface IStrategyDao {
List queryStrategyList();
+ /**
+ * 通过策略id查询策略
+ * @param strategyId 策略id
+ * @return
+ */
+ Strategy queryStrategyByStrategyId(@Param("strategyId") Long strategyId);
}
diff --git a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyRuleDao.java b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyRuleDao.java
index 53068717f94102b83050c513b7028b39f9ee8d04..d37bbe74127db6dd5c6fe1ad15721b6c98749274 100644
--- a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyRuleDao.java
+++ b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyRuleDao.java
@@ -15,4 +15,10 @@ public interface IStrategyRuleDao {
List queryStrategyRuleList();
+ /**
+ * 策略规则和策略id查询
+ * @param strategyRuleReq
+ * @return
+ */
+ StrategyRule queryStrategyRule(StrategyRule strategyRuleReq);
}
diff --git a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/Strategy.java b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/Strategy.java
index 017dd7659477fe430484b79dfab47cccd76100dd..3f2e16ecef9d370cf36afb67b3332f1978049e92 100644
--- a/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/Strategy.java
+++ b/xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/Strategy.java
@@ -19,6 +19,8 @@ public class Strategy {
private Long strategyId;
/** 抽奖策略描述 */
private String strategyDesc;
+ /** 抽奖规则模型 rule_weight,rule_blacklist */
+ private String ruleModels;
/** 创建时间 */
private Date createTime;
/** 更新时间 */
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 fc41464014eba7a16b7c29552391b9f1e146df89..40069d7d98df4b0201a404dc39e7da9f5c4eb34a 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
@@ -1,19 +1,27 @@
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.repository.IStrategyRepository;
import cn.bugstack.infrastructure.persistent.dao.IStrategyAwardDao;
+import cn.bugstack.infrastructure.persistent.dao.IStrategyDao;
+import cn.bugstack.infrastructure.persistent.dao.IStrategyRuleDao;
+import cn.bugstack.infrastructure.persistent.po.Strategy;
import cn.bugstack.infrastructure.persistent.po.StrategyAward;
+import cn.bugstack.infrastructure.persistent.po.StrategyRule;
import cn.bugstack.infrastructure.persistent.redis.IRedisService;
-import cn.bugstack.infrastructure.persistent.redis.RedisService;
import cn.bugstack.types.common.Constants;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
-import org.redisson.misc.Hash;
+import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
-import org.springframework.stereotype.Service;
-import java.math.BigDecimal;
+import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -35,11 +43,20 @@ public class StrategyRepository implements IStrategyRepository {
@Autowired
private IRedisService redisService;
+
+ @Autowired
+ private IStrategyDao strategyDao;
+
+ @Autowired
+ private IStrategyRuleDao strategyRuleDao;
+
+
@Override
public List queryStrategyAwardList(Long strategy) {
// 1. 查询redis中是否有保存策略数据有的话直接返回
String cacheKey = Constants.RedisKey.STRATEGY_AWARD_KEY + strategy;
- List strategyAwardEntities = redisService.getValue(cacheKey);
+ Object json = redisService.getValue(cacheKey);
+ List strategyAwardEntities = JSON.parseArray(json.toString(), StrategyAwardEntity.class);
if (strategyAwardEntities != null && !strategyAwardEntities.isEmpty()) {
return strategyAwardEntities;
}
@@ -57,28 +74,73 @@ public class StrategyRepository implements IStrategyRepository {
}).collect(Collectors.toList());
// 2.1 保存到redis中
- redisService.setValue(cacheKey,strategyAwardEntityList);
+
+// redisService.setValue(cacheKey, strategyAwardEntityList);
return strategyAwardEntityList;
}
@Override
- public void storeStrategyAwardSearchRateTables(Long strategyId, Integer rateRange, HashMap shuffleStrategyAwardSearchRateTables) {
+ public void storeStrategyAwardSearchRateTables(String key, Integer rateRange, HashMap shuffleStrategyAwardSearchRateTables) {
// 1. 存储概率值
- redisService.setValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + strategyId, rateRange.intValue());
+ redisService.setValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + key, rateRange.intValue());
// 2. 存储概率查找表
- Map cacheRateTable = redisService.getMap(Constants.RedisKey.STRATEGY_RATE_TABLE_KEY + strategyId);
+ Map cacheRateTable = redisService.getMap(Constants.RedisKey.STRATEGY_RATE_TABLE_KEY + key);
cacheRateTable.putAll(shuffleStrategyAwardSearchRateTables);
}
@Override
public int getRandomAwardId(Long strategyId) {
- return redisService.getValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + strategyId);
+ return getRateRange(String.valueOf(strategyId));
+ }
+
+ @Override
+ public Integer getStrategyAwardAssemble(String key, int nextInt) {
+ return redisService.getFromMap(Constants.RedisKey.STRATEGY_RATE_TABLE_KEY + key,nextInt);
+ }
+
+ @Override
+ 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;
+ // 2. 没有数据从数据库获取
+ Strategy strategy = strategyDao.queryStrategyByStrategyId(strategyId);
+ strategyEntity = StrategyEntity.builder()
+ .strategyId(strategy.getStrategyId())
+ .strategyDesc(strategy.getStrategyDesc())
+ .ruleModels(strategy.getRuleModels())
+ .build();
+ // 3. 写入缓存
+ redisService.setValue(cacheKey,strategyEntity);
+ return strategyEntity;
+ }
+
+ @Override
+ public StrategyRuleEntity queryStrategyRule(Long strategyId, String ruleModel) {
+ StrategyRule strategyRuleReq = new StrategyRule();
+ strategyRuleReq.setStrategyId(strategyId);
+ strategyRuleReq.setRuleModel(ruleModel);
+ StrategyRule strategyRuleRes = strategyRuleDao.queryStrategyRule(strategyRuleReq);
+ return StrategyRuleEntity.builder()
+ .strategyId(strategyRuleRes.getStrategyId())
+ .awardId(strategyRuleRes.getAwardId())
+ .ruleType(strategyRuleRes.getRuleType())
+ .ruleModel(strategyRuleRes.getRuleModel())
+ .ruleValue(strategyRuleRes.getRuleValue())
+ .ruleDesc(strategyRuleRes.getRuleDesc())
+ .build();
}
@Override
- public Integer getStrategyAwardAssemble(Long strategyId, int nextInt) {
- return redisService.getFromMap(Constants.RedisKey.STRATEGY_RATE_TABLE_KEY + strategyId,nextInt);
+ public int getRateRange(String key) {
+ return redisService.getValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + key);
}
}
diff --git a/xfg-frame-archetype-lite-types/src/main/java/cn/bugstack/types/common/Constants.java b/xfg-frame-archetype-lite-types/src/main/java/cn/bugstack/types/common/Constants.java
index 008bc32b0ba0ae1a280531c7528f15fd4107ef46..0c21914eefa30758b56af35ab298e2b6b03483e8 100644
--- a/xfg-frame-archetype-lite-types/src/main/java/cn/bugstack/types/common/Constants.java
+++ b/xfg-frame-archetype-lite-types/src/main/java/cn/bugstack/types/common/Constants.java
@@ -3,8 +3,11 @@ package cn.bugstack.types.common;
public class Constants {
public final static String SPLIT = ",";
+ public final static String COLON = ":";
+ public final static String SPACE = " ";
public static class RedisKey {
+ public static final String STRATEGY_KEY = "big_market_strategy_key_";
public static String STRATEGY_AWARD_KEY = "big_market_strategy_award_key_";
public static String STRATEGY_RATE_TABLE_KEY = "big_market_strategy_rate_table_key_";
public static String STRATEGY_RATE_RANGE_KEY = "big_market_strategy_rate_range_key_";
diff --git a/xfg-frame-archetype-lite-types/src/main/java/cn/bugstack/types/enums/ResponseCode.java b/xfg-frame-archetype-lite-types/src/main/java/cn/bugstack/types/enums/ResponseCode.java
index 7460d4b0cfdc6c3c82e27089338ef10bf0c40ef1..e9015360ba82ebde99bfee1f49a74e252dcb25cb 100644
--- a/xfg-frame-archetype-lite-types/src/main/java/cn/bugstack/types/enums/ResponseCode.java
+++ b/xfg-frame-archetype-lite-types/src/main/java/cn/bugstack/types/enums/ResponseCode.java
@@ -12,6 +12,7 @@ public enum ResponseCode {
SUCCESS("0000", "成功"),
UN_ERROR("0001", "未知失败"),
ILLEGAL_PARAMETER("0002", "非法参数"),
+ STRATEGY_RULE_WEIGHT_IS_NULL("ERR_BIZ_001", "业务异常,策略规则中 rule_weight 权重规则已适用但未配置")
;
private String code;