提交 33928eda 编写于 作者: C caathead

完成了权重的设置

上级 cdc1171b
......@@ -109,10 +109,14 @@ COMMIT;
CREATE database if NOT EXISTS `big_market` default character set utf8mb4 collate utf8mb4_0900_ai_ci;
use `big_market`;
DROP TABLE IF EXISTS `strategy`;
CREATE TABLE `strategy` (
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`strategy_id` bigint(8) NOT NULL COMMENT '抽奖策略ID',
`strategy_desc` varchar(128) NOT NULL COMMENT '抽奖策略描述',
`rule_models` varchar(256) DEFAULT NULL COMMENT '规则模型,rule配置的模型同步到此表,便于使用',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
......@@ -122,12 +126,14 @@ CREATE TABLE `strategy` (
LOCK TABLES `strategy` WRITE;
/*!40000 ALTER TABLE `strategy` DISABLE KEYS */;
INSERT INTO `strategy`
(`id`, `strategy_id`, `strategy_desc`, `create_time`, `update_time`)
INSERT INTO `strategy` (`id`, `strategy_id`, `strategy_desc`, `rule_models`, `create_time`, `update_time`)
VALUES
(1,100001,'抽奖策略','2023-12-09 09:37:19','2023-12-09 09:37:19');
(1,100001,'抽奖策略','rule_weight,rule_blacklist','2023-12-09 09:37:19','2023-12-09 18:06:34');
/*!40000 ALTER TABLE `strategy` ENABLE KEYS */;
UNLOCK TABLES;
CREATE TABLE `strategy_award` (
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`strategy_id` bigint(8) NOT NULL COMMENT '抽奖策略ID',
......@@ -167,7 +173,7 @@ CREATE TABLE `strategy_rule` (
`award_id` int(8) DEFAULT NULL COMMENT '抽奖奖品ID【规则类型为策略,则不需要奖品ID】',
`rule_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '抽象规则类型;1-策略规则、2-奖品规则',
`rule_model` varchar(16) NOT NULL COMMENT '抽奖规则类型【rule_random - 随机值计算、rule_lock - 抽奖几次后解锁、rule_luck_award - 幸运奖(兜底奖品)】',
`rule_value` varchar(64) NOT NULL COMMENT '抽奖规则比值',
`rule_value` varchar(256) NOT NULL COMMENT '抽奖规则比值',
`rule_desc` varchar(128) NOT NULL COMMENT '抽奖规则描述',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
......
25-03-03.21:06:31.068 [main ] INFO ApiTest - Starting ApiTest using Java 17.0.10 on xruicc with PID 27140 (started by 15505 in D:\MarketingIntegrationSystem\xfg-frame-archetype-lite-app)
25-03-03.21:06:31.069 [main ] INFO ApiTest - The following 1 profile is active: "dev"
25-03-03.21:06:32.143 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-03-03.21:06:32.148 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-03-03.21:06:32.189 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 14 ms. Found 0 Redis repository interfaces.
25-03-03.21:06:33.173 [main ] INFO Version - Redisson 3.23.4
25-03-03.21:06:33.646 [redisson-netty-2-4] INFO MasterPubSubConnectionPool - 1 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.21:06:33.662 [redisson-netty-2-13] INFO MasterConnectionPool - 5 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.21:06:35.292 [main ] INFO EndpointLinksResolver - Exposing 1 endpoint(s) beneath base path '/actuator'
25-03-03.21:06:35.347 [main ] INFO ApiTest - Started ApiTest in 4.759 seconds (JVM running for 5.923)
25-03-03.21:06:35.870 [main ] INFO ApiTest - 测试结果:100
25-03-03.22:38:56.367 [main ] INFO StrategyArmoryTest - Starting StrategyArmoryTest using Java 17.0.10 on xruicc with PID 19328 (started by 15505 in D:\MarketingIntegrationSystem\xfg-frame-archetype-lite-app)
25-03-03.22:38:56.368 [main ] INFO StrategyArmoryTest - The following 1 profile is active: "dev"
25-03-03.22:38:57.244 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-03-03.22:38:57.246 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-03-03.22:38:57.278 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 16 ms. Found 0 Redis repository interfaces.
25-03-03.22:38:58.526 [main ] INFO Version - Redisson 3.23.4
25-03-03.22:38:59.017 [redisson-netty-2-4] INFO MasterPubSubConnectionPool - 1 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.22:38:59.039 [redisson-netty-2-13] INFO MasterConnectionPool - 5 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.22:39:00.415 [main ] INFO EndpointLinksResolver - Exposing 1 endpoint(s) beneath base path '/actuator'
25-03-03.22:39:00.472 [main ] INFO StrategyArmoryTest - Started StrategyArmoryTest in 4.546 seconds (JVM running for 5.706)
25-03-03.22:39:01.015 [main ] INFO HikariDataSource - HikariPool-1 - Starting...
25-03-03.22:39:01.417 [main ] INFO HikariDataSource - HikariPool-1 - Start completed.
25-03-03.22:39:15.717 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariPool-1 - Shutdown initiated...
25-03-03.22:39:15.734 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariPool-1 - Shutdown completed.
25-03-03.22:49:25.462 [main ] INFO StrategyArmoryTest - Starting StrategyArmoryTest using Java 17.0.10 on xruicc with PID 22388 (started by 15505 in D:\MarketingIntegrationSystem\xfg-frame-archetype-lite-app)
25-03-03.22:49:25.462 [main ] INFO StrategyArmoryTest - The following 1 profile is active: "dev"
25-03-03.22:49:26.394 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-03-03.22:49:26.396 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-03-03.22:49:26.428 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 17 ms. Found 0 Redis repository interfaces.
25-03-03.22:49:27.663 [main ] INFO Version - Redisson 3.23.4
25-03-03.22:49:28.164 [redisson-netty-2-4] INFO MasterPubSubConnectionPool - 1 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.22:49:28.182 [redisson-netty-2-13] INFO MasterConnectionPool - 5 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.22:49:29.535 [main ] INFO EndpointLinksResolver - Exposing 1 endpoint(s) beneath base path '/actuator'
25-03-03.22:49:29.582 [main ] INFO StrategyArmoryTest - Started StrategyArmoryTest in 4.547 seconds (JVM running for 5.653)
25-03-03.22:50:59.298 [main ] INFO StrategyArmoryTest - Starting StrategyArmoryTest using Java 17.0.10 on xruicc with PID 27376 (started by 15505 in D:\MarketingIntegrationSystem\xfg-frame-archetype-lite-app)
25-03-03.22:50:59.299 [main ] INFO StrategyArmoryTest - The following 1 profile is active: "dev"
25-03-03.22:51:00.158 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-03-03.22:51:00.160 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-03-03.22:51:00.191 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 17 ms. Found 0 Redis repository interfaces.
25-03-03.22:51:01.355 [main ] INFO Version - Redisson 3.23.4
25-03-03.22:51:01.816 [redisson-netty-2-4] INFO MasterPubSubConnectionPool - 1 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.22:51:01.837 [redisson-netty-2-13] INFO MasterConnectionPool - 5 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.22:51:03.156 [main ] INFO EndpointLinksResolver - Exposing 1 endpoint(s) beneath base path '/actuator'
25-03-03.22:51:03.209 [main ] INFO StrategyArmoryTest - Started StrategyArmoryTest in 4.371 seconds (JVM running for 5.499)
25-03-03.22:51:03.710 [main ] INFO HikariDataSource - HikariPool-1 - Starting...
25-03-03.22:51:04.076 [main ] INFO HikariDataSource - HikariPool-1 - Start completed.
25-03-03.22:51:04.349 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariPool-1 - Shutdown initiated...
25-03-03.22:51:04.363 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariPool-1 - Shutdown completed.
25-03-03.22:55:30.466 [main ] INFO StrategyArmoryTest - Starting StrategyArmoryTest using Java 17.0.10 on xruicc with PID 11100 (started by 15505 in D:\MarketingIntegrationSystem\xfg-frame-archetype-lite-app)
25-03-03.22:55:30.467 [main ] INFO StrategyArmoryTest - The following 1 profile is active: "dev"
25-03-03.22:55:31.327 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-03-03.22:55:31.332 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-03-03.22:55:31.361 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 15 ms. Found 0 Redis repository interfaces.
25-03-03.22:55:32.533 [main ] INFO Version - Redisson 3.23.4
25-03-03.22:55:32.979 [redisson-netty-2-4] INFO MasterPubSubConnectionPool - 1 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.22:55:32.996 [redisson-netty-2-13] INFO MasterConnectionPool - 5 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.22:55:34.444 [main ] INFO EndpointLinksResolver - Exposing 1 endpoint(s) beneath base path '/actuator'
25-03-03.22:55:34.503 [main ] INFO StrategyArmoryTest - Started StrategyArmoryTest in 4.551 seconds (JVM running for 5.69)
25-03-03.23:05:02.637 [main ] INFO StrategyArmoryTest - Starting StrategyArmoryTest using Java 17.0.10 on xruicc with PID 27872 (started by 15505 in D:\MarketingIntegrationSystem\xfg-frame-archetype-lite-app)
25-03-03.23:05:02.638 [main ] INFO StrategyArmoryTest - The following 1 profile is active: "dev"
25-03-03.23:05:03.612 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-03-03.23:05:03.615 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-03-03.23:05:03.646 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 17 ms. Found 0 Redis repository interfaces.
25-03-03.23:05:05.145 [main ] INFO Version - Redisson 3.23.4
25-03-03.23:05:05.733 [redisson-netty-2-4] INFO MasterPubSubConnectionPool - 1 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.23:05:05.755 [redisson-netty-2-13] INFO MasterConnectionPool - 5 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.23:05:07.553 [main ] INFO EndpointLinksResolver - Exposing 1 endpoint(s) beneath base path '/actuator'
25-03-03.23:05:07.621 [main ] INFO StrategyArmoryTest - Started StrategyArmoryTest in 5.522 seconds (JVM running for 7.136)
25-03-03.23:14:35.673 [main ] INFO StrategyArmoryTest - Starting StrategyArmoryTest using Java 17.0.10 on xruicc with PID 23408 (started by 15505 in D:\MarketingIntegrationSystem\xfg-frame-archetype-lite-app)
25-03-03.23:14:35.674 [main ] INFO StrategyArmoryTest - The following 1 profile is active: "dev"
25-03-03.23:14:36.513 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-03-03.23:14:36.517 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-03-03.23:14:36.545 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 16 ms. Found 0 Redis repository interfaces.
25-03-03.23:14:37.757 [main ] INFO Version - Redisson 3.23.4
25-03-03.23:14:38.190 [redisson-netty-2-4] INFO MasterPubSubConnectionPool - 1 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.23:14:38.206 [redisson-netty-2-13] INFO MasterConnectionPool - 5 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.23:14:39.491 [main ] INFO EndpointLinksResolver - Exposing 1 endpoint(s) beneath base path '/actuator'
25-03-03.23:14:39.534 [main ] INFO StrategyArmoryTest - Started StrategyArmoryTest in 4.288 seconds (JVM running for 5.373)
25-03-03.23:16:07.203 [main ] INFO StrategyArmoryTest - Starting StrategyArmoryTest using Java 17.0.10 on xruicc with PID 26864 (started by 15505 in D:\MarketingIntegrationSystem\xfg-frame-archetype-lite-app)
25-03-03.23:16:07.204 [main ] INFO StrategyArmoryTest - The following 1 profile is active: "dev"
25-03-03.23:16:08.184 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-03-03.23:16:08.186 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-03-03.23:16:08.214 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 16 ms. Found 0 Redis repository interfaces.
25-03-03.23:16:09.432 [main ] INFO Version - Redisson 3.23.4
25-03-03.23:16:09.894 [redisson-netty-2-4] INFO MasterPubSubConnectionPool - 1 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.23:16:09.914 [redisson-netty-2-13] INFO MasterConnectionPool - 5 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-03.23:16:11.278 [main ] INFO EndpointLinksResolver - Exposing 1 endpoint(s) beneath base path '/actuator'
25-03-03.23:16:11.330 [main ] INFO StrategyArmoryTest - Started StrategyArmoryTest in 4.566 seconds (JVM running for 5.677)
25-03-03.23:16:11.810 [main ] INFO StrategyArmoryTest - 测试:101
25-03-03.23:16:11.813 [main ] INFO StrategyArmoryTest - 测试:101
25-03-03.23:16:11.817 [main ] INFO StrategyArmoryTest - 测试:101
25-03-04.22:24:53.944 [main ] INFO StrategyArmoryDispatchTest - Starting StrategyArmoryDispatchTest using Java 17.0.10 on xruicc with PID 4052 (started by 15505 in D:\MarketingIntegrationSystem\xfg-frame-archetype-lite-app)
25-03-04.22:24:53.945 [main ] INFO StrategyArmoryDispatchTest - The following 1 profile is active: "dev"
25-03-04.22:24:55.095 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-03-04.22:24:55.098 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-03-04.22:24:55.133 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 17 ms. Found 0 Redis repository interfaces.
25-03-04.22:24:56.571 [main ] INFO Version - Redisson 3.23.4
25-03-04.22:24:57.068 [redisson-netty-2-4] INFO MasterPubSubConnectionPool - 1 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-04.22:24:57.087 [redisson-netty-2-13] INFO MasterConnectionPool - 5 connections initialized for 192.168.1.10/192.168.1.10:6379
25-03-04.22:24:58.434 [main ] INFO EndpointLinksResolver - Exposing 1 endpoint(s) beneath base path '/actuator'
25-03-04.22:24:58.489 [main ] INFO StrategyArmoryDispatchTest - Started StrategyArmoryDispatchTest in 5.029 seconds (JVM running for 6.288)
25-03-04.22:24:59.246 [main ] INFO HikariDataSource - HikariPool-1 - Starting...
25-03-04.22:24:59.656 [main ] INFO HikariDataSource - HikariPool-1 - Start completed.
25-03-04.22:24:59.767 [main ] INFO StrategyArmoryDispatchTest - 测试结果:101 - 4000 策略配置
25-03-04.22:24:59.770 [main ] INFO StrategyArmoryDispatchTest - 测试结果:101 - 5000 策略配置
25-03-04.22:24:59.773 [main ] INFO StrategyArmoryDispatchTest - 测试结果:103 - 6000 策略配置
25-03-04.22:24:59.805 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariPool-1 - Shutdown initiated...
25-03-04.22:24:59.816 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariPool-1 - Shutdown completed.
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.dao.IStrategyAwardDao;
import cn.bugstack.infrastructure.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;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
......@@ -15,24 +18,27 @@ import javax.annotation.Resource;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class StrategyArmoryTest {
public class StrategyArmoryDispatchTest {
@Resource
private IStrategyArmory strategyArmory;
@Test
@Resource
private IStrategyDispatch strategyDispatch;
@Before
public void test(){
boolean success=strategyArmory.assembleLotteryStrategy(100001l);
log.info(String.valueOf(success));
}
@Test
public void test_getRandomAward(){
log.info("测试:{}", strategyArmory.getRandomAwardId(100001l));
log.info("测试:{}", strategyArmory.getRandomAwardId(100001l));
log.info("测试:{}", strategyArmory.getRandomAwardId(100001l));
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"));
}
}
\ No newline at end of file
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;
import org.checkerframework.checker.lock.qual.NewObject;
import org.checkerframework.common.value.qual.ArrayLen;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StrategyEntity {
/** 抽奖策略ID */
private Long strategyId;
/** 抽奖策略描述 */
private String strategyDesc;
/** 抽奖规则模型 rule_weight,rule_blacklist */
private String ruleModels;
//解析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;
}
}
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;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 策略规则实体
* @create 2023-12-31 15:32
*/
@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<String, List<Integer>> getRuleWeightValues() {
if (!"rule_weight".equals(ruleModel)) return null;
String[] ruleValueGroups = ruleValue.split(Constants.SPACE);
Map<String, List<Integer>> 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<Integer> values = new ArrayList<>();
for (String valueString : valueStrings) {
values.add(Integer.parseInt(valueString));
}
// 将键和值放入Map中
resultMap.put(ruleValueGroup, values);
}
return resultMap;
}
}
......@@ -3,6 +3,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.util.Date;
import java.util.List;
......@@ -12,14 +14,21 @@ import java.util.Map;
* @description 策略服务仓储接口
*/
public interface IStrategyRepository {
List<StrategyAwardEntity> queryStrategyAwardList(Long strategyId);
void storeStrategyAwardSearchRateTable(Long strategyId, int size, Map<Integer, Integer> shuffleStrategyAwardSearchRateTable);
void storeStrategyAwardSearchRateTable(String key, int size, Map<Integer, Integer> shuffleStrategyAwardSearchRateTable);
int getRateRange(Long strategyId);
int getRateRange(String key);
Integer getStrategyAwardAssemble(Long strategyId, Integer rateKey);
StrategyEntity queryStrategyEntityByStrategyId(Long strategyId);
StrategyRuleEntity queryStrategyRule(Long strategyId, String ruleWeight);
// List<StrategyAwardEntity> queryStrategyAwardList(Long strategyId);
//
// <K, V> void storeStrategyAwardSearchRateTable(String key, Integer rateRange, Map<K, V> strategyAwardSearchRateTable);
......
......@@ -14,13 +14,6 @@ public interface IStrategyArmory {
boolean assembleLotteryStrategy(Long strategyId);
/**
* 获取抽奖策略装配的随机结果
*
* @param strategyId 策略ID
* @return 抽奖结果
*/
Integer getRandomAwardId(Long strategyId);
}
package cn.bugstack.domain.strategy.service.armory;
/**
* 策略抽奖调度
*/
public interface IStrategyDispatch {
/**
* 获取抽奖策略装配的随机结果
*
* @param strategyId 策略ID
* @return 抽奖结果
*/
Integer getRandomAwardId(Long strategyId);
/**
* 权重抽奖
*
* @param strategyId 策略ID
* @return 抽奖结果
*/
Integer getRandomAwardId(Long strategyId,String ruleWeightValue);
}
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 lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
......@@ -17,7 +21,7 @@ import java.util.*;
*/
@Slf4j
@Service
public class StrategyArmory implements IStrategyArmory {
public class StrategyArmoryDispatch implements IStrategyArmory,IStrategyDispatch {
@Resource
private IStrategyRepository repository;
......@@ -26,7 +30,36 @@ public class StrategyArmory implements IStrategyArmory {
public boolean assembleLotteryStrategy(Long strategyId) {
//取得了配置实体类
List<StrategyAwardEntity> strategyAwardEntities=repository.queryStrategyAwardList(strategyId);
assembleLotteryStrategy(String.valueOf(strategyId), strategyAwardEntities);
//权重策略配置 -适用于rule_weight 权重规则配置
StrategyEntity strategyEntity=repository.queryStrategyEntityByStrategyId(strategyId);
String ruleWeight = strategyEntity.getRuleWeight();
//一般来说 逻辑少的先判断
if(null==ruleWeight) return true;
//查找具体的策略
StrategyRuleEntity strategyRuleEntity = repository.queryStrategyRule(strategyId, ruleWeight);
if (null == strategyRuleEntity) {
throw new AppException(ResponseCode.STRATEGY_RULE_WEIGHT_IS_NULL.getCode(), ResponseCode.STRATEGY_RULE_WEIGHT_IS_NULL.getInfo());
}
Map<String, List<Integer>> ruleWeightMap = strategyRuleEntity.getRuleWeightValues();
Set<String> keys=ruleWeightMap.keySet();
//取原来的奖品集合 然后过滤掉里面不符合权重规则的奖品
for (String key : keys) {
List<Integer> ruleWeightValues = ruleWeightMap.get(key);
ArrayList<StrategyAwardEntity> strategyAwardEntitiesClone = new ArrayList<>(strategyAwardEntities);
strategyAwardEntitiesClone.removeIf(entity -> !ruleWeightValues.contains(entity.getAwardId()));
assembleLotteryStrategy(String.valueOf(strategyId).concat("_").concat(key), strategyAwardEntitiesClone);
}
return true;
}
private void assembleLotteryStrategy(String key, List<StrategyAwardEntity> strategyAwardEntities) {
//最小的概率
BigDecimal minAwardRate=strategyAwardEntities.stream()
.map(StrategyAwardEntity :: getAwardRate)
......@@ -61,11 +94,11 @@ public class StrategyArmory implements IStrategyArmory {
}
// 8. 存放到 Redis
repository.storeStrategyAwardSearchRateTable(strategyId, shuffleStrategyAwardSearchRateTable.size(), shuffleStrategyAwardSearchRateTable);
repository.storeStrategyAwardSearchRateTable(key, shuffleStrategyAwardSearchRateTable.size(), shuffleStrategyAwardSearchRateTable);
return true;
}
@Override
public Integer getRandomAwardId(Long strategyId) {
// 分布式部署下,不一定为当前应用做的策略装配。也就是值不一定会保存到本应用,而是分布式应用,所以需要从 Redis 中获取。
......@@ -75,5 +108,14 @@ public class StrategyArmory implements IStrategyArmory {
}
@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(strategyId, new SecureRandom().nextInt(rateRange));
}
}
package cn.bugstack.infrastructure.adapter.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.dao.IStrategyAwardDao;
import cn.bugstack.infrastructure.dao.IStrategyDao;
......@@ -34,10 +36,10 @@ public class StrategyRepository implements IStrategyRepository {
// @Resource
// private IRaffleActivityDao raffleActivityDao;
// @Resource
// private IStrategyDao strategyDao;
// @Resource
// private IStrategyRuleDao strategyRuleDao;
@Resource
private IStrategyDao strategyDao;
@Resource
private IStrategyRuleDao strategyRuleDao;
// @Resource
// private IRaffleActivityAccountDao raffleActivityAccountDao;
......@@ -91,11 +93,11 @@ public class StrategyRepository implements IStrategyRepository {
* 简单来说,getMap 方法返回的 RMap 对象是懒加载的,只有在你实际进行操作时,Redis 数据库中的数据结构才会被创建或修改。
*/
@Override
public void storeStrategyAwardSearchRateTable(Long strategyId, int size, Map<Integer, Integer> shuffleStrategyAwardSearchRateTable) {
public void storeStrategyAwardSearchRateTable(String key, int size, Map<Integer, Integer> shuffleStrategyAwardSearchRateTable) {
// 1. 存储抽奖策略范围值,如10000,用于生成1000以内的随机数
redisService.setValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + strategyId, size);
redisService.setValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + key, size);
// 2. 存储概率查找表
Map<Integer, Integer> cacheRateTable = redisService.getMap(Constants.RedisKey.STRATEGY_RATE_TABLE_KEY + strategyId);
Map<Integer, Integer> cacheRateTable = redisService.getMap(Constants.RedisKey.STRATEGY_RATE_TABLE_KEY + key);
cacheRateTable.putAll(shuffleStrategyAwardSearchRateTable);
}
......@@ -105,11 +107,54 @@ public class StrategyRepository implements IStrategyRepository {
return redisService.getValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + strategyId);
}
@Override
public int getRateRange(String key) {
return redisService.getValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + key);
}
@Override
public Integer getStrategyAwardAssemble(Long strategyId, Integer rateKey) {
return redisService.getFromMap(Constants.RedisKey.STRATEGY_RATE_TABLE_KEY + strategyId,rateKey);
}
@Override
public StrategyEntity queryStrategyEntityByStrategyId(Long strategyId) {
//优先从缓存中取
String cacheKey = Constants.RedisKey.STRATEGY_KEY + strategyId;
StrategyEntity strategyEntity = redisService.getValue(cacheKey);
if (null != strategyEntity) return strategyEntity;
Strategy strategy = strategyDao.queryStrategyByStrategyId(strategyId);
strategyEntity = StrategyEntity.builder()
.strategyId(strategy.getStrategyId())
.strategyDesc(strategy.getStrategyDesc())
.ruleModels(strategy.getRuleModels())
.build();
redisService.setValue(cacheKey, strategyEntity);
return strategyEntity;
}
@Override
public StrategyRuleEntity queryStrategyRule(Long strategyId, String ruleModel) {
StrategyRule strategyReq=new StrategyRule();
strategyReq.setStrategyId(strategyId);
strategyReq.setRuleModel(ruleModel);
StrategyRule strategyRule=strategyRuleDao.queryStrategyRule(strategyReq);
return StrategyRuleEntity.builder()
.strategyId(strategyRule.getStrategyId())
.awardId(strategyRule.getAwardId())
.ruleType(strategyRule.getRuleType())
.ruleModel(strategyRule.getRuleModel())
.ruleValue(strategyRule.getRuleValue())
.ruleDesc(strategyRule.getRuleDesc())
.build();
}
//
// @Override
......
......@@ -19,5 +19,6 @@ public class Strategy {
private Date createTime;
private Date updateTime;
private String ruleModels;
}
......@@ -6,9 +6,9 @@ import java.util.Date;
@Data
public class StrategyRule {
private Long id;
private Integer strategyId;
private Long strategyId;
private Integer awardId;
private Byte ruleType;
private Integer ruleType;
private String ruleModel;
private String ruleValue;
private String ruleDesc;
......
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册