Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
KnowledgePlanet
road-map
xfg-frame-archetype-lite
提交
b647fac1
xfg-frame-archetype-lite
项目概览
KnowledgePlanet
/
road-map
/
xfg-frame-archetype-lite
通知
1165
Star
58
Fork
71
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
xfg-frame-archetype-lite
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
b647fac1
编写于
11月 17, 2024
作者:
鲸落和鲨掉
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
策略权重概率装配、抽奖前置规则过滤
上级
ebac0706
变更
34
隐藏空白更改
内联
并排
Showing
34 changed file
with
1175 addition
and
34 deletion
+1175
-34
.idea/dataSources.xml
.idea/dataSources.xml
+14
-0
xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_mapper.xml
...app/src/main/resources/mybatis/mapper/strategy_mapper.xml
+7
-1
xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_rule_mapper.xml
...rc/main/resources/mybatis/mapper/strategy_rule_mapper.xml
+14
-1
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/RaffleStrategyTest.java
...test/java/cn/bugstack/test/domain/RaffleStrategyTest.java
+65
-0
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/StrategyArmoryDispatchTest.java
...a/cn/bugstack/test/domain/StrategyArmoryDispatchTest.java
+5
-5
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/StrategyTest.java
...p/src/test/java/cn/bugstack/test/domain/StrategyTest.java
+110
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/RaffleAwardEntity.java
...stack/domain/strategy/model/entity/RaffleAwardEntity.java
+30
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/RaffleFactorEntity.java
...tack/domain/strategy/model/entity/RaffleFactorEntity.java
+25
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/RuleActionEntity.java
...gstack/domain/strategy/model/entity/RuleActionEntity.java
+61
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/RuleMatterEntity.java
...gstack/domain/strategy/model/entity/RuleMatterEntity.java
+30
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyEntity.java
...bugstack/domain/strategy/model/entity/StrategyEntity.java
+41
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyRuleEntity.java
...tack/domain/strategy/model/entity/StrategyRuleEntity.java
+69
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleLogicCheckTypeVO.java
...ck/domain/strategy/model/valobj/RuleLogicCheckTypeVO.java
+24
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/repository/IStrategyRepository.java
...stack/domain/strategy/repository/IStrategyRepository.java
+14
-2
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/IRaffleStrategy.java
.../cn/bugstack/domain/strategy/service/IRaffleStrategy.java
+18
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/annotation/LogicStrategy.java
...ack/domain/strategy/service/annotation/LogicStrategy.java
+23
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/IStrategyArmory.java
...stack/domain/strategy/service/armory/IStrategyArmory.java
+0
-7
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/IStrategyDispatch.java
...ack/domain/strategy/service/armory/IStrategyDispatch.java
+14
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/StrategyArmoryDispatch.java
...omain/strategy/service/armory/StrategyArmoryDispatch.java
+114
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/AbstractRaffleStrategy.java
...omain/strategy/service/raffle/AbstractRaffleStrategy.java
+78
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/DefaultRaffleStrategy.java
...domain/strategy/service/raffle/DefaultRaffleStrategy.java
+84
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/ILogicFilter.java
...n/bugstack/domain/strategy/service/rule/ILogicFilter.java
+17
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/factory/DefaultLogicFactory.java
...in/strategy/service/rule/factory/DefaultLogicFactory.java
+52
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/impl/RuleBackListLogicFilter.java
...n/strategy/service/rule/impl/RuleBackListLogicFilter.java
+63
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/impl/RuleWeightLogicFilter.java
...ain/strategy/service/rule/impl/RuleWeightLogicFilter.java
+105
-0
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyDao.java
.../bugstack/infrastructure/persistent/dao/IStrategyDao.java
+6
-1
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyRuleDao.java
...stack/infrastructure/persistent/dao/IStrategyRuleDao.java
+7
-1
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/Award.java
.../java/cn/bugstack/infrastructure/persistent/po/Award.java
+2
-0
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/Strategy.java
...va/cn/bugstack/infrastructure/persistent/po/Strategy.java
+10
-9
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/StrategyAward.java
.../bugstack/infrastructure/persistent/po/StrategyAward.java
+2
-0
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/StrategyRule.java
...n/bugstack/infrastructure/persistent/po/StrategyRule.java
+1
-0
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/repository/StrategyRepository.java
...rastructure/persistent/repository/StrategyRepository.java
+63
-7
xfg-frame-archetype-lite-types/src/main/java/cn/bugstack/types/common/Constants.java
...pes/src/main/java/cn/bugstack/types/common/Constants.java
+5
-0
xfg-frame-archetype-lite-types/src/main/java/cn/bugstack/types/enums/ResponseCode.java
...s/src/main/java/cn/bugstack/types/enums/ResponseCode.java
+2
-0
未找到文件。
.idea/dataSources.xml
浏览文件 @
b647fac1
...
...
@@ -13,5 +13,19 @@
</jdbc-additional-properties>
<working-dir>
$ProjectFileDir$
</working-dir>
</data-source>
<data-source
source=
"LOCAL"
name=
"big_market@127.0.0.1"
uuid=
"297e8e74-a084-4e7f-beeb-45bb9a7d972e"
>
<driver-ref>
mysql.8
</driver-ref>
<synchronize>
true
</synchronize>
<imported>
true
</imported>
<remarks>
$PROJECT_DIR$/xfg-frame-archetype-lite-app/src/main/resources/application-dev.yml
</remarks>
<jdbc-driver>
com.mysql.cj.jdbc.Driver
</jdbc-driver>
<jdbc-url>
jdbc:mysql://127.0.0.1:13306/big_market?useUnicode=true
&
characterEncoding=utf8
&
autoReconnect=true
&
zeroDateTimeBehavior=convertToNull
&
serverTimezone=UTC
&
useSSL=true
</jdbc-url>
<jdbc-additional-properties>
<property
name=
"com.intellij.clouds.kubernetes.db.host.port"
/>
<property
name=
"com.intellij.clouds.kubernetes.db.enabled"
value=
"false"
/>
<property
name=
"com.intellij.clouds.kubernetes.db.container.port"
/>
</jdbc-additional-properties>
<working-dir>
$ProjectFileDir$
</working-dir>
</data-source>
</component>
</project>
\ No newline at end of file
xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_mapper.xml
浏览文件 @
b647fac1
...
...
@@ -6,6 +6,7 @@
<id
column=
"id"
property=
"id"
/>
<result
column=
"strategy_id"
property=
"strategyId"
/>
<result
column=
"strategy_desc"
property=
"strategyDesc"
/>
<result
column=
"rule_models"
property=
"ruleModels"
/>
<result
column=
"create_time"
property=
"createTime"
/>
<result
column=
"update_time"
property=
"updateTime"
/>
</resultMap>
...
...
@@ -16,5 +17,10 @@
limit 10
</select>
</mapper>
<select
id=
"queryStrategyByStrategyId"
parameterType=
"java.lang.Long"
resultMap=
"dataMap"
>
select strategy_id, strategy_desc, rule_models
from strategy
where strategy_id = #{strategyId}
</select>
</mapper>
xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/strategy_rule_mapper.xml
浏览文件 @
b647fac1
...
...
@@ -20,5 +20,18 @@
limit 10
</select>
</mapper>
<select
id=
"queryStrategyRule"
parameterType=
"cn.bugstack.infrastructure.persistent.po.StrategyRule"
resultMap=
"dataMap"
>
select strategy_id, award_id, rule_type, rule_model, rule_value, rule_desc
from strategy_rule
where strategy_id = #{strategyId} and rule_model = #{ruleModel}
</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>
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/RaffleStrategyTest.java
0 → 100644
浏览文件 @
b647fac1
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
;
import
java.security.PrivateKey
;
/**
* @ClassName: RaffleStrategyTest
* @Description:
* @Author: zhaoyongfeng
* @Date: 2024/11/17 17:11
*/
@SpringBootTest
@Slf4j
@RunWith
(
SpringRunner
.
class
)
public
class
RaffleStrategyTest
{
@Resource
private
IRaffleStrategy
raffleStrategy
;
@Resource
private
RuleWeightLogicFilter
ruleWeightLogicFilter
;
@Before
public
void
setUp
()
{
ReflectionTestUtils
.
setField
(
ruleWeightLogicFilter
,
"userScore"
,
4500L
);
}
@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
));
}
}
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/StrategyArmoryTest.java
→
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/StrategyArmory
Dispatch
Test.java
浏览文件 @
b647fac1
...
...
@@ -18,18 +18,18 @@ import javax.annotation.Resource;
@SpringBootTest
@Slf4j
@RunWith
(
SpringRunner
.
class
)
public
class
StrategyArmoryTest
{
public
class
StrategyArmory
Dispatch
Test
{
@Resource
private
IStrategyArmory
strategyArmory
;
@Test
/*
@Test
public void test_strategyArmory(){
strategyArmory.assembleLotteryStrategy(100002L);
}
/**
*/
/**
* 从装配的策略中随机获取奖品ID值
*/
*/
/*
@Test
public void test_getAssembleRandomVal() {
log.info("测试结果:{} - 奖品ID值", strategyArmory.getRandomAwardId(100002L));
...
...
@@ -38,5 +38,5 @@ public class StrategyArmoryTest {
log.info("测试结果:{} - 奖品ID值", strategyArmory.getRandomAwardId(100002L));
log.info("测试结果:{} - 奖品ID值", strategyArmory.getRandomAwardId(100002L));
}
}
*/
}
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/StrategyTest.java
0 → 100644
浏览文件 @
b647fac1
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
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
org.springframework.test.context.junit4.SpringRunner
;
import
javax.annotation.Resource
;
import
java.util.*
;
/**
* @ClassName: StrategyTest
* @Description:
* @Author: zhaoyongfeng
* @Date: 2024/11/17 17:18
*/
@Slf4j
@RunWith
(
SpringRunner
.
class
)
@SpringBootTest
public
class
StrategyTest
{
@Resource
private
IStrategyArmory
strategyArmory
;
@Resource
private
IStrategyDispatch
strategyDispatch
;
/**
* 策略ID;100001L、100002L 装配的时候创建策略表写入到 Redis Map 中
*/
@Before
public
void
test_strategyArmory
()
{
boolean
success
=
strategyArmory
.
assembleLotteryStrategy
(
100001L
);
log
.
info
(
"测试结果:{}"
,
success
);
}
/**
* 从装配的策略中随机获取奖品ID值
*/
@Test
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
private
IRedisService
redisService
;
@Test
public
void
test_map
()
{
RMap
<
Integer
,
Integer
>
map
=
redisService
.
getMap
(
"strategy_id_100001"
);
map
.
put
(
1
,
101
);
map
.
put
(
2
,
101
);
map
.
put
(
3
,
101
);
map
.
put
(
4
,
102
);
map
.
put
(
5
,
102
);
map
.
put
(
6
,
102
);
map
.
put
(
7
,
103
);
map
.
put
(
8
,
103
);
map
.
put
(
9
,
104
);
map
.
put
(
10
,
105
);
log
.
info
(
"测试结果:{}"
,
redisService
.
getMap
(
"strategy_id_100001"
).
get
(
1
));
}
@Test
public
void
test_shuffle
(){
Map
<
Integer
,
Integer
>
strategyAwardSearchRateTable
=
new
HashMap
<>();
// 添加内容到Map中
strategyAwardSearchRateTable
.
put
(
1
,
10
);
strategyAwardSearchRateTable
.
put
(
2
,
20
);
strategyAwardSearchRateTable
.
put
(
3
,
30
);
strategyAwardSearchRateTable
.
put
(
4
,
40
);
// 将Map中的值转换为List
List
<
Integer
>
valueList
=
new
ArrayList
<>(
strategyAwardSearchRateTable
.
values
());
// 使用Collections.shuffle()方法对值的List进行乱序
Collections
.
shuffle
(
valueList
);
// 将乱序后的值重新放回Map中
Map
<
Integer
,
Integer
>
randomizedMap
=
new
LinkedHashMap
<>();
Iterator
<
Integer
>
valueIterator
=
valueList
.
iterator
();
for
(
Integer
key
:
strategyAwardSearchRateTable
.
keySet
())
{
randomizedMap
.
put
(
key
,
valueIterator
.
next
());
}
// 打印乱序后的Map内容
for
(
Map
.
Entry
<
Integer
,
Integer
>
entry
:
randomizedMap
.
entrySet
())
{
System
.
out
.
println
(
"Key: "
+
entry
.
getKey
()
+
", Value: "
+
entry
.
getValue
());
}
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/RaffleAwardEntity.java
0 → 100644
浏览文件 @
b647fac1
package
cn.bugstack.domain.strategy.model.entity
;
import
lombok.AllArgsConstructor
;
import
lombok.Builder
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
/**
* @ClassName: RaffleAwardEntity
* @Description: 抽奖奖品实体
* @Author: zhaoyongfeng
* @Date: 2024/11/17 16:25
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public
class
RaffleAwardEntity
{
/** 策略ID */
private
Long
strategyId
;
/** 奖品ID */
private
Integer
awardId
;
/** 奖品对接标识 - 每一个都是一个对应的发奖策略 */
private
String
awardKey
;
/** 奖品配置信息 */
private
String
awardConfig
;
/** 奖品内容描述 */
private
String
awardDesc
;
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/RaffleFactorEntity.java
0 → 100644
浏览文件 @
b647fac1
package
cn.bugstack.domain.strategy.model.entity
;
import
lombok.AllArgsConstructor
;
import
lombok.Builder
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
org.checkerframework.checker.units.qual.A
;
/**
* @ClassName: RaffleFactorEntity
* @Description: 抽奖因子实体
* @Author: zhaoyongfeng
* @Date: 2024/11/17 16:26
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public
class
RaffleFactorEntity
{
/** 用户ID */
private
String
userId
;
/** 策略ID */
private
Long
strategyId
;
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/RuleActionEntity.java
0 → 100644
浏览文件 @
b647fac1
package
cn.bugstack.domain.strategy.model.entity
;
import
cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO
;
import
lombok.*
;
/**
* @ClassName: RuleActionEntity
* @Description: 规则动作
* @Author: zhaoyongfeng
* @Date: 2024/11/17 16:26
*/
@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
{
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/RuleMatterEntity.java
0 → 100644
浏览文件 @
b647fac1
package
cn.bugstack.domain.strategy.model.entity
;
import
lombok.AllArgsConstructor
;
import
lombok.Builder
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
org.checkerframework.checker.units.qual.A
;
/**
* @ClassName: RuleMatterEntity
* @Description: 规则物料实体对象,用于过滤规则的必要参数信息
* @Author: zhaoyongfeng
* @Date: 2024/11/17 16:26
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
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
;
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyEntity.java
0 → 100644
浏览文件 @
b647fac1
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
;
/**
* @ClassName: StrategyEntity
* @Description: 策略实体
* @Author: zhaoyongfeng
* @Date: 2024/11/15 23:35
*/
@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
;
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/entity/StrategyRuleEntity.java
0 → 100644
浏览文件 @
b647fac1
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
;
/**
* @ClassName: StrategyRuleEntity
* @Description: 策略规则实体
* @Author: zhaoyongfeng
* @Date: 2024/11/15 23:36
*/
@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
;
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleLogicCheckTypeVO.java
0 → 100644
浏览文件 @
b647fac1
package
cn.bugstack.domain.strategy.model.valobj
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
/**
* @ClassName: RuleLogicCheckTypeVO
* @Description: 规则过滤校验类型值对象
* @Author: zhaoyongfeng
* @Date: 2024/11/17 16:24
*/
@Getter
@AllArgsConstructor
public
enum
RuleLogicCheckTypeVO
{
ALLOW
(
"0000"
,
"放行;执行后续的流程,不受规则引擎影响"
),
TAKE_OVER
(
"0001"
,
"接管;后续的流程,受规则引擎执行结果影响"
),
;
private
final
String
code
;
private
final
String
info
;
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/repository/IStrategyRepository.java
浏览文件 @
b647fac1
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.List
;
import
java.util.Map
;
public
interface
IStrategyRepository
{
List
<
StrategyAwardEntity
>
queryStrategyAwardList
(
Long
strategyId
);
void
storeStrategyAwardSearchRateTable
(
Long
strategyId
,
Integer
rateRange
,
Map
<
Integer
,
Integer
>
strategyAwardSearchRateTable
);
void
storeStrategyAwardSearchRateTable
(
String
key
,
Integer
rateRange
,
Map
<
Integer
,
Integer
>
strategyAwardSearchRateTable
);
Integer
getStrategyAwardAssemble
(
Long
strategyId
,
Integer
rateKey
);
Integer
getStrategyAwardAssemble
(
String
key
,
Integer
rateKey
);
int
getRateRange
(
Long
strategyId
);
int
getRateRange
(
String
key
);
StrategyEntity
queryStrategyEntityByStrategyId
(
Long
strategyId
);
StrategyRuleEntity
queryStrategyRule
(
Long
strategyId
,
String
ruleModel
);
String
queryStrategyRuleValue
(
Long
strategyId
,
Integer
awardId
,
String
ruleModel
);
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/IRaffleStrategy.java
0 → 100644
浏览文件 @
b647fac1
package
cn.bugstack.domain.strategy.service
;
import
cn.bugstack.domain.strategy.model.entity.RaffleAwardEntity
;
import
cn.bugstack.domain.strategy.model.entity.RaffleFactorEntity
;
public
interface
IRaffleStrategy
{
/**
* 执行抽奖;用抽奖因子入参,执行抽奖计算,返回奖品信息
*
* @param raffleFactorEntity 抽奖因子实体对象,根据入参信息计算抽奖结果
* @return 抽奖的奖品
*/
RaffleAwardEntity
performRaffle
(
RaffleFactorEntity
raffleFactorEntity
);
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/annotation/LogicStrategy.java
0 → 100644
浏览文件 @
b647fac1
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
;
/**
* @ClassName: LogicStrategy
* @Description: 策略自定义枚举
* @Author: zhaoyongfeng
* @Date: 2024/11/17 16:02
*/
@Target
({
ElementType
.
TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
LogicStrategy
{
DefaultLogicFactory
.
LogicModel
logicMode
();
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/IStrategyArmory.java
浏览文件 @
b647fac1
...
...
@@ -10,12 +10,5 @@ public interface IStrategyArmory {
*/
boolean
assembleLotteryStrategy
(
Long
strategyId
);
/**
* 获取抽奖策略装配的随机结果
*
* @param strategyId 策略ID
* @return 抽奖结果
*/
Integer
getRandomAwardId
(
Long
strategyId
);
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/IStrategyDispatch.java
0 → 100644
浏览文件 @
b647fac1
package
cn.bugstack.domain.strategy.service.armory
;
public
interface
IStrategyDispatch
{
/**
* 获取抽奖策略装配的随机结果
*
* @param strategyId 策略ID
* @return 抽奖结果
*/
Integer
getRandomAwardId
(
Long
strategyId
);
Integer
getRandomAwardId
(
Long
strategyId
,
String
ruleWeightValue
);
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/StrategyArmory.java
→
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/armory/StrategyArmory
Dispatch
.java
浏览文件 @
b647fac1
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
;
...
...
@@ -19,51 +23,74 @@ import java.util.*;
*/
@Slf4j
@Service
public
class
StrategyArmory
implements
IStrategyArmory
{
public
class
StrategyArmory
Dispatch
implements
IStrategyArmory
,
IStrategyDispatch
{
@Resource
private
IStrategyRepository
repository
;
@Override
public
boolean
assembleLotteryStrategy
(
Long
strategyId
)
{
//1. 查询策略配置
//
1. 查询策略配置
List
<
StrategyAwardEntity
>
strategyAwardEntities
=
repository
.
queryStrategyAwardList
(
strategyId
);
// 获取最小概率值
assembleLotteryStrategy
(
String
.
valueOf
(
strategyId
),
strategyAwardEntities
);
// 2. 权重策略配置 - 适用于 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
>>
ruleWeightValueMap
=
strategyRuleEntity
.
getRuleWeightValues
();
Set
<
String
>
keys
=
ruleWeightValueMap
.
keySet
();
for
(
String
key
:
keys
)
{
List
<
Integer
>
ruleWeightValues
=
ruleWeightValueMap
.
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
)
{
// 1. 获取最小概率值
BigDecimal
minAwardRate
=
strategyAwardEntities
.
stream
()
.
map
(
StrategyAwardEntity:
:
getAwardRate
)
.
min
(
BigDecimal:
:
compareTo
)
.
orElse
(
BigDecimal
.
ZERO
);
//
3
. 获取概率值总和
//
2
. 获取概率值总和
BigDecimal
totalAwardRate
=
strategyAwardEntities
.
stream
()
.
map
(
StrategyAwardEntity:
:
getAwardRate
)
.
reduce
(
BigDecimal
.
ZERO
,
BigDecimal:
:
add
);
//TODO 需要修改问题
//
4
. 用 1 % 0.0001 获得概率范围,百分位、千分位、万分位
//
3
. 用 1 % 0.0001 获得概率范围,百分位、千分位、万分位
BigDecimal
rateRange
=
totalAwardRate
.
divide
(
minAwardRate
,
0
,
RoundingMode
.
CEILING
);
// 5. 生成策略奖品概率查找表「这里指需要在list集合中,存放上对应的奖品占位即可,占位越多等于概率越高」
ArrayList
<
Integer
>
strategyAwardSearchRateTables
=
new
ArrayList
<>(
rateRange
.
intValue
());
for
(
StrategyAwardEntity
strategyAward:
strategyAwardEntities
){
// 4. 生成策略奖品概率查找表「这里指需要在list集合中,存放上对应的奖品占位即可,占位越多等于概率越高」
List
<
Integer
>
strategyAwardSearchRateTables
=
new
ArrayList
<>(
rateRange
.
intValue
());
for
(
StrategyAwardEntity
strategyAward
:
strategyAwardEntities
)
{
Integer
awardId
=
strategyAward
.
getAwardId
();
BigDecimal
awardRate
=
strategyAward
.
getAwardRate
();
// 计算出每个概率值需要存放到查找表的数量,循环填充
for
(
int
i
=
0
;
i
<
rateRange
.
multiply
(
awardRate
).
setScale
(
0
,
RoundingMode
.
CEILING
).
intValue
();
i
++)
{
strategyAwardSearchRateTables
.
add
(
awardId
);
}
}
// 6. 对存储的奖品进行乱序操作
// 5. 对存储的奖品进行乱序操作
Collections
.
shuffle
(
strategyAwardSearchRateTables
);
// 7. 生成出Map集合,key值,对应的就是后续的概率值。通过概率来获得对应的奖品ID
// 6. 生成出Map集合,key值,对应的就是后续的概率值。通过概率来获得对应的奖品ID
Map
<
Integer
,
Integer
>
shuffleStrategyAwardSearchRateTable
=
new
LinkedHashMap
<>();
for
(
int
i
=
0
;
i
<
strategyAwardSearchRateTables
.
size
();
i
++)
{
shuffleStrategyAwardSearchRateTable
.
put
(
i
,
strategyAwardSearchRateTables
.
get
(
i
));
}
// 8. 存放到 Redis
repository
.
storeStrategyAwardSearchRateTable
(
strategyId
,
shuffleStrategyAwardSearchRateTable
.
size
(),
shuffleStrategyAwardSearchRateTable
);
return
true
;
// 7. 存放到 Redis
repository
.
storeStrategyAwardSearchRateTable
(
key
,
shuffleStrategyAwardSearchRateTable
.
size
(),
shuffleStrategyAwardSearchRateTable
);
}
@Override
...
...
@@ -71,7 +98,17 @@ public class StrategyArmory implements IStrategyArmory{
// 分布式部署下,不一定为当前应用做的策略装配。也就是值不一定会保存到本应用,而是分布式应用,所以需要从 Redis 中获取。
int
rateRange
=
repository
.
getRateRange
(
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
));
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/AbstractRaffleStrategy.java
0 → 100644
浏览文件 @
b647fac1
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.types.enums.ResponseCode
;
import
cn.bugstack.types.exception.AppException
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
/**
* @ClassName: AbstractRaffleStrategy
* @Description: 抽奖策略抽象类,定义抽奖的标准流程
* @Author: zhaoyongfeng
* @Date: 2024/11/17 16:14
*/
@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
());
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
()))
{
// 权重根据返回的信息进行抽奖
RuleActionEntity
.
RaffleBeforeEntity
raffleBeforeEntity
=
ruleActionEntity
.
getData
();
String
ruleWeightValueKey
=
raffleBeforeEntity
.
getRuleWeightValueKey
();
Integer
awardId
=
strategyDispatch
.
getRandomAwardId
(
strategyId
,
ruleWeightValueKey
);
return
RaffleAwardEntity
.
builder
()
.
awardId
(
awardId
)
.
build
();
}
}
// 4. 默认抽奖流程
Integer
awardId
=
strategyDispatch
.
getRandomAwardId
(
strategyId
);
return
RaffleAwardEntity
.
builder
()
.
awardId
(
awardId
)
.
build
();
}
protected
abstract
RuleActionEntity
<
RuleActionEntity
.
RaffleBeforeEntity
>
doCheckRaffleBeforeLogic
(
RaffleFactorEntity
raffleFactorEntity
,
String
...
logics
);
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/DefaultRaffleStrategy.java
0 → 100644
浏览文件 @
b647fac1
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
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
;
/**
* @ClassName: DefaultRaffleStrategy
* @Description: 默认的抽奖策略实现
* @Author: zhaoyongfeng
* @Date: 2024/11/17 16:16
*/
@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
)
{
Map
<
String
,
ILogicFilter
<
RuleActionEntity
.
RaffleBeforeEntity
>>
logicFilterGroup
=
logicFactory
.
openLogicFilter
();
// 黑名单规则优先过滤
String
ruleBackList
=
Arrays
.
stream
(
logics
)
.
filter
(
str
->
str
.
contains
(
DefaultLogicFactory
.
LogicModel
.
RULE_BLACKLIST
.
getCode
()))
.
findFirst
()
.
orElse
(
null
);
if
(
StringUtils
.
isNotBlank
(
ruleBackList
))
{
ILogicFilter
<
RuleActionEntity
.
RaffleBeforeEntity
>
logicFilter
=
logicFilterGroup
.
get
(
DefaultLogicFactory
.
LogicModel
.
RULE_BLACKLIST
.
getCode
());
RuleMatterEntity
ruleMatterEntity
=
new
RuleMatterEntity
();
ruleMatterEntity
.
setUserId
(
raffleFactorEntity
.
getUserId
());
ruleMatterEntity
.
setAwardId
(
ruleMatterEntity
.
getAwardId
());
ruleMatterEntity
.
setStrategyId
(
raffleFactorEntity
.
getStrategyId
());
ruleMatterEntity
.
setRuleModel
(
DefaultLogicFactory
.
LogicModel
.
RULE_BLACKLIST
.
getCode
());
RuleActionEntity
<
RuleActionEntity
.
RaffleBeforeEntity
>
ruleActionEntity
=
logicFilter
.
filter
(
ruleMatterEntity
);
if
(!
RuleLogicCheckTypeVO
.
ALLOW
.
getCode
().
equals
(
ruleActionEntity
.
getCode
()))
{
return
ruleActionEntity
;
}
}
// 顺序过滤剩余规则
List
<
String
>
ruleList
=
Arrays
.
stream
(
logics
)
.
filter
(
s
->
!
s
.
equals
(
DefaultLogicFactory
.
LogicModel
.
RULE_BLACKLIST
.
getCode
()))
.
collect
(
Collectors
.
toList
());
RuleActionEntity
<
RuleActionEntity
.
RaffleBeforeEntity
>
ruleActionEntity
=
null
;
for
(
String
ruleModel
:
ruleList
)
{
ILogicFilter
<
RuleActionEntity
.
RaffleBeforeEntity
>
logicFilter
=
logicFilterGroup
.
get
(
ruleModel
);
RuleMatterEntity
ruleMatterEntity
=
new
RuleMatterEntity
();
ruleMatterEntity
.
setUserId
(
raffleFactorEntity
.
getUserId
());
ruleMatterEntity
.
setAwardId
(
ruleMatterEntity
.
getAwardId
());
ruleMatterEntity
.
setStrategyId
(
raffleFactorEntity
.
getStrategyId
());
ruleMatterEntity
.
setRuleModel
(
ruleModel
);
ruleActionEntity
=
logicFilter
.
filter
(
ruleMatterEntity
);
// 非放行结果则顺序过滤
log
.
info
(
"抽奖前规则过滤 userId: {} ruleModel: {} code: {} info: {}"
,
raffleFactorEntity
.
getUserId
(),
ruleModel
,
ruleActionEntity
.
getCode
(),
ruleActionEntity
.
getInfo
());
if
(!
RuleLogicCheckTypeVO
.
ALLOW
.
getCode
().
equals
(
ruleActionEntity
.
getCode
()))
return
ruleActionEntity
;
}
return
ruleActionEntity
;
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/ILogicFilter.java
0 → 100644
浏览文件 @
b647fac1
package
cn.bugstack.domain.strategy.service.rule
;
import
cn.bugstack.domain.strategy.model.entity.RuleActionEntity
;
import
cn.bugstack.domain.strategy.model.entity.RuleMatterEntity
;
/*
* @return
* @author zhaoyongfeng
* @description 抽奖规则过滤接口
*
* @param null
*/
public
interface
ILogicFilter
<
T
extends
RuleActionEntity
.
RaffleEntity
>
{
RuleActionEntity
<
T
>
filter
(
RuleMatterEntity
ruleMatterEntity
);
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/factory/DefaultLogicFactory.java
0 → 100644
浏览文件 @
b647fac1
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
;
/**
* @ClassName: DefaultLogicFactory
* @Description:
* @Author: zhaoyongfeng
* @Date: 2024/11/17 16:05
*/
@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
;
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/impl/RuleBackListLogicFilter.java
0 → 100644
浏览文件 @
b647fac1
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
;
/**
* @ClassName: RuleBackListLogicFilter
* @Description: 【抽奖前规则】黑名单用户过滤规则
* @Author: zhaoyongfeng
* @Date: 2024/11/17 16:07
*/
@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
();
// 查询规则值配置
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
();
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/impl/RuleWeightLogicFilter.java
0 → 100644
浏览文件 @
b647fac1
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.*
;
/**
* @ClassName: RuleWeightLogicFilter
* @Description: 【抽奖前规则】根据抽奖权重返回可抽奖范围KEY
* @Author: zhaoyongfeng
* @Date: 2024/11/17 16:08
*/
@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
ruleValueKey
:
ruleValueGroups
)
{
// 检查输入是否为空
if
(
ruleValueKey
==
null
||
ruleValueKey
.
isEmpty
())
{
return
ruleValueMap
;
}
// 分割字符串以获取键和值
String
[]
parts
=
ruleValueKey
.
split
(
Constants
.
COLON
);
if
(
parts
.
length
!=
2
)
{
throw
new
IllegalArgumentException
(
"rule_weight rule_rule invalid input format"
+
ruleValueKey
);
}
ruleValueMap
.
put
(
Long
.
parseLong
(
parts
[
0
]),
ruleValueKey
);
}
return
ruleValueMap
;
}
}
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyDao.java
浏览文件 @
b647fac1
package
cn.bugstack.infrastructure.persistent.dao
;
import
cn.bugstack.infrastructure.persistent.po.Award
;
import
cn.bugstack.infrastructure.persistent.po.Strategy
;
import
org.apache.ibatis.annotations.Mapper
;
import
java.util.List
;
@Mapper
public
interface
IStrategyDao
{
List
<
Award
>
queryStrategyList
();
List
<
Strategy
>
queryStrategyList
();
Strategy
queryStrategyByStrategyId
(
Long
strategyId
);
}
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IStrategyRuleDao.java
浏览文件 @
b647fac1
package
cn.bugstack.infrastructure.persistent.dao
;
import
cn.bugstack.infrastructure.persistent.po.Award
;
import
cn.bugstack.infrastructure.persistent.po.StrategyRule
;
import
org.apache.ibatis.annotations.Mapper
;
import
java.util.List
;
@Mapper
public
interface
IStrategyRuleDao
{
List
<
Award
>
queryStrategyRuleList
();
List
<
StrategyRule
>
queryStrategyRuleList
();
StrategyRule
queryStrategyRule
(
StrategyRule
strategyRuleReq
);
String
queryStrategyRuleValue
(
StrategyRule
strategyRule
);
}
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/Award.java
浏览文件 @
b647fac1
package
cn.bugstack.infrastructure.persistent.po
;
import
lombok.Builder
;
import
lombok.Data
;
import
java.util.Date
;
...
...
@@ -28,4 +29,5 @@ public class Award {
/** 更新时间 */
private
Date
updateTime
;
}
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/Strategy.java
浏览文件 @
b647fac1
package
cn.bugstack.infrastructure.persistent.po
;
import
lombok.Builder
;
import
lombok.Data
;
import
java.util.Date
;
...
...
@@ -11,21 +12,21 @@ import java.util.Date;
* @Date: 2024/11/13 20:26
*/
@Data
@Builder
public
class
Strategy
{
/*
ID
*/
/*
* 自增ID
*/
private
Long
id
;
/* 抽奖策略描述*/
/** 抽奖策略ID */
private
Long
strategyId
;
/* 抽奖策略ID*/
/** 抽奖策略描述 */
private
String
strategyDesc
;
/* 创建时间*/
/** 抽奖规则模型 */
private
String
ruleModels
;
/** 创建时间 */
private
Date
createTime
;
/* 更新时间*/
/** 更新时间 */
private
Date
updateTime
;
}
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/StrategyAward.java
浏览文件 @
b647fac1
package
cn.bugstack.infrastructure.persistent.po
;
import
lombok.Builder
;
import
lombok.Data
;
import
java.math.BigDecimal
;
...
...
@@ -38,4 +39,5 @@ public class StrategyAward {
/** 修改时间 */
private
Date
updateTime
;
}
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/StrategyRule.java
浏览文件 @
b647fac1
package
cn.bugstack.infrastructure.persistent.po
;
import
lombok.Builder
;
import
lombok.Data
;
import
java.util.Date
;
...
...
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/repository/StrategyRepository.java
浏览文件 @
b647fac1
...
...
@@ -2,9 +2,15 @@ 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.types.common.Constants
;
import
org.springframework.stereotype.Repository
;
...
...
@@ -24,6 +30,10 @@ import java.util.Map;
@Repository
public
class
StrategyRepository
implements
IStrategyRepository
{
@Resource
private
IStrategyDao
strategyDao
;
@Resource
private
IStrategyRuleDao
strategyRuleDao
;
@Resource
private
IStrategyAwardDao
strategyAwardDao
;
@Resource
...
...
@@ -53,24 +63,70 @@ public class StrategyRepository implements IStrategyRepository {
}
@Override
public
void
storeStrategyAwardSearchRateTable
(
Long
strategyId
,
Integer
rateRange
,
Map
<
Integer
,
Integer
>
strategyAwardSearchRateTable
)
{
public
void
storeStrategyAwardSearchRateTable
(
String
key
,
Integer
rateRange
,
Map
<
Integer
,
Integer
>
strategyAwardSearchRateTable
)
{
// 1. 存储抽奖策略范围值,如10000,用于生成1000以内的随机数
redisService
.
setValue
(
Constants
.
RedisKey
.
STRATEGY_RATE_RANGE_KEY
+
strategyId
,
rateRange
);
redisService
.
setValue
(
Constants
.
RedisKey
.
STRATEGY_RATE_RANGE_KEY
+
key
,
rateRange
);
// 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
(
strategyAwardSearchRateTable
);
}
@Override
public
Integer
getStrategyAwardAssemble
(
Long
strategyId
,
Integer
rateKey
)
{
return
redisService
.
getFromMap
(
Constants
.
RedisKey
.
STRATEGY_RATE_TABLE_KEY
+
strategyId
,
rateKey
);
public
Integer
getStrategyAwardAssemble
(
String
key
,
Integer
rateKey
)
{
return
redisService
.
getFromMap
(
Constants
.
RedisKey
.
STRATEGY_RATE_TABLE_KEY
+
key
,
rateKey
);
}
@Override
public
int
getRateRange
(
Long
strategyId
)
{
return
redisService
.
getValue
(
Constants
.
RedisKey
.
STRATEGY_RATE_RANGE_KEY
+
strategyId
);
return
getRateRange
(
String
.
valueOf
(
strategyId
));
}
@Override
public
int
getRateRange
(
String
key
)
{
return
redisService
.
getValue
(
Constants
.
RedisKey
.
STRATEGY_RATE_RANGE_KEY
+
key
);
}
@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
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
String
queryStrategyRuleValue
(
Long
strategyId
,
Integer
awardId
,
String
ruleModel
)
{
StrategyRule
strategyRule
=
new
StrategyRule
();
strategyRule
.
setStrategyId
(
strategyId
);
strategyRule
.
setAwardId
(
awardId
);
strategyRule
.
setRuleModel
(
ruleModel
);
return
strategyRuleDao
.
queryStrategyRuleValue
(
strategyRule
);
}
}
xfg-frame-archetype-lite-types/src/main/java/cn/bugstack/types/common/Constants.java
浏览文件 @
b647fac1
...
...
@@ -3,11 +3,16 @@ package cn.bugstack.types.common;
public
class
Constants
{
public
final
static
String
SPLIT
=
","
;
public
final
static
String
SPACE
=
" "
;
public
final
static
String
COLON
=
":"
;
public
static
class
RedisKey
{
public
static
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_"
;
}
...
...
xfg-frame-archetype-lite-types/src/main/java/cn/bugstack/types/enums/ResponseCode.java
浏览文件 @
b647fac1
...
...
@@ -12,9 +12,11 @@ public enum ResponseCode {
SUCCESS
(
"0000"
,
"成功"
),
UN_ERROR
(
"0001"
,
"未知失败"
),
ILLEGAL_PARAMETER
(
"0002"
,
"非法参数"
),
STRATEGY_RULE_WEIGHT_IS_NULL
(
"ERR_BIZ_001"
,
"业务异常,策略规则中 rule_weight 权重规则已适用但未配置"
),
;
private
String
code
;
private
String
info
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录