Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
KnowledgePlanet
road-map
xfg-frame-archetype-lite
提交
b4c652e7
xfg-frame-archetype-lite
项目概览
KnowledgePlanet
/
road-map
/
xfg-frame-archetype-lite
通知
1162
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看板
提交
b4c652e7
编写于
4月 23, 2024
作者:
H
hudingrong
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
2024-4-23-rule-flow
上级
7ac02f13
变更
37
隐藏空白更改
内联
并排
Showing
37 changed file
with
572 addition
and
497 deletion
+572
-497
xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/rule_tree_mapper.xml
...pp/src/main/resources/mybatis/mapper/rule_tree_mapper.xml
+21
-0
xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/rule_tree_node_line_mapper.xml
...n/resources/mybatis/mapper/rule_tree_node_line_mapper.xml
+22
-0
xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/rule_tree_node_mapper.xml
...c/main/resources/mybatis/mapper/rule_tree_node_mapper.xml
+21
-0
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/LogicChainTest.java
...src/test/java/cn/bugstack/test/domain/LogicChainTest.java
+6
-6
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/LogicTreeTest.java
.../src/test/java/cn/bugstack/test/domain/LogicTreeTest.java
+10
-10
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/RaffleStrategyTest.java
...test/java/cn/bugstack/test/domain/RaffleStrategyTest.java
+6
-19
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/infrastructure/StrategyRepositoryTest.java
.../bugstack/test/infrastructure/StrategyRepositoryTest.java
+33
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeNodeLineVO.java
...tack/domain/strategy/model/valobj/RuleTreeNodeLineVO.java
+1
-1
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeNodeVO.java
...bugstack/domain/strategy/model/valobj/RuleTreeNodeVO.java
+1
-1
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeVO.java
.../cn/bugstack/domain/strategy/model/valobj/RuleTreeVO.java
+1
-1
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/StrategyAwardRuleModelVO.java
...omain/strategy/model/valobj/StrategyAwardRuleModelVO.java
+0
-22
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/repository/IStrategyRepository.java
...stack/domain/strategy/repository/IStrategyRepository.java
+11
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/annotation/LogicStrategy.java
...ack/domain/strategy/service/annotation/LogicStrategy.java
+0
-21
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/DefaultRaffleStrategy.java
...domain/strategy/service/raffle/DefaultRaffleStrategy.java
+23
-78
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/AbstractRaffleStrategy.java
.../domain/strategy/service/rule/AbstractRaffleStrategy.java
+87
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/chain/ILogicChain.java
...stack/domain/strategy/service/rule/chain/ILogicChain.java
+3
-1
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/chain/factory/DefaultChainFactory.java
...ategy/service/rule/chain/factory/DefaultChainFactory.java
+26
-0
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/chain/impl/BackListLogicChain.java
.../strategy/service/rule/chain/impl/BackListLogicChain.java
+7
-3
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/chain/impl/DefaultLogicChain.java
...n/strategy/service/rule/chain/impl/DefaultLogicChain.java
+7
-3
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/chain/impl/RuleWeightLogicChain.java
...trategy/service/rule/chain/impl/RuleWeightLogicChain.java
+6
-2
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/ILogicFilter.java
...ack/domain/strategy/service/rule/filter/ILogicFilter.java
+0
-16
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/factory/DefaultLogicFactory.java
...tegy/service/rule/filter/factory/DefaultLogicFactory.java
+0
-62
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleBackListLogicFilter.java
...egy/service/rule/filter/impl/RuleBackListLogicFilter.java
+0
-65
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleLockLogicFilter.java
...trategy/service/rule/filter/impl/RuleLockLogicFilter.java
+0
-54
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleWeightLogicFilter.java
...ategy/service/rule/filter/impl/RuleWeightLogicFilter.java
+0
-102
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/DefaultTreeFactory.java
...trategy/service/rule/tree/factory/DefaultTreeFactory.java
+8
-18
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/engine/IDecisionTreeEngine.java
...service/rule/tree/factory/engine/IDecisionTreeEngine.java
+1
-1
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/engine/impl/DecisionTreeEngine.java
...ice/rule/tree/factory/engine/impl/DecisionTreeEngine.java
+3
-3
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleLuckAwardLogicTreeNode.java
...gy/service/rule/tree/impl/RuleLuckAwardLogicTreeNode.java
+1
-1
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IRuleTreeDao.java
.../bugstack/infrastructure/persistent/dao/IRuleTreeDao.java
+16
-0
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IRuleTreeNodeDao.java
...stack/infrastructure/persistent/dao/IRuleTreeNodeDao.java
+18
-0
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IRuleTreeNodeLineDao.java
...k/infrastructure/persistent/dao/IRuleTreeNodeLineDao.java
+18
-0
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/RuleTree.java
...va/cn/bugstack/infrastructure/persistent/po/RuleTree.java
+50
-0
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/RuleTreeNode.java
...n/bugstack/infrastructure/persistent/po/RuleTreeNode.java
+50
-0
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/RuleTreeNodeLine.java
...gstack/infrastructure/persistent/po/RuleTreeNodeLine.java
+48
-0
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/repository/StrategyRepository.java
...rastructure/persistent/repository/StrategyRepository.java
+66
-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
+1
-0
未找到文件。
xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/rule_tree_mapper.xml
0 → 100644
浏览文件 @
b4c652e7
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"cn.bugstack.infrastructure.persistent.dao.IRuleTreeDao"
>
<resultMap
id=
"dataMap"
type=
"cn.bugstack.infrastructure.persistent.po.RuleTree"
>
<id
column=
"id"
property=
"id"
/>
<result
column=
"tree_id"
property=
"treeId"
/>
<result
column=
"tree_name"
property=
"treeName"
/>
<result
column=
"tree_desc"
property=
"treeDesc"
/>
<result
column=
"tree_node_rule_key"
property=
"treeRootRuleKey"
/>
<result
column=
"create_time"
property=
"createTime"
/>
<result
column=
"update_time"
property=
"updateTime"
/>
</resultMap>
<select
id=
"queryRuleTreeByTreeId"
parameterType=
"java.lang.String"
resultMap=
"dataMap"
>
select tree_id, tree_name, tree_desc, tree_node_rule_key
from rule_tree
where tree_id = #{treeId}
</select>
</mapper>
xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/rule_tree_node_line_mapper.xml
0 → 100644
浏览文件 @
b4c652e7
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"cn.bugstack.infrastructure.persistent.dao.IRuleTreeNodeLineDao"
>
<resultMap
id=
"dataMap"
type=
"cn.bugstack.infrastructure.persistent.po.RuleTreeNodeLine"
>
<id
column=
"id"
property=
"id"
/>
<result
column=
"tree_id"
property=
"treeId"
/>
<result
column=
"rule_node_from"
property=
"ruleNodeFrom"
/>
<result
column=
"rule_node_to"
property=
"ruleNodeTo"
/>
<result
column=
"rule_limit_type"
property=
"ruleLimitType"
/>
<result
column=
"rule_limit_value"
property=
"ruleLimitValue"
/>
<result
column=
"create_time"
property=
"createTime"
/>
<result
column=
"update_time"
property=
"updateTime"
/>
</resultMap>
<select
id=
"queryRuleTreeNodeLineListByTreeId"
parameterType=
"java.lang.String"
resultMap=
"dataMap"
>
select tree_id, rule_node_from, rule_node_to, rule_limit_type, rule_limit_value
from rule_tree_node_line
where tree_id = #{treeId}
</select>
</mapper>
xfg-frame-archetype-lite-app/src/main/resources/mybatis/mapper/rule_tree_node_mapper.xml
0 → 100644
浏览文件 @
b4c652e7
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"cn.bugstack.infrastructure.persistent.dao.IRuleTreeNodeDao"
>
<resultMap
id=
"dataMap"
type=
"cn.bugstack.infrastructure.persistent.po.RuleTreeNode"
>
<id
column=
"id"
property=
"id"
/>
<result
column=
"tree_id"
property=
"treeId"
/>
<result
column=
"rule_key"
property=
"ruleKey"
/>
<result
column=
"rule_desc"
property=
"ruleDesc"
/>
<result
column=
"rule_value"
property=
"ruleValue"
/>
<result
column=
"create_time"
property=
"createTime"
/>
<result
column=
"update_time"
property=
"updateTime"
/>
</resultMap>
<select
id=
"queryRuleTreeNodeListByTreeId"
parameterType=
"java.lang.String"
resultMap=
"dataMap"
>
select tree_id, rule_key, rule_desc, rule_value
from rule_tree_node
where tree_id = #{treeId}
</select>
</mapper>
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/LogicChainTest.java
浏览文件 @
b4c652e7
...
...
@@ -42,8 +42,8 @@ public class LogicChainTest {
@Test
public
void
test_LogicChain_rule_blacklist
()
{
ILogicChain
logicChain
=
defaultChainFactory
.
openLogicChain
(
100003L
);
Integer
awardId
=
logicChain
.
logic
(
"user001"
,
100003L
);
log
.
info
(
"测试结果:{}"
,
awardId
);
//
Integer awardId = logicChain.logic("user001", 100003L);
//
log.info("测试结果:{}", awardId);
}
@Test
...
...
@@ -52,16 +52,16 @@ public class LogicChainTest {
ReflectionTestUtils
.
setField
(
ruleWeightLogicChain
,
"userScore"
,
4900L
);
ILogicChain
logicChain
=
defaultChainFactory
.
openLogicChain
(
100001L
);
Integer
awardId
=
logicChain
.
logic
(
"xiaofuge"
,
100001L
);
log
.
info
(
"测试结果:{}"
,
awardId
);
//
Integer awardId = logicChain.logic("xiaofuge", 100001L);
//
log.info("测试结果:{}", awardId);
}
@Test
public
void
test_LogicChain_rule_default
()
{
ILogicChain
logicChain
=
defaultChainFactory
.
openLogicChain
(
100001L
);
Integer
awardId
=
logicChain
.
logic
(
"xiaofuge"
,
100001L
);
log
.
info
(
"测试结果:{}"
,
awardId
);
//
Integer awardId = logicChain.logic("xiaofuge", 100001L);
//
log.info("测试结果:{}", awardId);
}
}
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/LogicTreeTest.java
浏览文件 @
b4c652e7
...
...
@@ -35,13 +35,13 @@ public class LogicTreeTest {
public
void
test_tree_rule
()
{
// 构建参数
RuleTreeNodeVO
rule_lock
=
RuleTreeNodeVO
.
builder
()
.
treeId
(
100000001
)
.
treeId
(
"100000001"
)
.
ruleKey
(
"rule_lock"
)
.
ruleDesc
(
"限定用户已完成N次抽奖后解锁"
)
.
ruleValue
(
"1"
)
.
treeNodeLineVOList
(
new
ArrayList
<
RuleTreeNodeLineVO
>()
{{
add
(
RuleTreeNodeLineVO
.
builder
()
.
treeId
(
100000001
)
.
treeId
(
"100000001"
)
.
ruleNodeFrom
(
"rule_lock"
)
.
ruleNodeTo
(
"rule_luck_award"
)
.
ruleLimitType
(
RuleLimitTypeVO
.
EQUAL
)
...
...
@@ -49,7 +49,7 @@ public class LogicTreeTest {
.
build
());
add
(
RuleTreeNodeLineVO
.
builder
()
.
treeId
(
100000001
)
.
treeId
(
"100000001"
)
.
ruleNodeFrom
(
"rule_lock"
)
.
ruleNodeTo
(
"rule_stock"
)
.
ruleLimitType
(
RuleLimitTypeVO
.
EQUAL
)
...
...
@@ -59,7 +59,7 @@ public class LogicTreeTest {
.
build
();
RuleTreeNodeVO
rule_luck_award
=
RuleTreeNodeVO
.
builder
()
.
treeId
(
100000001
)
.
treeId
(
"100000001"
)
.
ruleKey
(
"rule_luck_award"
)
.
ruleDesc
(
"限定用户已完成N次抽奖后解锁"
)
.
ruleValue
(
"1"
)
...
...
@@ -67,13 +67,13 @@ public class LogicTreeTest {
.
build
();
RuleTreeNodeVO
rule_stock
=
RuleTreeNodeVO
.
builder
()
.
treeId
(
100000001
)
.
treeId
(
"100000001"
)
.
ruleKey
(
"rule_stock"
)
.
ruleDesc
(
"库存处理规则"
)
.
ruleValue
(
null
)
.
treeNodeLineVOList
(
new
ArrayList
<
RuleTreeNodeLineVO
>()
{{
add
(
RuleTreeNodeLineVO
.
builder
()
.
treeId
(
100000001
)
.
treeId
(
"100000001"
)
.
ruleNodeFrom
(
"rule_lock"
)
.
ruleNodeTo
(
"rule_luck_award"
)
.
ruleLimitType
(
RuleLimitTypeVO
.
EQUAL
)
...
...
@@ -83,7 +83,7 @@ public class LogicTreeTest {
.
build
();
RuleTreeVO
ruleTreeVO
=
new
RuleTreeVO
();
ruleTreeVO
.
setTreeId
(
100000001
);
ruleTreeVO
.
setTreeId
(
"100000001"
);
ruleTreeVO
.
setTreeName
(
"决策树规则;增加dall-e-3画图模型"
);
ruleTreeVO
.
setTreeDesc
(
"决策树规则;增加dall-e-3画图模型"
);
ruleTreeVO
.
setTreeRootRuleNode
(
"rule_lock"
);
...
...
@@ -95,9 +95,9 @@ public class LogicTreeTest {
}});
IDecisionTreeEngine
treeEngine
=
defaultTreeFactory
.
openLogicTree
(
ruleTreeVO
);
DefaultTreeFactory
.
StrategyAwardData
data
=
treeEngine
.
process
(
"xiaofuge"
,
100001L
,
100
);
log
.
info
(
"测试结果:{}"
,
JSON
.
toJSONString
(
data
));
//
//
DefaultTreeFactory.StrategyAwardData data = treeEngine.process("xiaofuge", 100001L, 100);
//
log.info("测试结果:{}", JSON.toJSONString(data));
}
...
...
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/RaffleStrategyTest.java
浏览文件 @
b4c652e7
...
...
@@ -4,8 +4,7 @@ import cn.bugstack.domain.strategy.model.entity.RaffleAwardEntity;
import
cn.bugstack.domain.strategy.model.entity.RaffleFactorEntity
;
import
cn.bugstack.domain.strategy.service.IRaffleStrategy
;
import
cn.bugstack.domain.strategy.service.armory.IStrategyArmory
;
import
cn.bugstack.domain.strategy.service.rule.filter.impl.RuleLockLogicFilter
;
import
cn.bugstack.domain.strategy.service.rule.filter.impl.RuleWeightLogicFilter
;
import
cn.bugstack.domain.strategy.service.rule.chain.impl.RuleWeightLogicChain
;
import
com.alibaba.fastjson.JSON
;
import
lombok.extern.slf4j.Slf4j
;
import
org.junit.Before
;
...
...
@@ -32,35 +31,23 @@ public class RaffleStrategyTest {
@Resource
private
IRaffleStrategy
raffleStrategy
;
@Resource
private
RuleWeightLogicFilter
ruleWeightLogicFilter
;
@Resource
private
RuleLockLogicFilter
ruleLockLogicFilter
;
private
RuleWeightLogicChain
ruleWeightLogicChain
;
@Before
public
void
setUp
()
{
// 策略装配 100001、100002、100003
log
.
info
(
"测试结果:{}"
,
strategyArmory
.
assembleLotteryStrategy
(
100001L
));
log
.
info
(
"测试结果:{}"
,
strategyArmory
.
assembleLotteryStrategy
(
100002L
));
log
.
info
(
"测试结果:{}"
,
strategyArmory
.
assembleLotteryStrategy
(
100003L
));
log
.
info
(
"测试结果:{}"
,
strategyArmory
.
assembleLotteryStrategy
(
100006L
));
// 通过反射 mock 规则中的值
ReflectionTestUtils
.
setField
(
ruleWeightLogicFilter
,
"userScore"
,
40500L
);
ReflectionTestUtils
.
setField
(
ruleLockLogicFilter
,
"userRaffleCount"
,
10L
);
ReflectionTestUtils
.
setField
(
ruleWeightLogicChain
,
"userScore"
,
4900L
);
}
@Test
public
void
test
()
{
log
.
info
(
"测试结果:{}"
,
strategyArmory
.
assembleLotteryStrategy
(
100001L
));
log
.
info
(
"测试结果:{}"
,
strategyArmory
.
assembleLotteryStrategy
(
100002L
));
log
.
info
(
"测试结果:{}"
,
strategyArmory
.
assembleLotteryStrategy
(
100003L
));
}
@Test
public
void
test_performRaffle
()
{
RaffleFactorEntity
raffleFactorEntity
=
RaffleFactorEntity
.
builder
()
.
userId
(
"xiaofuge"
)
.
strategyId
(
10000
1
L
)
.
strategyId
(
10000
6
L
)
.
build
();
RaffleAwardEntity
raffleAwardEntity
=
raffleStrategy
.
performRaffle
(
raffleFactorEntity
);
...
...
@@ -73,7 +60,7 @@ public class RaffleStrategyTest {
public
void
test_performRaffle_blacklist
()
{
RaffleFactorEntity
raffleFactorEntity
=
RaffleFactorEntity
.
builder
()
.
userId
(
"user003"
)
// 黑名单用户 user001,user002,user003
.
strategyId
(
10000
3
L
)
.
strategyId
(
10000
1
L
)
.
build
();
RaffleAwardEntity
raffleAwardEntity
=
raffleStrategy
.
performRaffle
(
raffleFactorEntity
);
...
...
xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/infrastructure/StrategyRepositoryTest.java
0 → 100644
浏览文件 @
b4c652e7
package
cn.bugstack.test.infrastructure
;
import
cn.bugstack.domain.strategy.model.valobj.RuleTreeVO
;
import
cn.bugstack.domain.strategy.repository.IStrategyRepository
;
import
com.alibaba.fastjson2.JSON
;
import
lombok.extern.slf4j.Slf4j
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
org.springframework.test.context.junit4.SpringRunner
;
import
javax.annotation.Resource
;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 策略仓储测试
* @create 2024-02-03 09:43
*/
@Slf4j
@RunWith
(
SpringRunner
.
class
)
@SpringBootTest
public
class
StrategyRepositoryTest
{
@Resource
private
IStrategyRepository
strategyRepository
;
@Test
public
void
queryRuleTreeVOByTreeId
()
{
RuleTreeVO
ruleTreeVO
=
strategyRepository
.
queryRuleTreeVOByTreeId
(
"tree_lock"
);
log
.
info
(
"测试结果:{}"
,
JSON
.
toJSONString
(
ruleTreeVO
));
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeNodeLineVO.java
浏览文件 @
b4c652e7
...
...
@@ -18,7 +18,7 @@ import lombok.NoArgsConstructor;
public
class
RuleTreeNodeLineVO
{
/** 规则树ID */
private
Integer
treeId
;
private
String
treeId
;
/** 规则Key节点 From */
private
String
ruleNodeFrom
;
/** 规则Key节点 To */
...
...
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeNodeVO.java
浏览文件 @
b4c652e7
...
...
@@ -20,7 +20,7 @@ import java.util.List;
public
class
RuleTreeNodeVO
{
/** 规则树ID */
private
Integer
treeId
;
private
String
treeId
;
/** 规则Key */
private
String
ruleKey
;
/** 规则描述 */
...
...
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeVO.java
浏览文件 @
b4c652e7
...
...
@@ -19,7 +19,7 @@ import java.util.Map;
@NoArgsConstructor
public
class
RuleTreeVO
{
/** 规则树ID */
private
Integer
treeId
;
private
String
treeId
;
/** 规则树名称 */
private
String
treeName
;
/** 规则树描述 */
...
...
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/StrategyAwardRuleModelVO.java
浏览文件 @
b4c652e7
package
cn.bugstack.domain.strategy.model.valobj
;
import
cn.bugstack.domain.strategy.service.rule.filter.factory.DefaultLogicFactory
;
import
cn.bugstack.types.common.Constants
;
import
lombok.AllArgsConstructor
;
import
lombok.Builder
;
...
...
@@ -25,26 +24,5 @@ public class StrategyAwardRuleModelVO {
private
String
ruleModels
;
/**
* 获取抽奖中规则;或者使用 lambda 表达式
* <p>
* List<String> ruleModelList = Arrays.stream(ruleModels.split(Constants.SPLIT))
* .filter(DefaultLogicFactory.LogicModel::isCenter)
* .collect(Collectors.toList());
* return ruleModelList;
* <p>
* List<String> collect = Arrays.stream(ruleModelValues).filter(DefaultLogicFactory.LogicModel::isCenter).collect(Collectors.toList());
*/
public
String
[]
raffleCenterRuleModelList
()
{
List
<
String
>
ruleModelList
=
new
ArrayList
<>();
String
[]
ruleModeValues
=
ruleModels
.
split
(
Constants
.
SPLIT
);
Arrays
.
stream
(
ruleModeValues
).
forEach
(
item
->
{
if
(
DefaultLogicFactory
.
LogicModel
.
isCenter
(
item
))
{
ruleModelList
.
add
(
item
);
}
});
return
ruleModelList
.
toArray
(
new
String
[
0
]);
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/repository/IStrategyRepository.java
浏览文件 @
b4c652e7
...
...
@@ -3,6 +3,7 @@ package cn.bugstack.domain.strategy.repository;
import
cn.bugstack.domain.strategy.model.entity.StrategyAwardEntity
;
import
cn.bugstack.domain.strategy.model.entity.StrategyEntity
;
import
cn.bugstack.domain.strategy.model.entity.StrategyRuleEntity
;
import
cn.bugstack.domain.strategy.model.valobj.RuleTreeVO
;
import
cn.bugstack.domain.strategy.model.valobj.StrategyAwardRuleModelVO
;
import
java.math.BigDecimal
;
...
...
@@ -93,4 +94,14 @@ public interface IStrategyRepository {
* @return
*/
StrategyAwardRuleModelVO
queryStrategyAwardRuleModelVO
(
Long
strategyId
,
Integer
awardId
);
/**
* 根据规则树ID,查询树结构信息
*
* @param treeId 规则树ID
* @return 树结构信息
*/
RuleTreeVO
queryRuleTreeVOByTreeId
(
String
treeId
);
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/annotation/LogicStrategy.java
已删除
100644 → 0
浏览文件 @
7ac02f13
package
cn.bugstack.domain.strategy.service.annotation
;
import
cn.bugstack.domain.strategy.service.rule.filter.factory.DefaultLogicFactory
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 策略自定义枚举
* @create 2023-12-31 11:29
*/
@Target
({
ElementType
.
TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
LogicStrategy
{
DefaultLogicFactory
.
LogicModel
logicMode
();
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/DefaultRaffleStrategy.java
浏览文件 @
b4c652e7
...
...
@@ -4,11 +4,15 @@ 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.model.valobj.RuleTreeVO
;
import
cn.bugstack.domain.strategy.model.valobj.StrategyAwardRuleModelVO
;
import
cn.bugstack.domain.strategy.repository.IStrategyRepository
;
import
cn.bugstack.domain.strategy.service.armory.IStrategyDispatch
;
import
cn.bugstack.domain.strategy.service.rule.filter.ILogicFilter
;
import
cn.bugstack.domain.strategy.service.rule.AbstractRaffleStrategy
;
import
cn.bugstack.domain.strategy.service.rule.chain.ILogicChain
;
import
cn.bugstack.domain.strategy.service.rule.chain.factory.DefaultChainFactory
;
import
cn.bugstack.domain.strategy.service.rule.filter.factory.DefaultLogicFactory
;
import
cn.bugstack.domain.strategy.service.rule.tree.factory.DefaultTreeFactory
;
import
cn.bugstack.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine
;
import
com.alibaba.fastjson.JSON
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
...
...
@@ -28,91 +32,32 @@ import java.util.stream.Collectors;
*/
@Slf4j
@Service
public
class
DefaultRaffleStrategy
extends
AbstractRaffleStrategy
{
public
class
DefaultRaffleStrategy
extends
AbstractRaffleStrategy
{
@Resource
private
DefaultLogicFactory
logicFactory
;
public
DefaultRaffleStrategy
(
IStrategyRepository
repository
,
IStrategyDispatch
strategyDispatch
,
DefaultChainFactory
defaultChainFactory
)
{
super
(
repository
,
strategyDispatch
,
defaultChainFactory
);
public
DefaultRaffleStrategy
(
IStrategyRepository
repository
,
IStrategyDispatch
strategyDispatch
,
DefaultChainFactory
defaultChainFactory
,
DefaultTreeFactory
defaultTreeFactory
)
{
super
(
repository
,
strategyDispatch
,
defaultChainFactory
,
defaultTreeFactory
);
}
@Override
protected
RuleActionEntity
<
RuleActionEntity
.
RaffleCenterEntity
>
doCheckRaffleCenterLogic
(
RaffleFactorEntity
raffleFactorEntity
,
String
...
logics
)
{
if
(
logics
==
null
||
0
==
logics
.
length
)
return
RuleActionEntity
.<
RuleActionEntity
.
RaffleCenterEntity
>
builder
()
.
code
(
RuleLogicCheckTypeVO
.
ALLOW
.
getCode
())
.
info
(
RuleLogicCheckTypeVO
.
ALLOW
.
getInfo
())
.
build
();
Map
<
String
,
ILogicFilter
<
RuleActionEntity
.
RaffleCenterEntity
>>
logicFilterGroup
=
logicFactory
.
openLogicFilter
();
RuleActionEntity
<
RuleActionEntity
.
RaffleCenterEntity
>
ruleActionEntity
=
null
;
for
(
String
ruleModel
:
logics
)
{
ILogicFilter
<
RuleActionEntity
.
RaffleCenterEntity
>
logicFilter
=
logicFilterGroup
.
get
(
ruleModel
);
RuleMatterEntity
ruleMatterEntity
=
new
RuleMatterEntity
();
ruleMatterEntity
.
setUserId
(
raffleFactorEntity
.
getUserId
());
ruleMatterEntity
.
setAwardId
(
raffleFactorEntity
.
getAwardId
());
ruleMatterEntity
.
setStrategyId
(
raffleFactorEntity
.
getStrategyId
());
ruleMatterEntity
.
setRuleModel
(
ruleModel
);
ruleActionEntity
=
logicFilter
.
filter
(
ruleMatterEntity
);
// 非放行结果则顺序过滤
log
.
info
(
"抽奖中规则过滤 userId: {} ruleModel: {} code: {} info: {}"
,
raffleFactorEntity
.
getUserId
(),
ruleModel
,
ruleActionEntity
.
getCode
(),
ruleActionEntity
.
getInfo
());
if
(!
RuleLogicCheckTypeVO
.
ALLOW
.
getCode
().
equals
(
ruleActionEntity
.
getCode
()))
return
ruleActionEntity
;
}
return
ruleActionEntity
;
public
DefaultChainFactory
.
StrategyAwardVO
raffleLogicChain
(
String
userId
,
Long
strategyId
)
{
ILogicChain
logicChain
=
defaultChainFactory
.
openLogicChain
(
strategyId
);
return
logicChain
.
logic
(
userId
,
strategyId
);
}
@Override
protected
RuleActionEntity
<
RuleActionEntity
.
RaffleBeforeEntity
>
doCheckRaffleBeforeLogic
(
RaffleFactorEntity
raffleFactorEntity
,
String
...
logics
)
{
if
(
logics
==
null
||
0
==
logics
.
length
)
return
RuleActionEntity
.<
RuleActionEntity
.
RaffleBeforeEntity
>
builder
()
.
code
(
RuleLogicCheckTypeVO
.
ALLOW
.
getCode
())
.
info
(
RuleLogicCheckTypeVO
.
ALLOW
.
getInfo
())
.
build
();
log
.
info
(
"raffleFactorEntity:{},logics:{}"
,
JSON
.
toJSONString
(
raffleFactorEntity
),
logics
);
Map
<
String
,
ILogicFilter
<
RuleActionEntity
.
RaffleBeforeEntity
>>
logicFilterGroup
=
logicFactory
.
openLogicFilter
();
// 黑名单规则优先过滤
String
ruleBackList
=
Arrays
.
stream
(
logics
)
.
filter
(
str
->
str
.
contains
(
DefaultLogicFactory
.
LogicModel
.
RULE_BLACKLIST
.
getCode
()))
.
findFirst
()
.
orElse
(
null
);
if
(
StringUtils
.
isNotBlank
(
ruleBackList
))
{
ILogicFilter
<
RuleActionEntity
.
RaffleBeforeEntity
>
logicFilter
=
logicFilterGroup
.
get
(
DefaultLogicFactory
.
LogicModel
.
RULE_BLACKLIST
.
getCode
());
RuleMatterEntity
ruleMatterEntity
=
new
RuleMatterEntity
();
ruleMatterEntity
.
setUserId
(
raffleFactorEntity
.
getUserId
());
ruleMatterEntity
.
setAwardId
(
ruleMatterEntity
.
getAwardId
());
ruleMatterEntity
.
setStrategyId
(
raffleFactorEntity
.
getStrategyId
());
ruleMatterEntity
.
setRuleModel
(
DefaultLogicFactory
.
LogicModel
.
RULE_BLACKLIST
.
getCode
());
RuleActionEntity
<
RuleActionEntity
.
RaffleBeforeEntity
>
ruleActionEntity
=
logicFilter
.
filter
(
ruleMatterEntity
);
if
(!
RuleLogicCheckTypeVO
.
ALLOW
.
getCode
().
equals
(
ruleActionEntity
.
getCode
()))
{
return
ruleActionEntity
;
}
public
DefaultTreeFactory
.
StrategyAwardVO
raffleLogicTree
(
String
userId
,
Long
strategyId
,
Integer
awardId
)
{
StrategyAwardRuleModelVO
strategyAwardRuleModelVO
=
repository
.
queryStrategyAwardRuleModelVO
(
strategyId
,
awardId
);
if
(
null
==
strategyAwardRuleModelVO
)
{
return
DefaultTreeFactory
.
StrategyAwardVO
.
builder
()
.
awardId
(
awardId
)
.
build
();
}
// 顺序过滤剩余规则
List
<
String
>
ruleList
=
Arrays
.
stream
(
logics
)
.
filter
(
str
->
!
str
.
contains
(
DefaultLogicFactory
.
LogicModel
.
RULE_BLACKLIST
.
getCode
()))
.
collect
(
Collectors
.
toList
());
RuleActionEntity
<
RuleActionEntity
.
RaffleBeforeEntity
>
ruleActionEntity
=
null
;
for
(
String
ruleModel
:
ruleList
)
{
ILogicFilter
<
RuleActionEntity
.
RaffleBeforeEntity
>
logicFilter
=
logicFilterGroup
.
get
(
ruleModel
);
RuleMatterEntity
ruleMatterEntity
=
new
RuleMatterEntity
();
ruleMatterEntity
.
setUserId
(
raffleFactorEntity
.
getUserId
());
// todo 数据不对
ruleMatterEntity
.
setAwardId
(
ruleMatterEntity
.
getAwardId
());
ruleMatterEntity
.
setStrategyId
(
raffleFactorEntity
.
getStrategyId
());
ruleMatterEntity
.
setRuleModel
(
ruleModel
);
ruleActionEntity
=
logicFilter
.
filter
(
ruleMatterEntity
);
log
.
info
(
"ruleActionEntity:{}"
,
JSON
.
toJSONString
(
ruleActionEntity
));
log
.
info
(
"抽奖前规则过滤 userId: {} ruleModel: {} code: {} info: {}"
,
raffleFactorEntity
.
getUserId
(),
ruleModel
,
ruleActionEntity
.
getCode
(),
ruleActionEntity
.
getInfo
());
if
(!
RuleLogicCheckTypeVO
.
ALLOW
.
getCode
().
equals
(
ruleActionEntity
.
getCode
()))
{
return
ruleActionEntity
;
}
RuleTreeVO
ruleTreeVO
=
repository
.
queryRuleTreeVOByTreeId
(
strategyAwardRuleModelVO
.
getRuleModels
());
if
(
null
==
ruleTreeVO
)
{
throw
new
RuntimeException
(
"存在抽奖策略配置的规则模型 Key,未在库表 rule_tree、rule_tree_node、rule_tree_line 配置对应的规则树信息 \" + strategyAwardRuleModelVO.getRuleModels()"
);
}
IDecisionTreeEngine
treeEngine
=
defaultTreeFactory
.
openLogicTree
(
ruleTreeVO
);
return
treeEngine
.
process
(
userId
,
strategyId
,
awardId
);
return
ruleActionEntity
;
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/r
aff
le/AbstractRaffleStrategy.java
→
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/r
u
le/AbstractRaffleStrategy.java
浏览文件 @
b4c652e7
package
cn.bugstack.domain.strategy.service.r
aff
le
;
package
cn.bugstack.domain.strategy.service.r
u
le
;
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.model.valobj.StrategyAwardRuleModelVO
;
import
cn.bugstack.domain.strategy.repository.IStrategyRepository
;
import
cn.bugstack.domain.strategy.service.IRaffleStrategy
;
import
cn.bugstack.domain.strategy.service.armory.IStrategyDispatch
;
import
cn.bugstack.domain.strategy.service.rule.chain.ILogicChain
;
import
cn.bugstack.domain.strategy.service.rule.chain.factory.DefaultChainFactory
;
import
cn.bugstack.domain.strategy.service.rule.
filter.factory.DefaultLogic
Factory
;
import
cn.bugstack.domain.strategy.service.rule.
tree.factory.DefaultTree
Factory
;
import
cn.bugstack.types.enums.ResponseCode
;
import
cn.bugstack.types.exception.AppException
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
/**
* @description:
* @description:
抽奖策略抽象类,定义抽奖的标准流程
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.r
aff
le
* @DATE: 2024/4/
12
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.r
u
le
* @DATE: 2024/4/
23
*/
@Slf4j
public
abstract
class
AbstractRaffleStrategy
implements
IRaffleStrategy
{
// 策略仓储服务 -> domain层像一个大厨,仓储层提供米面粮油
protected
IStrategyRepository
repository
;
// 策略调度服务 -> 只负责抽奖处理,通过新增接口的方式,隔离职责,不需要使用方关心或者调用抽奖的初始化
protected
IStrategyDispatch
strategyDispatch
;
// 抽奖的
职责链 -> 抽奖的规则中,解耦出前置规则为职责
链处理
// 抽奖的
责任链 -> 从抽奖的规则中,解耦出前置规则为责任
链处理
protected
final
DefaultChainFactory
defaultChainFactory
;
// 抽奖的决策树 -> 负责抽奖中到抽奖后的规则过滤,如抽奖到A奖品ID,之后要做次数的判断和库存的扣减等。
protected
final
DefaultTreeFactory
defaultTreeFactory
;
public
AbstractRaffleStrategy
(
IStrategyRepository
repository
,
IStrategyDispatch
strategyDispatch
,
DefaultChainFactory
defaultChainFactory
)
{
public
AbstractRaffleStrategy
(
IStrategyRepository
repository
,
IStrategyDispatch
strategyDispatch
,
DefaultChainFactory
defaultChainFactory
,
DefaultTreeFactory
defaultTreeFactory
)
{
this
.
repository
=
repository
;
this
.
strategyDispatch
=
strategyDispatch
;
this
.
defaultChainFactory
=
defaultChainFactory
;
this
.
defaultTreeFactory
=
defaultTreeFactory
;
}
@Override
public
RaffleAwardEntity
performRaffle
(
RaffleFactorEntity
raffleFactorEntity
)
{
// 1. 参数校验
String
userId
=
raffleFactorEntity
.
getUserId
();
Long
strategyId
=
raffleFactorEntity
.
getStrategyId
();
...
...
@@ -49,65 +45,43 @@ public abstract class AbstractRaffleStrategy implements IRaffleStrategy {
throw
new
AppException
(
ResponseCode
.
ILLEGAL_PARAMETER
.
getCode
(),
ResponseCode
.
ILLEGAL_PARAMETER
.
getInfo
());
}
// // 2. 获取抽奖职责链 -> 前置规则的责任链处理
// ILogicChain logicChain = defaultChainFactory.openLogicChain(strategyId);
//
// // 3. 通过职责链获取,获奖id
// Integer awardId = logicChain.logic(userId, strategyId);
// 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
);
// 5. 查询奖品规则「抽奖中(拿到奖品ID时,过滤规则)、抽奖后(扣减完奖品库存后过滤,抽奖中拦截和无库存则走兜底)」
StrategyAwardRuleModelVO
strategyAwardRuleModelVO
=
repository
.
queryStrategyAwardRuleModelVO
(
strategyId
,
awardId
);
// 6. 抽奖中 - 规则过滤
RuleActionEntity
<
RuleActionEntity
.
RaffleCenterEntity
>
ruleActionCenterEntity
=
this
.
doCheckRaffleCenterLogic
(
RaffleFactorEntity
.
builder
()
.
userId
(
userId
)
.
strategyId
(
strategyId
)
.
awardId
(
awardId
)
.
build
(),
strategyAwardRuleModelVO
.
raffleCenterRuleModelList
());
if
(
RuleLogicCheckTypeVO
.
TAKE_OVER
.
getCode
().
equals
(
ruleActionCenterEntity
.
getCode
())){
log
.
info
(
"【临时日志】中奖中规则拦截,通过抽奖后规则 rule_luck_award 走兜底奖励。"
);
// 2. 责任链抽奖计算【这步拿到的是初步的抽奖ID,之后需要根据ID处理抽奖】注意;黑名单、权重等非默认抽奖的直接返回抽奖结果
DefaultChainFactory
.
StrategyAwardVO
chainStrategyAwardVO
=
raffleLogicChain
(
userId
,
strategyId
);
log
.
info
(
"抽奖策略计算-责任链 {} {} {} {}"
,
userId
,
strategyId
,
chainStrategyAwardVO
.
getAwardId
(),
chainStrategyAwardVO
.
getLogicModel
());
if
(!
DefaultChainFactory
.
LogicModel
.
RULE_DEFAULT
.
getCode
().
equals
(
chainStrategyAwardVO
.
getLogicModel
()))
{
return
RaffleAwardEntity
.
builder
()
.
award
Desc
(
"中奖中规则拦截,通过抽奖后规则 rule_luck_award 走兜底奖励。"
)
.
award
Id
(
chainStrategyAwardVO
.
getAwardId
()
)
.
build
();
}
// 3. 规则树抽奖过滤【奖品ID,会根据抽奖次数判断、库存判断、兜底兜里返回最终的可获得奖品信息】
DefaultTreeFactory
.
StrategyAwardVO
treeStrategyAwardVO
=
raffleLogicTree
(
userId
,
strategyId
,
chainStrategyAwardVO
.
getAwardId
());
log
.
info
(
"抽奖策略计算-规则树 {} {} {} {}"
,
userId
,
strategyId
,
treeStrategyAwardVO
.
getAwardId
(),
treeStrategyAwardVO
.
getAwardRuleValue
());
// 4. 返回抽奖结果
return
RaffleAwardEntity
.
builder
()
.
awardId
(
awardId
)
.
awardId
(
treeStrategyAwardVO
.
getAwardId
())
.
awardConfig
(
treeStrategyAwardVO
.
getAwardRuleValue
())
.
build
();
}
protected
abstract
RuleActionEntity
<
RuleActionEntity
.
RaffleCenterEntity
>
doCheckRaffleCenterLogic
(
RaffleFactorEntity
raffleFactorEntity
,
String
...
logics
);
/**
* 抽奖计算,责任链抽象方法
*
* @param userId 用户ID
* @param strategyId 策略ID
* @return 奖品ID
*/
public
abstract
DefaultChainFactory
.
StrategyAwardVO
raffleLogicChain
(
String
userId
,
Long
strategyId
);
/**
* 抽奖结果过滤,决策树抽象方法
*
* @param userId 用户ID
* @param strategyId 策略ID
* @param awardId 奖品ID
* @return 过滤结果【奖品ID,会根据抽奖次数判断、库存判断、兜底兜里返回最终的可获得奖品信息】
*/
public
abstract
DefaultTreeFactory
.
StrategyAwardVO
raffleLogicTree
(
String
userId
,
Long
strategyId
,
Integer
awardId
);
protected
abstract
RuleActionEntity
<
RuleActionEntity
.
RaffleBeforeEntity
>
doCheckRaffleBeforeLogic
(
RaffleFactorEntity
factorEntity
,
String
...
logics
);
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/chain/ILogicChain.java
浏览文件 @
b4c652e7
package
cn.bugstack.domain.strategy.service.rule.chain
;
import
cn.bugstack.domain.strategy.service.rule.chain.factory.DefaultChainFactory
;
/**
* @description: 抽奖策略规则责任链接口
* @author: hdr
...
...
@@ -15,5 +17,5 @@ public interface ILogicChain extends ILogicChainArmory {
* @param strategyId 策略id
* @return 奖品id
*/
Integer
logic
(
String
userId
,
Long
strategyId
);
DefaultChainFactory
.
StrategyAwardVO
logic
(
String
userId
,
Long
strategyId
);
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/chain/factory/DefaultChainFactory.java
浏览文件 @
b4c652e7
...
...
@@ -3,6 +3,7 @@ package cn.bugstack.domain.strategy.service.rule.chain.factory;
import
cn.bugstack.domain.strategy.model.entity.StrategyEntity
;
import
cn.bugstack.domain.strategy.repository.IStrategyRepository
;
import
cn.bugstack.domain.strategy.service.rule.chain.ILogicChain
;
import
lombok.*
;
import
org.springframework.stereotype.Service
;
import
java.util.Map
;
...
...
@@ -47,4 +48,29 @@ public class DefaultChainFactory {
return
logicChain
;
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public
static
class
StrategyAwardVO
{
/** 抽奖奖品ID - 内部流转使用 */
private
Integer
awardId
;
/** */
private
String
logicModel
;
}
@Getter
@AllArgsConstructor
public
enum
LogicModel
{
RULE_DEFAULT
(
"rule_default"
,
"默认抽奖"
),
RULE_BLACKLIST
(
"rule_blacklist"
,
"黑名单抽奖"
),
RULE_WEIGHT
(
"rule_weight"
,
"权重规则"
),
;
private
final
String
code
;
private
final
String
info
;
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/chain/impl/BackListLogicChain.java
浏览文件 @
b4c652e7
...
...
@@ -2,6 +2,7 @@ package cn.bugstack.domain.strategy.service.rule.chain.impl;
import
cn.bugstack.domain.strategy.repository.IStrategyRepository
;
import
cn.bugstack.domain.strategy.service.rule.chain.AbstractLogicChain
;
import
cn.bugstack.domain.strategy.service.rule.chain.factory.DefaultChainFactory
;
import
cn.bugstack.types.common.Constants
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Component
;
...
...
@@ -22,7 +23,7 @@ public class BackListLogicChain extends AbstractLogicChain {
private
IStrategyRepository
repository
;
@Override
public
Integer
logic
(
String
userId
,
Long
strategyId
)
{
public
DefaultChainFactory
.
StrategyAwardVO
logic
(
String
userId
,
Long
strategyId
)
{
log
.
info
(
"抽奖责任链-黑名单开始 userId: {} strategyId: {} ruleModel: {}"
,
userId
,
strategyId
,
ruleModel
());
// 查询规则值配置
...
...
@@ -36,7 +37,10 @@ public class BackListLogicChain extends AbstractLogicChain {
for
(
String
userBlackId
:
userBlackIds
)
{
if
(
userId
.
equals
(
userBlackId
))
{
log
.
info
(
"抽奖责任链-黑名单接管 userId: {} strategyId: {} ruleModel: {} awardId: {}"
,
userId
,
strategyId
,
ruleModel
(),
awardId
);
return
awardId
;
return
DefaultChainFactory
.
StrategyAwardVO
.
builder
()
.
awardId
(
awardId
)
.
logicModel
(
ruleModel
())
.
build
();
}
}
...
...
@@ -48,7 +52,7 @@ public class BackListLogicChain extends AbstractLogicChain {
@Override
protected
String
ruleModel
()
{
return
"rule_blacklist"
;
return
DefaultChainFactory
.
LogicModel
.
RULE_BLACKLIST
.
getCode
()
;
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/chain/impl/DefaultLogicChain.java
浏览文件 @
b4c652e7
...
...
@@ -2,6 +2,7 @@ package cn.bugstack.domain.strategy.service.rule.chain.impl;
import
cn.bugstack.domain.strategy.service.armory.IStrategyDispatch
;
import
cn.bugstack.domain.strategy.service.rule.chain.AbstractLogicChain
;
import
cn.bugstack.domain.strategy.service.rule.chain.factory.DefaultChainFactory
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Component
;
...
...
@@ -22,13 +23,16 @@ public class DefaultLogicChain extends AbstractLogicChain {
@Override
protected
String
ruleModel
()
{
return
"default"
;
return
DefaultChainFactory
.
LogicModel
.
RULE_DEFAULT
.
getCode
()
;
}
@Override
public
Integer
logic
(
String
userId
,
Long
strategyId
)
{
public
DefaultChainFactory
.
StrategyAwardVO
logic
(
String
userId
,
Long
strategyId
)
{
Integer
awardId
=
strategyDispatch
.
getRandomAwardId
(
strategyId
);
log
.
info
(
"抽奖责任链-默认处理 userId: {} strategyId: {} ruleModel: {} awardId: {}"
,
userId
,
strategyId
,
ruleModel
(),
awardId
);
return
awardId
;
return
DefaultChainFactory
.
StrategyAwardVO
.
builder
()
.
awardId
(
awardId
)
.
logicModel
(
ruleModel
())
.
build
();
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/chain/impl/RuleWeightLogicChain.java
浏览文件 @
b4c652e7
...
...
@@ -3,6 +3,7 @@ package cn.bugstack.domain.strategy.service.rule.chain.impl;
import
cn.bugstack.domain.strategy.repository.IStrategyRepository
;
import
cn.bugstack.domain.strategy.service.armory.IStrategyDispatch
;
import
cn.bugstack.domain.strategy.service.rule.chain.AbstractLogicChain
;
import
cn.bugstack.domain.strategy.service.rule.chain.factory.DefaultChainFactory
;
import
cn.bugstack.types.common.Constants
;
import
com.alibaba.fastjson.JSON
;
import
lombok.extern.slf4j.Slf4j
;
...
...
@@ -40,7 +41,7 @@ public class RuleWeightLogicChain extends AbstractLogicChain {
* 2. 解析数据格式;判断哪个范围符合用户的特定抽奖范围
*/
@Override
public
Integer
logic
(
String
userId
,
Long
strategyId
)
{
public
DefaultChainFactory
.
StrategyAwardVO
logic
(
String
userId
,
Long
strategyId
)
{
log
.
info
(
"抽奖责任链-权重开始 userId: {} strategyId: {} ruleModel: {}"
,
userId
,
strategyId
,
ruleModel
());
String
ruleValue
=
repository
.
queryStrategyRuleValue
(
strategyId
,
ruleModel
());
...
...
@@ -66,7 +67,10 @@ public class RuleWeightLogicChain extends AbstractLogicChain {
if
(
null
!=
nextValue
)
{
Integer
awardId
=
strategyDispatch
.
getRandomAwardId
(
strategyId
,
analyticalValueGroup
.
get
(
nextValue
));
log
.
info
(
"抽奖责任链-权重接管 userId: {} strategyId: {} ruleModel: {} awardId: {}"
,
userId
,
strategyId
,
ruleModel
(),
awardId
);
return
awardId
;
return
DefaultChainFactory
.
StrategyAwardVO
.
builder
()
.
awardId
(
awardId
)
.
logicModel
(
ruleModel
())
.
build
();
}
// 5. 过滤其他责任链
...
...
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/ILogicFilter.java
已删除
100644 → 0
浏览文件 @
7ac02f13
package
cn.bugstack.domain.strategy.service.rule.filter
;
import
cn.bugstack.domain.strategy.model.entity.RuleActionEntity
;
import
cn.bugstack.domain.strategy.model.entity.RuleMatterEntity
;
/**
* @description: 抽奖规则过滤接口
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule
* @DATE: 2024/4/12
*/
public
interface
ILogicFilter
<
T
extends
RuleActionEntity
.
RaffleEntity
>
{
RuleActionEntity
<
T
>
filter
(
RuleMatterEntity
ruleMatterEntity
);
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/factory/DefaultLogicFactory.java
已删除
100644 → 0
浏览文件 @
7ac02f13
package
cn.bugstack.domain.strategy.service.rule.filter.factory
;
import
cn.bugstack.domain.strategy.model.entity.RuleActionEntity
;
import
cn.bugstack.domain.strategy.service.annotation.LogicStrategy
;
import
cn.bugstack.domain.strategy.service.rule.filter.ILogicFilter
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
import
org.springframework.core.annotation.AnnotationUtils
;
import
org.springframework.stereotype.Service
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
/**
* @description: 规则工厂
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule.filter.factory
* @DATE: 2024/4/12
*/
@Service
public
class
DefaultLogicFactory
{
public
Map
<
String
,
ILogicFilter
<?>>
logicFilterMap
=
new
ConcurrentHashMap
<>();
public
DefaultLogicFactory
(
List
<
ILogicFilter
<?>>
logicFilters
)
{
logicFilters
.
forEach
(
logic
->
{
LogicStrategy
strategy
=
AnnotationUtils
.
findAnnotation
(
logic
.
getClass
(),
LogicStrategy
.
class
);
if
(
null
!=
strategy
)
{
logicFilterMap
.
put
(
strategy
.
logicMode
().
getCode
(),
logic
);
}
});
}
public
<
T
extends
RuleActionEntity
.
RaffleEntity
>
Map
<
String
,
ILogicFilter
<
T
>>
openLogicFilter
()
{
return
(
Map
<
String
,
ILogicFilter
<
T
>>)
(
Map
<?,
?>)
logicFilterMap
;
}
@Getter
@AllArgsConstructor
public
enum
LogicModel
{
RULE_WIGHT
(
"rule_weight"
,
"【抽奖前规则】根据抽奖权重返回可抽奖范围KEY"
,
"before"
),
RULE_BLACKLIST
(
"rule_blacklist"
,
"【抽奖前规则】黑名单规则过滤,命中黑名单则直接返回"
,
"before"
),
RULE_LOCK
(
"rule_lock"
,
"【抽奖中规则】抽奖n次后,对应奖品可解锁抽奖"
,
"center"
),
RULE_LUCK_AWARD
(
"rule_luck_award"
,
"【抽奖后规则】抽奖n次后,对应奖品可解锁抽奖"
,
"after"
),
;
private
final
String
code
;
private
final
String
info
;
private
final
String
type
;
public
static
boolean
isCenter
(
String
code
){
return
"center"
.
equals
(
LogicModel
.
valueOf
(
code
.
toUpperCase
()).
type
);
}
public
static
boolean
isAfter
(
String
code
){
return
"after"
.
equals
(
LogicModel
.
valueOf
(
code
.
toUpperCase
()).
type
);
}
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleBackListLogicFilter.java
已删除
100644 → 0
浏览文件 @
7ac02f13
package
cn.bugstack.domain.strategy.service.rule.filter.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.filter.ILogicFilter
;
import
cn.bugstack.domain.strategy.service.rule.filter.factory.DefaultLogicFactory
;
import
cn.bugstack.types.common.Constants
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
/**
* @description: [抽奖前规则]黑名单用户过滤规则
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule.filter.impl
* @DATE: 2024/4/12
*/
@Slf4j
@Component
@LogicStrategy
(
logicMode
=
DefaultLogicFactory
.
LogicModel
.
RULE_BLACKLIST
)
public
class
RuleBackListLogicFilter
implements
ILogicFilter
<
RuleActionEntity
.
RaffleBeforeEntity
>
{
@Resource
private
IStrategyRepository
repository
;
@Override
public
RuleActionEntity
<
RuleActionEntity
.
RaffleBeforeEntity
>
filter
(
RuleMatterEntity
ruleMatterEntity
)
{
log
.
info
(
"规则过滤-黑名单 userId:{} strategyId:{} ruleModel:{}"
,
ruleMatterEntity
.
getUserId
(),
ruleMatterEntity
.
getStrategyId
(),
ruleMatterEntity
.
getRuleModel
());
String
userId
=
ruleMatterEntity
.
getUserId
();
// 100:user001,user002,user003
// 查询规则值配置
String
ruleValue
=
repository
.
queryStrategyRuleValue
(
ruleMatterEntity
.
getStrategyId
(),
ruleMatterEntity
.
getAwardId
(),
ruleMatterEntity
.
getRuleModel
());
String
[]
splitRuleValue
=
ruleValue
.
split
(
Constants
.
COLON
);
//
Integer
awardId
=
Integer
.
parseInt
(
splitRuleValue
[
0
]);
// 过滤其他规则
String
[]
userBlackIds
=
splitRuleValue
[
1
].
split
(
Constants
.
SPLIT
);
for
(
String
userBlackId
:
userBlackIds
)
{
if
(
userId
.
equals
(
userBlackId
))
{
return
RuleActionEntity
.<
RuleActionEntity
.
RaffleBeforeEntity
>
builder
()
.
ruleModel
(
DefaultLogicFactory
.
LogicModel
.
RULE_BLACKLIST
.
getCode
())
.
data
(
RuleActionEntity
.
RaffleBeforeEntity
.
builder
()
.
strategyId
(
ruleMatterEntity
.
getStrategyId
())
.
awardId
(
awardId
)
.
build
())
.
code
(
RuleLogicCheckTypeVO
.
TAKE_OVER
.
getCode
())
.
info
(
RuleLogicCheckTypeVO
.
TAKE_OVER
.
getInfo
())
.
build
();
}
}
return
RuleActionEntity
.<
RuleActionEntity
.
RaffleBeforeEntity
>
builder
()
.
code
(
RuleLogicCheckTypeVO
.
ALLOW
.
getCode
())
.
info
(
RuleLogicCheckTypeVO
.
ALLOW
.
getInfo
())
.
build
();
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleLockLogicFilter.java
已删除
100644 → 0
浏览文件 @
7ac02f13
package
cn.bugstack.domain.strategy.service.rule.filter.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.filter.ILogicFilter
;
import
cn.bugstack.domain.strategy.service.rule.filter.factory.DefaultLogicFactory
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
/**
* @description: 用户抽奖n次后,对应奖品可解锁抽奖
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.raffle
* @DATE: 2024/4/16
*/
@Slf4j
@Component
@LogicStrategy
(
logicMode
=
DefaultLogicFactory
.
LogicModel
.
RULE_LOCK
)
public
class
RuleLockLogicFilter
implements
ILogicFilter
<
RuleActionEntity
.
RaffleCenterEntity
>
{
@Resource
private
IStrategyRepository
repository
;
// 测试数据
private
Long
userRaffleCount
=
0L
;
@Override
public
RuleActionEntity
<
RuleActionEntity
.
RaffleCenterEntity
>
filter
(
RuleMatterEntity
ruleMatterEntity
)
{
log
.
info
(
"规则过滤-次数锁 userId:{} strategyId:{} ruleModel:{}"
,
ruleMatterEntity
.
getUserId
(),
ruleMatterEntity
.
getStrategyId
(),
ruleMatterEntity
.
getRuleModel
());
// 查询规则值配置;当前奖品ID,抽奖中规则对应的校验值。如;1、2、6
String
ruleValue
=
repository
.
queryStrategyRuleValue
(
ruleMatterEntity
.
getStrategyId
(),
ruleMatterEntity
.
getAwardId
(),
ruleMatterEntity
.
getRuleModel
());
long
raffleCount
=
Long
.
parseLong
(
ruleValue
);
// 用户抽奖次数大于规则限定值,规则放行
if
(
userRaffleCount
>=
raffleCount
)
{
return
RuleActionEntity
.<
RuleActionEntity
.
RaffleCenterEntity
>
builder
()
.
code
(
RuleLogicCheckTypeVO
.
ALLOW
.
getCode
())
.
info
(
RuleLogicCheckTypeVO
.
ALLOW
.
getInfo
())
.
build
();
}
// 用户抽奖次数小于规则限定值,规则拦截
return
RuleActionEntity
.<
RuleActionEntity
.
RaffleCenterEntity
>
builder
()
.
code
(
RuleLogicCheckTypeVO
.
TAKE_OVER
.
getCode
())
.
info
(
RuleLogicCheckTypeVO
.
TAKE_OVER
.
getInfo
())
.
build
();
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleWeightLogicFilter.java
已删除
100644 → 0
浏览文件 @
7ac02f13
package
cn.bugstack.domain.strategy.service.rule.filter.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.filter.ILogicFilter
;
import
cn.bugstack.domain.strategy.service.rule.filter.factory.DefaultLogicFactory
;
import
cn.bugstack.types.common.Constants
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
import
java.util.*
;
/**
* @description: [抽奖前规则] 根据抽奖鉴权重返可抽奖范围key
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule.filter.impl
* @DATE: 2024/4/12
*/
@Slf4j
@Component
@LogicStrategy
(
logicMode
=
DefaultLogicFactory
.
LogicModel
.
RULE_WIGHT
)
public
class
RuleWeightLogicFilter
implements
ILogicFilter
<
RuleActionEntity
.
RaffleBeforeEntity
>
{
@Resource
private
IStrategyRepository
repository
;
public
Long
userScore
=
4500L
;
/**
* 1. 权重规则格式;4000:102,103,104,105 5000:102,103,104,105,106,107 6000:102,103,104,105,106,107,108,109
* 2. 解析数据格式;判断哪个范围符合用户的特定抽奖范围
* @param ruleMatterEntity
* @return
*/
@Override
public
RuleActionEntity
<
RuleActionEntity
.
RaffleBeforeEntity
>
filter
(
RuleMatterEntity
ruleMatterEntity
)
{
log
.
info
(
"规则过滤-权重范围 userId:{} strategyId:{} ruleModel:{}"
,
ruleMatterEntity
.
getUserId
(),
ruleMatterEntity
.
getStrategyId
(),
ruleMatterEntity
.
getRuleModel
());
String
userId
=
ruleMatterEntity
.
getUserId
();
Long
strategyId
=
ruleMatterEntity
.
getStrategyId
();
String
ruleValue
=
repository
.
queryStrategyRuleValue
(
ruleMatterEntity
.
getStrategyId
(),
ruleMatterEntity
.
getAwardId
(),
ruleMatterEntity
.
getRuleModel
());
// 1. 根据用户ID查询用户抽奖消耗的积分值,本章节我们先写死为固定的值。后续需要从数据库中查询。
Map
<
Long
,
String
>
analyticalValueGroup
=
getAnalyticalValue
(
ruleValue
);
if
(
null
==
analyticalValueGroup
||
analyticalValueGroup
.
isEmpty
())
{
return
RuleActionEntity
.<
RuleActionEntity
.
RaffleBeforeEntity
>
builder
()
.
code
(
RuleLogicCheckTypeVO
.
ALLOW
.
getCode
())
.
info
(
RuleLogicCheckTypeVO
.
ALLOW
.
getInfo
())
.
build
();
}
// 2. 转换Keys值,并默认排序
List
<
Long
>
analyticalSortedKeys
=
new
ArrayList
<>(
analyticalValueGroup
.
keySet
());
Collections
.
sort
(
analyticalSortedKeys
);
// 3. 找出最小符合的值,也就是【4500 积分,能找到 4000:102,103,104,105】、【5000 积分,能找到 5000:102,103,104,105,106,107】
Long
nextValue
=
analyticalSortedKeys
.
stream
()
.
filter
(
key
->
userScore
>=
key
)
.
findFirst
()
.
orElse
(
null
);
if
(
null
!=
nextValue
)
{
return
RuleActionEntity
.<
RuleActionEntity
.
RaffleBeforeEntity
>
builder
()
.
data
(
RuleActionEntity
.
RaffleBeforeEntity
.
builder
()
.
strategyId
(
strategyId
)
.
ruleWeightValueKey
(
analyticalValueGroup
.
get
(
nextValue
))
.
build
())
.
ruleModel
(
DefaultLogicFactory
.
LogicModel
.
RULE_WIGHT
.
getCode
())
.
code
(
RuleLogicCheckTypeVO
.
TAKE_OVER
.
getCode
())
.
info
(
RuleLogicCheckTypeVO
.
TAKE_OVER
.
getInfo
())
.
build
();
}
return
RuleActionEntity
.<
RuleActionEntity
.
RaffleBeforeEntity
>
builder
()
.
code
(
RuleLogicCheckTypeVO
.
ALLOW
.
getCode
())
.
info
(
RuleLogicCheckTypeVO
.
ALLOW
.
getInfo
())
.
build
();
}
private
Map
<
Long
,
String
>
getAnalyticalValue
(
String
ruleValue
)
{
String
[]
ruleValueGroups
=
ruleValue
.
split
(
Constants
.
SPACE
);
Map
<
Long
,
String
>
ruleValueMap
=
new
HashMap
<>();
for
(
String
ruleValueGroup
:
ruleValueGroups
)
{
// 检查驶入是否为空
if
(
ruleValueGroup
==
null
||
ruleValueGroup
.
isEmpty
())
{
return
ruleValueMap
;
}
// 分割字符串以获取键和值
String
[]
parts
=
ruleValueGroup
.
split
(
Constants
.
COLON
);
if
(
parts
.
length
<
2
)
{
throw
new
IllegalArgumentException
(
"rule_weight rule_rule invalid input format"
+
ruleValueGroup
);
}
ruleValueMap
.
put
(
Long
.
parseLong
(
parts
[
0
]),
ruleValueGroup
);
}
return
ruleValueMap
;
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/DefaultTreeFactory.java
浏览文件 @
b4c652e7
...
...
@@ -5,10 +5,7 @@ import cn.bugstack.domain.strategy.model.valobj.RuleTreeVO;
import
cn.bugstack.domain.strategy.service.rule.tree.ILogicTreeNode
;
import
cn.bugstack.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine
;
import
cn.bugstack.domain.strategy.service.rule.tree.factory.engine.impl.DecisionTreeEngine
;
import
lombok.AllArgsConstructor
;
import
lombok.Builder
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
lombok.*
;
import
org.springframework.stereotype.Service
;
import
java.util.Map
;
...
...
@@ -31,35 +28,28 @@ public class DefaultTreeFactory {
return
new
DecisionTreeEngine
(
logicTreeNodeGroup
,
ruleTreeVO
);
}
/**
* 决策树
动作实现
* 决策树
个动作实习
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public
static
class
TreeActionEntity
{
public
static
class
TreeActionEntity
{
private
RuleLogicCheckTypeVO
ruleLogicCheckType
;
private
StrategyAward
Data
strategyAwardData
;
private
StrategyAward
VO
strategyAwardVO
;
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public
static
class
StrategyAwardData
{
/**
* 抽奖奖品ID - 内部流转
*/
public
static
class
StrategyAwardVO
{
/** 抽奖奖品ID - 内部流转使用 */
private
Integer
awardId
;
/**
* 抽奖奖品规则
*/
/** 抽奖奖品规则 */
private
String
awardRuleValue
;
}
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/engine/IDecisionTreeEngine.java
浏览文件 @
b4c652e7
...
...
@@ -10,5 +10,5 @@ import cn.bugstack.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
*/
public
interface
IDecisionTreeEngine
{
DefaultTreeFactory
.
StrategyAward
Data
process
(
String
userId
,
Long
strategyId
,
Integer
awardId
);
DefaultTreeFactory
.
StrategyAward
VO
process
(
String
userId
,
Long
strategyId
,
Integer
awardId
);
}
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/engine/impl/DecisionTreeEngine.java
浏览文件 @
b4c652e7
...
...
@@ -31,9 +31,9 @@ public class DecisionTreeEngine implements IDecisionTreeEngine {
}
@Override
public
DefaultTreeFactory
.
StrategyAward
Data
process
(
String
userId
,
Long
strategyId
,
Integer
awardId
)
{
public
DefaultTreeFactory
.
StrategyAward
VO
process
(
String
userId
,
Long
strategyId
,
Integer
awardId
)
{
DefaultTreeFactory
.
StrategyAward
Data
strategyAwardData
=
null
;
DefaultTreeFactory
.
StrategyAward
VO
strategyAwardData
=
null
;
// 获取基础信息
String
nextNode
=
ruleTreeVO
.
getTreeRootRuleNode
();
...
...
@@ -46,7 +46,7 @@ public class DecisionTreeEngine implements IDecisionTreeEngine {
DefaultTreeFactory
.
TreeActionEntity
logicEntity
=
logicTreeNode
.
logic
(
userId
,
strategyId
,
awardId
);
RuleLogicCheckTypeVO
ruleLogicCheckTypeVO
=
logicEntity
.
getRuleLogicCheckType
();
strategyAwardData
=
logicEntity
.
getStrategyAward
Data
();
strategyAwardData
=
logicEntity
.
getStrategyAward
VO
();
log
.
info
(
"决策树引擎【{}】treeId:{} node:{} code:{}"
,
ruleTreeVO
.
getTreeName
(),
ruleTreeVO
.
getTreeId
(),
nextNode
,
ruleLogicCheckTypeVO
.
getCode
());
// 获取下个节点
...
...
xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleLuckAwardLogicTreeNode.java
浏览文件 @
b4c652e7
...
...
@@ -20,7 +20,7 @@ public class RuleLuckAwardLogicTreeNode implements ILogicTreeNode {
return
DefaultTreeFactory
.
TreeActionEntity
.
builder
()
.
ruleLogicCheckType
(
RuleLogicCheckTypeVO
.
TAKE_OVER
)
.
strategyAward
Data
(
DefaultTreeFactory
.
StrategyAwardData
.
builder
()
.
strategyAward
VO
(
DefaultTreeFactory
.
StrategyAwardVO
.
builder
()
.
awardId
(
101
)
.
awardRuleValue
(
"1,100"
)
.
build
())
...
...
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IRuleTreeDao.java
0 → 100644
浏览文件 @
b4c652e7
package
cn.bugstack.infrastructure.persistent.dao
;
import
cn.bugstack.infrastructure.persistent.po.RuleTree
;
import
org.apache.ibatis.annotations.Mapper
;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 规则树表DAO
* @create 2024-02-03 08:42
*/
@Mapper
public
interface
IRuleTreeDao
{
RuleTree
queryRuleTreeByTreeId
(
String
treeId
);
}
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IRuleTreeNodeDao.java
0 → 100644
浏览文件 @
b4c652e7
package
cn.bugstack.infrastructure.persistent.dao
;
import
cn.bugstack.infrastructure.persistent.po.RuleTreeNode
;
import
org.apache.ibatis.annotations.Mapper
;
import
java.util.List
;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 规则树节点表DAO
* @create 2024-02-03 08:43
*/
@Mapper
public
interface
IRuleTreeNodeDao
{
List
<
RuleTreeNode
>
queryRuleTreeNodeListByTreeId
(
String
treeId
);
}
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/dao/IRuleTreeNodeLineDao.java
0 → 100644
浏览文件 @
b4c652e7
package
cn.bugstack.infrastructure.persistent.dao
;
import
cn.bugstack.infrastructure.persistent.po.RuleTreeNodeLine
;
import
org.apache.ibatis.annotations.Mapper
;
import
java.util.List
;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 规则树节点连线表DAO
* @create 2024-02-03 08:44
*/
@Mapper
public
interface
IRuleTreeNodeLineDao
{
List
<
RuleTreeNodeLine
>
queryRuleTreeNodeLineListByTreeId
(
String
treeId
);
}
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/RuleTree.java
0 → 100644
浏览文件 @
b4c652e7
package
cn.bugstack.infrastructure.persistent.po
;
import
lombok.Data
;
import
java.util.Date
;
/**
* @description: 规则树
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.infrastructure.persistent.po
* @DATE: 2024/4/23
*/
@Data
public
class
RuleTree
{
/**
* 自增ID
*/
private
Long
id
;
/**
* 规则树ID
*/
private
String
treeId
;
/**
* 规则树名称
*/
private
String
treeName
;
/**
* 规则树描述
*/
private
String
treeDesc
;
/**
* 规则根节点
*/
private
String
treeRootRuleKey
;
/**
* 创建时间
*/
private
Date
createTime
;
/**
* 更新时间
*/
private
Date
updateTime
;
}
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/RuleTreeNode.java
0 → 100644
浏览文件 @
b4c652e7
package
cn.bugstack.infrastructure.persistent.po
;
import
lombok.Data
;
import
java.util.Date
;
/**
* @description: 规则树节点
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.infrastructure.persistent.po
* @DATE: 2024/4/23
*/
@Data
public
class
RuleTreeNode
{
/**
* 自增ID
*/
private
Long
id
;
/**
* 规则树ID
*/
private
String
treeId
;
/**
* 规则key
*/
private
String
ruleKey
;
/**
* 规则描述
*/
private
String
ruleDesc
;
/**
* 规则比值
*/
private
String
ruleValue
;
/**
* 创建时间
*/
private
Date
createTime
;
/**
* 更新时间
*/
private
Date
updateTime
;
}
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/po/RuleTreeNodeLine.java
0 → 100644
浏览文件 @
b4c652e7
package
cn.bugstack.infrastructure.persistent.po
;
import
lombok.Data
;
import
java.util.Date
;
/**
* @description: 规则树节点连线
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.infrastructure.persistent.po
* @DATE: 2024/4/23
*/
@Data
public
class
RuleTreeNodeLine
{
/**
* 自增ID
*/
private
Long
id
;
/**
* 规则树ID
*/
private
String
treeId
;
/**
* 规则key节点 from
*/
private
String
ruleNodeFrom
;
/**
* 规则key节点 to
*/
private
String
ruleNodeTo
;
/**
* 限定类型:1:=;2:>;3:<;4:>=;5<=;6:enum[枚举范围]
*/
private
String
ruleLimitType
;
/**
* 限定值(到下个节点)
*/
private
String
ruleLimitValue
;
/**
* 创建时间
*/
private
Date
createTime
;
/**
* 更新时间
*/
private
Date
updateTime
;
}
xfg-frame-archetype-lite-infrastructure/src/main/java/cn/bugstack/infrastructure/persistent/repository/StrategyRepository.java
浏览文件 @
b4c652e7
...
...
@@ -3,14 +3,10 @@ package cn.bugstack.infrastructure.persistent.repository;
import
cn.bugstack.domain.strategy.model.entity.StrategyAwardEntity
;
import
cn.bugstack.domain.strategy.model.entity.StrategyEntity
;
import
cn.bugstack.domain.strategy.model.entity.StrategyRuleEntity
;
import
cn.bugstack.domain.strategy.model.valobj.
StrategyAwardRuleModelVO
;
import
cn.bugstack.domain.strategy.model.valobj.
*
;
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.dao.*
;
import
cn.bugstack.infrastructure.persistent.po.*
;
import
cn.bugstack.infrastructure.persistent.redis.IRedisService
;
import
cn.bugstack.types.common.Constants
;
import
com.alibaba.fastjson.JSON
;
...
...
@@ -52,6 +48,15 @@ public class StrategyRepository implements IStrategyRepository {
@Autowired
private
IStrategyRuleDao
strategyRuleDao
;
@Autowired
private
IRuleTreeNodeDao
ruleTreeNodeDao
;
@Autowired
private
IRuleTreeDao
ruleTreeDao
;
@Autowired
private
IRuleTreeNodeLineDao
ruleTreeNodeLineDao
;
@Override
public
List
<
StrategyAwardEntity
>
queryStrategyAwardList
(
Long
strategy
)
{
...
...
@@ -182,4 +187,58 @@ public class StrategyRepository implements IStrategyRepository {
return
StrategyAwardRuleModelVO
.
builder
().
ruleModels
(
ruleModels
).
build
();
}
@Override
public
RuleTreeVO
queryRuleTreeVOByTreeId
(
String
treeId
)
{
// 优先从缓存获取
String
cacheKey
=
Constants
.
RedisKey
.
RULE_TREE_VO_KEY
+
treeId
;
RuleTreeVO
ruleTreeVOCache
=
redisService
.
getValue
(
cacheKey
);
if
(
null
!=
ruleTreeVOCache
)
return
ruleTreeVOCache
;
// 从数据库中获取
RuleTree
ruleTree
=
ruleTreeDao
.
queryRuleTreeByTreeId
(
treeId
);
List
<
RuleTreeNode
>
ruleTreeNodes
=
ruleTreeNodeDao
.
queryRuleTreeNodeListByTreeId
(
treeId
);
List
<
RuleTreeNodeLine
>
ruleTreeNodeLines
=
ruleTreeNodeLineDao
.
queryRuleTreeNodeLineListByTreeId
(
treeId
);
// 1. 转Map结构
Map
<
String
,
List
<
RuleTreeNodeLineVO
>>
ruleTreeNodeLineMap
=
new
HashMap
<>();
for
(
RuleTreeNodeLine
ruleTreeNodeLine
:
ruleTreeNodeLines
)
{
RuleTreeNodeLineVO
ruleTreeNodeLineVO
=
RuleTreeNodeLineVO
.
builder
()
.
treeId
(
ruleTreeNodeLine
.
getTreeId
())
.
ruleNodeFrom
(
ruleTreeNodeLine
.
getRuleNodeFrom
())
.
ruleNodeTo
(
ruleTreeNodeLine
.
getRuleNodeTo
())
.
ruleLimitType
(
RuleLimitTypeVO
.
valueOf
(
ruleTreeNodeLine
.
getRuleLimitType
()))
.
ruleLimitValue
(
RuleLogicCheckTypeVO
.
valueOf
(
ruleTreeNodeLine
.
getRuleLimitValue
()))
.
build
();
List
<
RuleTreeNodeLineVO
>
ruleTreeNodeLineVOList
=
ruleTreeNodeLineMap
.
computeIfAbsent
(
ruleTreeNodeLine
.
getRuleNodeFrom
(),
k
->
new
ArrayList
<>());
ruleTreeNodeLineVOList
.
add
(
ruleTreeNodeLineVO
);
}
// 2. 转map结构
Map
<
String
,
RuleTreeNodeVO
>
treeNodeMap
=
new
HashMap
<>();
for
(
RuleTreeNode
ruleTreeNode
:
ruleTreeNodes
)
{
RuleTreeNodeVO
ruleTreeNodeVO
=
RuleTreeNodeVO
.
builder
()
.
treeId
(
ruleTreeNode
.
getTreeId
())
.
ruleKey
(
ruleTreeNode
.
getRuleKey
())
.
ruleDesc
(
ruleTreeNode
.
getRuleDesc
())
.
ruleValue
(
ruleTreeNode
.
getRuleValue
())
.
treeNodeLineVOList
(
ruleTreeNodeLineMap
.
get
(
ruleTreeNode
.
getRuleKey
()))
.
build
();
treeNodeMap
.
put
(
ruleTreeNode
.
getRuleKey
(),
ruleTreeNodeVO
);
}
// 3. 构建 Rule Tree
RuleTreeVO
ruleTreeVODB
=
RuleTreeVO
.
builder
()
.
treeId
(
ruleTree
.
getTreeId
())
.
treeName
(
ruleTree
.
getTreeName
())
.
treeDesc
(
ruleTree
.
getTreeDesc
())
.
treeRootRuleNode
(
ruleTree
.
getTreeRootRuleKey
())
.
treeNodeMap
(
treeNodeMap
)
.
build
();
redisService
.
setValue
(
cacheKey
,
ruleTreeVODB
);
return
ruleTreeVODB
;
}
}
xfg-frame-archetype-lite-types/src/main/java/cn/bugstack/types/common/Constants.java
浏览文件 @
b4c652e7
...
...
@@ -11,6 +11,7 @@ public class Constants {
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_"
;
public
static
String
RULE_TREE_VO_KEY
=
"rule_tree_vo_key_"
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录