From 7ac02f1371a6fabeebc02e93e1bd912dd9e6b5df Mon Sep 17 00:00:00 2001 From: hudingrong <1649576115@qq.com> Date: Tue, 23 Apr 2024 14:10:30 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AD=96=E7=95=A5=E6=A0=91+=E7=BB=84=E5=90=88?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bugstack/test/domain/LogicTreeTest.java | 104 ++++++++++++++++++ .../model/valobj/RuleLimitTypeVO.java | 26 +++++ .../model/valobj/RuleTreeNodeLineVO.java | 30 +++++ .../strategy/model/valobj/RuleTreeNodeVO.java | 34 ++++++ .../strategy/model/valobj/RuleTreeVO.java | 33 ++++++ .../service/raffle/DefaultRaffleStrategy.java | 2 +- .../rule/{ => filter}/ILogicFilter.java | 2 +- .../filter/factory/DefaultLogicFactory.java | 2 +- .../filter/impl/RuleBackListLogicFilter.java | 2 +- .../rule/filter/impl/RuleLockLogicFilter.java | 2 +- .../filter/impl/RuleWeightLogicFilter.java | 2 +- .../service/rule/tree/ILogicTreeNode.java | 15 +++ .../rule/tree/factory/DefaultTreeFactory.java | 65 +++++++++++ .../factory/engine/IDecisionTreeEngine.java | 14 +++ .../engine/impl/DecisionTreeEngine.java | 86 +++++++++++++++ .../rule/tree/impl/RuleLockLogicTreeNode.java | 24 ++++ .../tree/impl/RuleLuckAwardLogicTreeNode.java | 29 +++++ .../tree/impl/RuleStockLogicTreeNode.java | 26 +++++ 18 files changed, 492 insertions(+), 6 deletions(-) create mode 100644 xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/LogicTreeTest.java create mode 100644 xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleLimitTypeVO.java create mode 100644 xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeNodeLineVO.java create mode 100644 xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeNodeVO.java create mode 100644 xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeVO.java rename xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/{ => filter}/ILogicFilter.java (88%) create mode 100644 xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/ILogicTreeNode.java create mode 100644 xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/DefaultTreeFactory.java create mode 100644 xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/engine/IDecisionTreeEngine.java create mode 100644 xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/engine/impl/DecisionTreeEngine.java create mode 100644 xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleLockLogicTreeNode.java create mode 100644 xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleLuckAwardLogicTreeNode.java create mode 100644 xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleStockLogicTreeNode.java diff --git a/xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/LogicTreeTest.java b/xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/LogicTreeTest.java new file mode 100644 index 0000000..a01e048 --- /dev/null +++ b/xfg-frame-archetype-lite-app/src/test/java/cn/bugstack/test/domain/LogicTreeTest.java @@ -0,0 +1,104 @@ +package cn.bugstack.test.domain; + +import cn.bugstack.domain.strategy.model.valobj.*; +import cn.bugstack.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine; +import cn.bugstack.domain.strategy.service.rule.tree.factory.DefaultTreeFactory; +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; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * @author Fuzhengwei bugstack.cn @小傅哥 + * @description 规则树测试 + * @create 2024-01-27 13:23 + */ +@Slf4j +@RunWith(SpringRunner.class) +@SpringBootTest +public class LogicTreeTest { + + @Resource + private DefaultTreeFactory defaultTreeFactory; + + /** + * rule_lock --左--> rule_luck_award + * --右--> rule_stock --右--> rule_luck_award + */ + @Test + public void test_tree_rule() { + // 构建参数 + RuleTreeNodeVO rule_lock = RuleTreeNodeVO.builder() + .treeId(100000001) + .ruleKey("rule_lock") + .ruleDesc("限定用户已完成N次抽奖后解锁") + .ruleValue("1") + .treeNodeLineVOList(new ArrayList() {{ + add(RuleTreeNodeLineVO.builder() + .treeId(100000001) + .ruleNodeFrom("rule_lock") + .ruleNodeTo("rule_luck_award") + .ruleLimitType(RuleLimitTypeVO.EQUAL) + .ruleLimitValue(RuleLogicCheckTypeVO.TAKE_OVER) + .build()); + + add(RuleTreeNodeLineVO.builder() + .treeId(100000001) + .ruleNodeFrom("rule_lock") + .ruleNodeTo("rule_stock") + .ruleLimitType(RuleLimitTypeVO.EQUAL) + .ruleLimitValue(RuleLogicCheckTypeVO.ALLOW) + .build()); + }}) + .build(); + + RuleTreeNodeVO rule_luck_award = RuleTreeNodeVO.builder() + .treeId(100000001) + .ruleKey("rule_luck_award") + .ruleDesc("限定用户已完成N次抽奖后解锁") + .ruleValue("1") + .treeNodeLineVOList(null) + .build(); + + RuleTreeNodeVO rule_stock = RuleTreeNodeVO.builder() + .treeId(100000001) + .ruleKey("rule_stock") + .ruleDesc("库存处理规则") + .ruleValue(null) + .treeNodeLineVOList(new ArrayList() {{ + add(RuleTreeNodeLineVO.builder() + .treeId(100000001) + .ruleNodeFrom("rule_lock") + .ruleNodeTo("rule_luck_award") + .ruleLimitType(RuleLimitTypeVO.EQUAL) + .ruleLimitValue(RuleLogicCheckTypeVO.TAKE_OVER) + .build()); + }}) + .build(); + + RuleTreeVO ruleTreeVO = new RuleTreeVO(); + ruleTreeVO.setTreeId(100000001); + ruleTreeVO.setTreeName("决策树规则;增加dall-e-3画图模型"); + ruleTreeVO.setTreeDesc("决策树规则;增加dall-e-3画图模型"); + ruleTreeVO.setTreeRootRuleNode("rule_lock"); + + ruleTreeVO.setTreeNodeMap(new HashMap() {{ + put("rule_lock", rule_lock); + put("rule_stock", rule_stock); + put("rule_luck_award", rule_luck_award); + }}); + + IDecisionTreeEngine treeEngine = defaultTreeFactory.openLogicTree(ruleTreeVO); + + DefaultTreeFactory.StrategyAwardData data = treeEngine.process("xiaofuge", 100001L, 100); + log.info("测试结果:{}", JSON.toJSONString(data)); + + } + +} diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleLimitTypeVO.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleLimitTypeVO.java new file mode 100644 index 0000000..7ba321e --- /dev/null +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleLimitTypeVO.java @@ -0,0 +1,26 @@ +package cn.bugstack.domain.strategy.model.valobj; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @description: 枚举类 + * @author: hdr + * @PACKAGE_NAME: cn.bugstack.domain.strategy.model.valobj + * @DATE: 2024/4/23 + */ +@Getter +@AllArgsConstructor +public enum RuleLimitTypeVO { + + EQUAL(1, "等于"), + GT(2,"大于"), + LT(3,"小于"), + GE(4,"大于&等于"), + LE(5,"小于&等于"), + ENUM(6,"枚举") + ; + + private final Integer code; + private final String info; +} diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeNodeLineVO.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeNodeLineVO.java new file mode 100644 index 0000000..8d0d695 --- /dev/null +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeNodeLineVO.java @@ -0,0 +1,30 @@ +package cn.bugstack.domain.strategy.model.valobj; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @description: 规则树节点指向线对象。 + * @author: hdr + * @PACKAGE_NAME: cn.bugstack.domain.strategy.model.valobj + * @DATE: 2024/4/23 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class RuleTreeNodeLineVO { + + /** 规则树ID */ + private Integer treeId; + /** 规则Key节点 From */ + private String ruleNodeFrom; + /** 规则Key节点 To */ + private String ruleNodeTo; + /** 限定类型;1:=;2:>;3:<;4:>=;5<=;6:enum[枚举范围] */ + private RuleLimitTypeVO ruleLimitType; + /** 限定值(到下个节点) */ + private RuleLogicCheckTypeVO ruleLimitValue; +} diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeNodeVO.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeNodeVO.java new file mode 100644 index 0000000..4bb259b --- /dev/null +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeNodeVO.java @@ -0,0 +1,34 @@ +package cn.bugstack.domain.strategy.model.valobj; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @description: 规则树节点对象 + * @author: hdr + * @PACKAGE_NAME: cn.bugstack.domain.strategy.model.valobj + * @DATE: 2024/4/23 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class RuleTreeNodeVO { + + /** 规则树ID */ + private Integer treeId; + /** 规则Key */ + private String ruleKey; + /** 规则描述 */ + private String ruleDesc; + /** 规则比值 */ + private String ruleValue; + + /** 规则连线 */ + private List treeNodeLineVOList; + +} diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeVO.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeVO.java new file mode 100644 index 0000000..61a2312 --- /dev/null +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/model/valobj/RuleTreeVO.java @@ -0,0 +1,33 @@ +package cn.bugstack.domain.strategy.model.valobj; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Map; + +/** + * @description: 规则树对象 【注意;不具有唯一ID,不需要改变数据库结果的对象,可以被定义为值对象】 + * @author: hdr + * @PACKAGE_NAME: cn.bugstack.domain.strategy.model.valobj + * @DATE: 2024/4/23 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class RuleTreeVO { + /** 规则树ID */ + private Integer treeId; + /** 规则树名称 */ + private String treeName; + /** 规则树描述 */ + private String treeDesc; + /** 规则根节点 */ + private String treeRootRuleNode; + + /** 规则节点 */ + private Map treeNodeMap; + +} diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/DefaultRaffleStrategy.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/DefaultRaffleStrategy.java index ce9b4d4..7f7fd19 100644 --- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/DefaultRaffleStrategy.java +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/raffle/DefaultRaffleStrategy.java @@ -6,7 +6,7 @@ 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.filter.ILogicFilter; import cn.bugstack.domain.strategy.service.rule.chain.factory.DefaultChainFactory; import cn.bugstack.domain.strategy.service.rule.filter.factory.DefaultLogicFactory; import com.alibaba.fastjson.JSON; diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/ILogicFilter.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/ILogicFilter.java similarity index 88% rename from xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/ILogicFilter.java rename to xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/ILogicFilter.java index f7dc29c..715ddae 100644 --- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/ILogicFilter.java +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/ILogicFilter.java @@ -1,4 +1,4 @@ -package cn.bugstack.domain.strategy.service.rule; +package cn.bugstack.domain.strategy.service.rule.filter; import cn.bugstack.domain.strategy.model.entity.RuleActionEntity; import cn.bugstack.domain.strategy.model.entity.RuleMatterEntity; diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/factory/DefaultLogicFactory.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/factory/DefaultLogicFactory.java index 4cc891d..9e537fb 100644 --- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/factory/DefaultLogicFactory.java +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/factory/DefaultLogicFactory.java @@ -2,7 +2,7 @@ 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.ILogicFilter; +import cn.bugstack.domain.strategy.service.rule.filter.ILogicFilter; import lombok.AllArgsConstructor; import lombok.Getter; import org.springframework.core.annotation.AnnotationUtils; diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleBackListLogicFilter.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleBackListLogicFilter.java index 4d1c728..44cfb77 100644 --- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleBackListLogicFilter.java +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleBackListLogicFilter.java @@ -5,7 +5,7 @@ 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.filter.ILogicFilter; import cn.bugstack.domain.strategy.service.rule.filter.factory.DefaultLogicFactory; import cn.bugstack.types.common.Constants; import lombok.extern.slf4j.Slf4j; diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleLockLogicFilter.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleLockLogicFilter.java index 2aa5a0a..58014f1 100644 --- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleLockLogicFilter.java +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleLockLogicFilter.java @@ -5,7 +5,7 @@ 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.filter.ILogicFilter; import cn.bugstack.domain.strategy.service.rule.filter.factory.DefaultLogicFactory; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleWeightLogicFilter.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleWeightLogicFilter.java index 471e807..25e36db 100644 --- a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleWeightLogicFilter.java +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/filter/impl/RuleWeightLogicFilter.java @@ -5,7 +5,7 @@ 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.filter.ILogicFilter; import cn.bugstack.domain.strategy.service.rule.filter.factory.DefaultLogicFactory; import cn.bugstack.types.common.Constants; import lombok.extern.slf4j.Slf4j; diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/ILogicTreeNode.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/ILogicTreeNode.java new file mode 100644 index 0000000..4708c33 --- /dev/null +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/ILogicTreeNode.java @@ -0,0 +1,15 @@ +package cn.bugstack.domain.strategy.service.rule.tree; + +import cn.bugstack.domain.strategy.service.rule.tree.factory.DefaultTreeFactory; + +/** + * @description: 规则树接口 + * @author: hdr + * @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule.tree + * @DATE: 2024/4/19 + */ +public interface ILogicTreeNode { + + DefaultTreeFactory.TreeActionEntity logic(String userId, Long strategyId, Integer awardId); + +} diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/DefaultTreeFactory.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/DefaultTreeFactory.java new file mode 100644 index 0000000..5075462 --- /dev/null +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/DefaultTreeFactory.java @@ -0,0 +1,65 @@ +package cn.bugstack.domain.strategy.service.rule.tree.factory; + +import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO; +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 org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * @description: 库存节点 + * @author: hdr + * @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule.tree.factory + * @DATE: 2024/4/22 + */ +@Service +public class DefaultTreeFactory { + private final Map logicTreeNodeGroup; + + public DefaultTreeFactory(Map logicTreeNodeGroup) { + this.logicTreeNodeGroup = logicTreeNodeGroup; + } + + public IDecisionTreeEngine openLogicTree(RuleTreeVO ruleTreeVO) { + return new DecisionTreeEngine(logicTreeNodeGroup, ruleTreeVO); + } + + /** + * 决策树动作实现 + */ + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class TreeActionEntity { + private RuleLogicCheckTypeVO ruleLogicCheckType; + private StrategyAwardData strategyAwardData; + } + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class StrategyAwardData { + + /** + * 抽奖奖品ID - 内部流转 + */ + private Integer awardId; + + /** + * 抽奖奖品规则 + */ + private String awardRuleValue; + } + + +} diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/engine/IDecisionTreeEngine.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/engine/IDecisionTreeEngine.java new file mode 100644 index 0000000..a524ccb --- /dev/null +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/engine/IDecisionTreeEngine.java @@ -0,0 +1,14 @@ +package cn.bugstack.domain.strategy.service.rule.tree.factory.engine; + +import cn.bugstack.domain.strategy.service.rule.tree.factory.DefaultTreeFactory; + +/** + * @description: + * @author: hdr + * @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule.tree.factory.engine + * @DATE: 2024/4/22 + */ +public interface IDecisionTreeEngine { + + DefaultTreeFactory.StrategyAwardData process(String userId, Long strategyId, Integer awardId); +} diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/engine/impl/DecisionTreeEngine.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/engine/impl/DecisionTreeEngine.java new file mode 100644 index 0000000..e4a2b4c --- /dev/null +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/factory/engine/impl/DecisionTreeEngine.java @@ -0,0 +1,86 @@ +package cn.bugstack.domain.strategy.service.rule.tree.factory.engine.impl; + +import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO; +import cn.bugstack.domain.strategy.model.valobj.RuleTreeNodeLineVO; +import cn.bugstack.domain.strategy.model.valobj.RuleTreeNodeVO; +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.DefaultTreeFactory; +import cn.bugstack.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; +import java.util.Map; + +/** + * @description: + * @author: hdr + * @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule.tree.factory.engine.impl + * @DATE: 2024/4/23 + */ +@Slf4j +public class DecisionTreeEngine implements IDecisionTreeEngine { + + private final Map logicTreeNodeGroup; + + private final RuleTreeVO ruleTreeVO; + + public DecisionTreeEngine(Map logicTreeNodeGroup, RuleTreeVO ruleTreeVO) { + this.logicTreeNodeGroup = logicTreeNodeGroup; + this.ruleTreeVO = ruleTreeVO; + } + + @Override + public DefaultTreeFactory.StrategyAwardData process(String userId, Long strategyId, Integer awardId) { + + DefaultTreeFactory.StrategyAwardData strategyAwardData = null; + + // 获取基础信息 + String nextNode = ruleTreeVO.getTreeRootRuleNode(); + Map treeNodeVOMap = ruleTreeVO.getTreeNodeMap(); + + // 获取其实节点 【根节点记录了第一个要执行的规则】 + RuleTreeNodeVO ruleTreeNode = treeNodeVOMap.get(nextNode); + while (null != nextNode) { + ILogicTreeNode logicTreeNode = logicTreeNodeGroup.get(ruleTreeNode.getRuleKey()); + + DefaultTreeFactory.TreeActionEntity logicEntity = logicTreeNode.logic(userId, strategyId, awardId); + RuleLogicCheckTypeVO ruleLogicCheckTypeVO = logicEntity.getRuleLogicCheckType(); + strategyAwardData = logicEntity.getStrategyAwardData(); + log.info("决策树引擎【{}】treeId:{} node:{} code:{}", ruleTreeVO.getTreeName(), ruleTreeVO.getTreeId(), nextNode, ruleLogicCheckTypeVO.getCode()); + + // 获取下个节点 + nextNode = nextNode(ruleLogicCheckTypeVO.getCode(), ruleTreeNode.getTreeNodeLineVOList()); + ruleTreeNode = treeNodeVOMap.get(nextNode); + } + + // 返回结果 + return strategyAwardData; + + } + + public String nextNode(String matterValue, List treeNodeLineVOList) { + if (null == treeNodeLineVOList || treeNodeLineVOList.isEmpty()) return null; + for (RuleTreeNodeLineVO nodeLine : treeNodeLineVOList) { + if (decisionLogic(matterValue, nodeLine)) { + return nodeLine.getRuleNodeTo(); + } + } + throw new RuntimeException("决策树引擎,nextNode 计算失败,未找到可执行节点!"); + } + + private boolean decisionLogic(String matterValue, RuleTreeNodeLineVO nodeLine) { + + switch (nodeLine.getRuleLimitType()) { + case EQUAL: + return matterValue.equals(nodeLine.getRuleLimitValue().getCode()); + // 以下规则暂时不需要实现 + case GT: + case LT: + case GE: + case LE: + default: + return false; + } + } +} diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleLockLogicTreeNode.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleLockLogicTreeNode.java new file mode 100644 index 0000000..4ffb043 --- /dev/null +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleLockLogicTreeNode.java @@ -0,0 +1,24 @@ +package cn.bugstack.domain.strategy.service.rule.tree.impl; + +import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO; +import cn.bugstack.domain.strategy.service.rule.tree.ILogicTreeNode; +import cn.bugstack.domain.strategy.service.rule.tree.factory.DefaultTreeFactory; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @description: + * @author: hdr + * @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule.tree.impl + * @DATE: 2024/4/22 + */ +@Slf4j +@Component("rule_lock") +public class RuleLockLogicTreeNode implements ILogicTreeNode { + @Override + public DefaultTreeFactory.TreeActionEntity logic(String userId, Long strategyId, Integer awardId) { + return DefaultTreeFactory.TreeActionEntity.builder() + .ruleLogicCheckType(RuleLogicCheckTypeVO.ALLOW) + .build(); + } +} diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleLuckAwardLogicTreeNode.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleLuckAwardLogicTreeNode.java new file mode 100644 index 0000000..1953c9c --- /dev/null +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleLuckAwardLogicTreeNode.java @@ -0,0 +1,29 @@ +package cn.bugstack.domain.strategy.service.rule.tree.impl; + +import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO; +import cn.bugstack.domain.strategy.service.rule.tree.ILogicTreeNode; +import cn.bugstack.domain.strategy.service.rule.tree.factory.DefaultTreeFactory; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @description: 兜底奖励节点 + * @author: hdr + * @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule.tree.impl + * @DATE: 2024/4/23 + */ +@Slf4j +@Component("rule_luck_award") +public class RuleLuckAwardLogicTreeNode implements ILogicTreeNode { + @Override + public DefaultTreeFactory.TreeActionEntity logic(String userId, Long strategyId, Integer awardId) { + + return DefaultTreeFactory.TreeActionEntity.builder() + .ruleLogicCheckType(RuleLogicCheckTypeVO.TAKE_OVER) + .strategyAwardData(DefaultTreeFactory.StrategyAwardData.builder() + .awardId(101) + .awardRuleValue("1,100") + .build()) + .build(); + } +} diff --git a/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleStockLogicTreeNode.java b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleStockLogicTreeNode.java new file mode 100644 index 0000000..226ccf2 --- /dev/null +++ b/xfg-frame-archetype-lite-domain/src/main/java/cn/bugstack/domain/strategy/service/rule/tree/impl/RuleStockLogicTreeNode.java @@ -0,0 +1,26 @@ +package cn.bugstack.domain.strategy.service.rule.tree.impl; + +import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO; +import cn.bugstack.domain.strategy.service.rule.tree.ILogicTreeNode; +import cn.bugstack.domain.strategy.service.rule.tree.factory.DefaultTreeFactory; +import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.units.qual.C; +import org.springframework.stereotype.Component; + +/** + * @description: 库存扣减节点 + * @author: hdr + * @PACKAGE_NAME: cn.bugstack.domain.strategy.service.rule.tree.impl + * @DATE: 2024/4/23 + */ +@Slf4j +@Component("rule_stock") +public class RuleStockLogicTreeNode implements ILogicTreeNode { + @Override + public DefaultTreeFactory.TreeActionEntity logic(String userId, Long strategyId, Integer awardId) { + + return DefaultTreeFactory.TreeActionEntity.builder() + .ruleLogicCheckType(RuleLogicCheckTypeVO.TAKE_OVER) + .build(); + } +} -- GitLab