├── doc ├── 表.jpg ├── 关键字 ├── 资料 └── sql │ └── DDL.sql ├── README.md ├── brms-api ├── src │ └── main │ │ └── java │ │ └── com │ │ └── weweibuy │ │ └── brms │ │ └── api │ │ ├── model │ │ ├── eum │ │ │ ├── ModelTypeEum.java │ │ │ ├── RuleEnterTypeEum.java │ │ │ ├── ModelAttrTypeEum.java │ │ │ ├── MultipleRuleSetExecModelStrategyEum.java │ │ │ ├── ModelAttrValueSourceEum.java │ │ │ ├── RuleActionValueTypeEum.java │ │ │ ├── ConditionLogicalOperatorEum.java │ │ │ └── OperatorEum.java │ │ ├── dto │ │ │ ├── resp │ │ │ │ ├── RuleTranslateRespDTO.java │ │ │ │ ├── ModelRespDTO.java │ │ │ │ ├── RuleSetRespDTO.java │ │ │ │ ├── RuleSetModelRespDTO.java │ │ │ │ ├── RuleHitLogRespDTO.java │ │ │ │ ├── RuleModelAttrRespDTO.java │ │ │ │ ├── RuleConditionRespDTO.java │ │ │ │ ├── RuleActionRespDTO.java │ │ │ │ └── RuleRespDTO.java │ │ │ ├── RuleExecRespDTO.java │ │ │ ├── RuleExecProcessRespDTO.java │ │ │ ├── req │ │ │ │ └── RuleHitLogReqDTO.java │ │ │ └── RuleExecReqDTO.java │ │ ├── message │ │ │ ├── RuleExecResultMessage.java │ │ │ └── RuleExecMessage.java │ │ └── constant │ │ │ └── RuleBuildConstant.java │ │ ├── RuleExecProvider.java │ │ ├── RuleExecApi.java │ │ └── RuleQueryApi.java └── pom.xml ├── brms-service ├── src │ ├── main │ │ ├── resources │ │ │ ├── generator │ │ │ │ ├── mybatis-generator-comment.ftl │ │ │ │ └── generatorConfig.xml │ │ │ ├── application.yml │ │ │ └── config │ │ │ │ └── mybatis │ │ │ │ └── mapper │ │ │ │ ├── ModelMapper.xml │ │ │ │ └── RuleSetMapper.xml │ │ └── java │ │ │ └── com │ │ │ └── weweibuy │ │ │ └── brms │ │ │ ├── model │ │ │ ├── po │ │ │ │ ├── Model.java │ │ │ │ ├── RuleSet.java │ │ │ │ ├── RuleSetModel.java │ │ │ │ ├── RuleHitLog.java │ │ │ │ ├── ModelAttr.java │ │ │ │ ├── RuleCondition.java │ │ │ │ ├── RuleAction.java │ │ │ │ └── Rule.java │ │ │ ├── event │ │ │ │ └── RuleHitLogEvent.java │ │ │ └── context │ │ │ │ └── RuleProcessContext.java │ │ │ ├── repository │ │ │ ├── RuleAndSetRepository.java │ │ │ ├── RuleSetModelRepository.java │ │ │ ├── RuleHitLogRepository.java │ │ │ ├── ModelAndAttrRepository.java │ │ │ ├── ConditionAndActionRepository.java │ │ │ ├── JdbcRuleSetModelRepositoryImpl.java │ │ │ ├── cache │ │ │ │ ├── CacheRuleAndSetRepositoryImpl.java │ │ │ │ ├── CacheRuleSetModelRepositoryImpl.java │ │ │ │ └── CacheModelAndAttrRepositoryImpl.java │ │ │ ├── JdbcModelAndAttrRepositoryImpl.java │ │ │ └── JdbcRuleAndSetRepositoryImpl.java │ │ │ ├── mq │ │ │ ├── RuleExecResultProvider.java │ │ │ └── RuleExecMessageConsumer.java │ │ │ ├── support │ │ │ ├── ConditionBuildContext.java │ │ │ ├── ConditionBuilder.java │ │ │ ├── RuleProcessContextHolder.java │ │ │ ├── KieBaseHolder.java │ │ │ ├── DrlBuildSupport.java │ │ │ ├── RuleTranslateHelper.java │ │ │ ├── RuleModelHelper.java │ │ │ ├── NotCollectionConditionBuilder.java │ │ │ ├── MultipleConditionBuilder.java │ │ │ ├── ActionBuilder.java │ │ │ └── CollectionConditionBuilder.java │ │ │ ├── BrmsApplication.java │ │ │ ├── controller │ │ │ ├── RuleMangeController.java │ │ │ ├── RuleExecController.java │ │ │ └── RuleQueryController.java │ │ │ ├── cglib │ │ │ └── RuleModelCreator.java │ │ │ ├── mapper │ │ │ ├── RuleMapper.java │ │ │ ├── ModelMapper.java │ │ │ ├── RuleSetMapper.java │ │ │ ├── ModelAttrMapper.java │ │ │ ├── RuleActionMapper.java │ │ │ ├── RuleHitLogMapper.java │ │ │ ├── RuleSetModelMapper.java │ │ │ └── RuleConditionMapper.java │ │ │ ├── config │ │ │ └── CacheConfig.java │ │ │ ├── manager │ │ │ ├── RuleQueryManager.java │ │ │ ├── RuleHitLogLogManager.java │ │ │ └── RuleBuildManager.java │ │ │ ├── utils │ │ │ ├── DroolsCollectionUtils.java │ │ │ └── DroolsCalculateUtils.java │ │ │ ├── service │ │ │ ├── RuleManageService.java │ │ │ ├── RuleExecService.java │ │ │ └── RuleQueryService.java │ │ │ └── drools │ │ │ └── RuleLogEventListener.java │ └── test │ │ └── java │ │ └── com │ │ └── weweibuy │ │ └── brms │ │ └── utils │ │ └── DroolsCalculateUtilsTest.java └── pom.xml ├── .gitignore └── pom.xml /doc/表.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weweibuy/brms/HEAD/doc/表.jpg -------------------------------------------------------------------------------- /doc/关键字: -------------------------------------------------------------------------------- 1 | https://www.jianshu.com/p/ae9a62588da4 2 | 3 | activation-group: 属于同一个activation-group的规则会进行唯一命中 -------------------------------------------------------------------------------- /doc/资料: -------------------------------------------------------------------------------- 1 | 表达式: https://github.com/alibaba/QLExpress 2 | Urule: https://juejin.cn/post/6844903588725178376 3 | http://www.bstek.com/resources/doc/4.0/flow/9.3.package-node.html 4 | Aviator: https://www.jianshu.com/p/02403dd1f4c4 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # brms 2 | 业务规则管理系统,集成Drools,以数据库的形式实现决策表,提供动态规则配置功能 3 | 4 | ##### 注意: 该项目对 [weweibuy-framework](https://github.com/weweibuy/weweibuy-framework)项目有依赖,直接打开会报错,需要先下载: 5 | [weweibuy-framework](https://github.com/weweibuy/weweibuy-framework) 然后 mvn install 6 | 本地启动时设置环境变量: -Dspring.profiles.active=dev 7 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/eum/ModelTypeEum.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.eum; 2 | 3 | /** 4 | * 模型类型 5 | * 6 | * @author durenhao 7 | * @date 2020/11/24 22:15 8 | **/ 9 | public enum ModelTypeEum { 10 | 11 | /** 12 | * 输入模型 13 | */ 14 | INPUT, 15 | 16 | /** 17 | * 输出模型 18 | */ 19 | OUTPUT, 20 | ; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/eum/RuleEnterTypeEum.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.eum; 2 | 3 | /** 4 | * 规则录入方式 5 | * 6 | * @author durenhao 7 | * @date 2020/11/23 21:20 8 | **/ 9 | public enum RuleEnterTypeEum { 10 | 11 | /** 12 | * 编码式录入 13 | */ 14 | CODING, 15 | 16 | /** 17 | * 选择式录入 18 | */ 19 | SELECT,; 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/dto/resp/RuleTranslateRespDTO.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.dto.resp; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 规则翻译响应 9 | * @author durenhao 10 | * @date 2021/7/27 21:22 11 | **/ 12 | @Data 13 | public class RuleTranslateRespDTO { 14 | 15 | private List condition; 16 | 17 | private List action; 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/eum/ModelAttrTypeEum.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.eum; 2 | 3 | /** 4 | * 模型属性类型 5 | * 6 | * @author durenhao 7 | * @date 2020/11/8 11:34 8 | **/ 9 | public enum ModelAttrTypeEum { 10 | 11 | STRING, 12 | NUMBER, 13 | BOOLEAN, 14 | DATE_DAY, 15 | DATE_SECOND, 16 | COLLECTION_NUMBER, 17 | COLLECTION_STRING, 18 | OBJECT 19 | ; 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/message/RuleExecResultMessage.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.message; 2 | 3 | import com.weweibuy.brms.api.model.dto.RuleExecRespDTO; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author durenhao 8 | * @date 2020/12/4 22:26 9 | **/ 10 | @Data 11 | public class RuleExecResultMessage extends RuleExecRespDTO { 12 | 13 | /** 14 | * 请求号 15 | */ 16 | private String reqNo; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /brms-service/src/main/resources/generator/mybatis-generator-comment.ftl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/eum/MultipleRuleSetExecModelStrategyEum.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.eum; 2 | 3 | /** 4 | * 多规则集执行时,模型转化策略 5 | * 6 | * @author durenhao 7 | * @date 2020/11/24 21:38 8 | **/ 9 | public enum MultipleRuleSetExecModelStrategyEum { 10 | 11 | /** 12 | * 使用规则 action的模型作为下一个规则的输入模型 13 | */ 14 | USE_ACTION_MODEL, 15 | 16 | /** 17 | * 总是使用第一的模型 18 | */ 19 | ALWAYS_USE_FIRST, 20 | 21 | 22 | ; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/dto/RuleExecRespDTO.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * 规则执行响应 10 | * 11 | * @author durenhao 12 | * @date 2020/11/27 20:49 13 | **/ 14 | @Data 15 | public class RuleExecRespDTO { 16 | 17 | private Boolean hit; 18 | 19 | private Map model; 20 | 21 | private List process; 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/message/RuleExecMessage.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.message; 2 | 3 | import com.weweibuy.brms.api.model.dto.RuleExecReqDTO; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author durenhao 8 | * @date 2020/12/4 20:41 9 | **/ 10 | @Data 11 | public class RuleExecMessage extends RuleExecReqDTO { 12 | 13 | /** 14 | * 请求号 回执时用 15 | */ 16 | private String reqNo; 17 | 18 | /** 19 | * 回调消息 tag 20 | */ 21 | private String callBackTag; 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | # Created by .ignore support plugin (hsz.mobi) 3 | ### Java template 4 | # Compiled class file 5 | *.class 6 | # Log file 7 | *.log 8 | 9 | # BlueJ files 10 | *.ctxt 11 | 12 | # Mobile Tools for Java (J2ME) 13 | .mtj.tmp/ 14 | .idea 15 | target 16 | applog 17 | # Package Files # 18 | *.jar 19 | *.war 20 | *.nar 21 | *.ear 22 | *.zip 23 | *.tar.gz 24 | *.gz 25 | *.rar 26 | 27 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 28 | hs_err_pid* 29 | *.iml 30 | 31 | rebel.xml 32 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/eum/ModelAttrValueSourceEum.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.eum; 2 | 3 | /** 4 | * 模型属性值来源 5 | * 6 | * @author durenhao 7 | * @date 2020/11/8 11:51 8 | **/ 9 | public enum ModelAttrValueSourceEum { 10 | 11 | /** 12 | * 直接输入 13 | */ 14 | INPUT, 15 | 16 | /** 17 | * 字典 18 | */ 19 | DICT, 20 | /** 21 | * 一级地址 22 | */ 23 | ADDRESS_1, 24 | /** 25 | * 二级地址 26 | */ 27 | ADDRESS_2, 28 | /** 29 | * 三级地址 30 | */ 31 | ADDRESS_3,; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/dto/RuleExecProcessRespDTO.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 规则执行过程响应 9 | * 10 | * @author durenhao 11 | * @date 2020/11/27 20:50 12 | **/ 13 | @Data 14 | public class RuleExecProcessRespDTO { 15 | 16 | private String ruleSet; 17 | 18 | private List rule; 19 | 20 | 21 | @Data 22 | public static class ProcessRuleDTO { 23 | 24 | private String name; 25 | 26 | private Boolean hit; 27 | 28 | private String agendaGroup; 29 | 30 | } 31 | 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/model/po/Model.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.model.po; 2 | 3 | import java.time.LocalDateTime; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class Model { 8 | /** 9 | * id自增1 10 | */ 11 | private Long id; 12 | 13 | /** 14 | * 模型key 15 | */ 16 | private String modelKey; 17 | 18 | /** 19 | * 模型描述 20 | */ 21 | private String modelDesc; 22 | 23 | /** 24 | * 是否删除 25 | */ 26 | private Boolean deleted; 27 | 28 | /** 29 | * 创建时间 30 | */ 31 | private LocalDateTime createTime; 32 | 33 | /** 34 | * 更新时间 35 | */ 36 | private LocalDateTime updateTime; 37 | } -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/model/po/RuleSet.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.model.po; 2 | 3 | import java.time.LocalDateTime; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class RuleSet { 8 | /** 9 | * id自增1 10 | */ 11 | private Long id; 12 | 13 | /** 14 | * 规则集key(package) 15 | */ 16 | private String ruleSetKey; 17 | 18 | /** 19 | * 规则集名称 20 | */ 21 | private String ruleSetName; 22 | 23 | /** 24 | * 是否删除 25 | */ 26 | private Boolean deleted; 27 | 28 | /** 29 | * 创建时间 30 | */ 31 | private LocalDateTime createTime; 32 | 33 | /** 34 | * 更新时间 35 | */ 36 | private LocalDateTime updateTime; 37 | } -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/dto/resp/ModelRespDTO.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.dto.resp; 2 | 3 | import lombok.Data; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | /** 8 | * @author durenhao 9 | * @date 2021/7/29 21:30 10 | **/ 11 | @Data 12 | public class ModelRespDTO { 13 | 14 | /** 15 | * id自增1 16 | */ 17 | private Long id; 18 | 19 | /** 20 | * 模型key 21 | */ 22 | private String modelKey; 23 | 24 | /** 25 | * 模型描述 26 | */ 27 | private String modelDesc; 28 | 29 | /** 30 | * 创建时间 31 | */ 32 | private LocalDateTime createTime; 33 | 34 | /** 35 | * 更新时间 36 | */ 37 | private LocalDateTime updateTime; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/eum/RuleActionValueTypeEum.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.eum; 2 | 3 | import java.util.Arrays; 4 | import java.util.Optional; 5 | 6 | /** 7 | * 规则 action 值类型 8 | * 9 | * @author durenhao 10 | * @date 2020/11/30 22:27 11 | **/ 12 | public enum RuleActionValueTypeEum { 13 | 14 | /** 15 | * 输入型 16 | */ 17 | INPUT, 18 | 19 | /** 20 | * 计算型 21 | */ 22 | CALCULATE, 23 | ; 24 | 25 | public static Optional fromValue(String value) { 26 | return Arrays.stream(RuleActionValueTypeEum.values()) 27 | .filter(a -> a.toString().equals(value)) 28 | .findFirst(); 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/RuleExecProvider.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api; 2 | 3 | import com.weweibuy.brms.api.model.dto.RuleExecReqDTO; 4 | import com.weweibuy.framework.rocketmq.annotation.RocketProducer; 5 | import com.weweibuy.framework.rocketmq.annotation.RocketProducerHandler; 6 | import org.apache.rocketmq.client.producer.SendResult; 7 | 8 | /** 9 | * @author durenhao 10 | * @date 2019/12/29 10:26 11 | **/ 12 | @RocketProducer(topic = "${rocket-mq.producer.rule.topic}") 13 | public interface RuleExecProvider { 14 | 15 | /** 16 | * TAG支持EL表达式的形式, 如何方法参数中有@Tag标记的值, 将覆盖注解中的值 17 | * 18 | * @return 19 | */ 20 | @RocketProducerHandler 21 | SendResult send(RuleExecReqDTO user); 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/RuleExecApi.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api; 2 | 3 | import com.weweibuy.brms.api.model.dto.RuleExecReqDTO; 4 | import com.weweibuy.brms.api.model.dto.RuleExecRespDTO; 5 | import com.weweibuy.framework.common.core.model.dto.CommonDataResponse; 6 | import org.springframework.web.bind.annotation.PostMapping; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | 9 | /** 10 | * @author durenhao 11 | * @date 2020/12/3 22:16 12 | **/ 13 | public interface RuleExecApi { 14 | 15 | /** 16 | * 执行规则 17 | * 18 | * @param reqDTO 19 | * @return 20 | */ 21 | @PostMapping("/rule/exec") 22 | CommonDataResponse execRule(RuleExecReqDTO reqDTO); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/dto/resp/RuleSetRespDTO.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.dto.resp; 2 | 3 | import lombok.Data; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | /** 8 | * @author durenhao 9 | * @date 2021/7/23 21:43 10 | **/ 11 | @Data 12 | public class RuleSetRespDTO { 13 | 14 | /** 15 | * id自增1 16 | */ 17 | private Long id; 18 | 19 | /** 20 | * 规则集key(package) 21 | */ 22 | private String ruleSetKey; 23 | 24 | /** 25 | * 规则集名称 26 | */ 27 | private String ruleSetName; 28 | 29 | /** 30 | * 创建时间 31 | */ 32 | private LocalDateTime createTime; 33 | 34 | /** 35 | * 更新时间 36 | */ 37 | private LocalDateTime updateTime; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/repository/RuleAndSetRepository.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.repository; 2 | 3 | import com.weweibuy.brms.model.po.Rule; 4 | import com.weweibuy.brms.model.po.RuleSet; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | /** 10 | * 规则集 与规则仓库 11 | * 12 | * @author durenhao 13 | * @date 2020/11/25 21:38 14 | **/ 15 | public interface RuleAndSetRepository { 16 | 17 | /** 18 | * 查询规则集 19 | * 20 | * @param ruleSetKey 21 | * @return 22 | */ 23 | Optional selectRuleSet(String ruleSetKey); 24 | 25 | /** 26 | * 查询规则 27 | * 28 | * @param ruleSetKey 29 | * @return 30 | */ 31 | List selectRule(String ruleSetKey); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/model/po/RuleSetModel.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.model.po; 2 | 3 | import java.time.LocalDateTime; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class RuleSetModel { 8 | /** 9 | * id自增1 10 | */ 11 | private Long id; 12 | 13 | /** 14 | * 模型key 15 | */ 16 | private String modelKey; 17 | 18 | /** 19 | * 规则集key(package) 20 | */ 21 | private String ruleSetKey; 22 | 23 | /** 24 | * 模型类型(INPUT:输入; OUTPUT:输出) 25 | */ 26 | private String modelType; 27 | 28 | /** 29 | * 是否删除 30 | */ 31 | private Boolean deleted; 32 | 33 | /** 34 | * 创建时间 35 | */ 36 | private LocalDateTime createTime; 37 | 38 | /** 39 | * 更新时间 40 | */ 41 | private LocalDateTime updateTime; 42 | } -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/repository/RuleSetModelRepository.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.repository; 2 | 3 | import com.weweibuy.brms.api.model.eum.ModelTypeEum; 4 | import com.weweibuy.brms.model.po.RuleSetModel; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | /** 10 | * 规则集模型 11 | * 12 | * @author durenhao 13 | * @date 2020/11/25 20:40 14 | **/ 15 | public interface RuleSetModelRepository { 16 | 17 | /** 18 | * 查询模型 19 | * 20 | * @param ruleSetKey 21 | * @return 22 | */ 23 | List selectRuleSetModel(String ruleSetKey); 24 | 25 | /** 26 | * 查询模型 27 | * 28 | * @param ruleSetKey 29 | * @param modelType 30 | * @return 31 | */ 32 | Optional selectRuleSetModel(String ruleSetKey, ModelTypeEum modelType); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/dto/resp/RuleSetModelRespDTO.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.dto.resp; 2 | 3 | import lombok.Data; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | /** 8 | * @author durenhao 9 | * @date 2021/7/25 16:06 10 | **/ 11 | @Data 12 | public class RuleSetModelRespDTO { 13 | 14 | /** 15 | * id自增1 16 | */ 17 | private Long id; 18 | 19 | /** 20 | * 模型key 21 | */ 22 | private String modelKey; 23 | 24 | /** 25 | * 规则集key(package) 26 | */ 27 | private String ruleSetKey; 28 | 29 | /** 30 | * 模型类型(INPUT:输入; OUTPUT:输出) 31 | */ 32 | private String modelType; 33 | 34 | /** 35 | * 创建时间 36 | */ 37 | private LocalDateTime createTime; 38 | 39 | /** 40 | * 更新时间 41 | */ 42 | private LocalDateTime updateTime; 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/mq/RuleExecResultProvider.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.mq; 2 | 3 | import com.weweibuy.brms.api.model.message.RuleExecResultMessage; 4 | import com.weweibuy.framework.rocketmq.annotation.RocketProducer; 5 | import com.weweibuy.framework.rocketmq.annotation.RocketProducerHandler; 6 | import com.weweibuy.framework.rocketmq.annotation.Tag; 7 | import org.apache.rocketmq.client.producer.SendResult; 8 | 9 | /** 10 | * @author durenhao 11 | * @date 2019/12/29 10:26 12 | **/ 13 | @RocketProducer(topic = "${rocket-mq.producer.rule-result.topic}") 14 | public interface RuleExecResultProvider { 15 | 16 | /** 17 | * TAG支持EL表达式的形式, 如何方法参数中有@Tag标记的值, 将覆盖注解中的值 18 | * 19 | * @return 20 | */ 21 | @RocketProducerHandler 22 | SendResult send(RuleExecResultMessage resultMessage, @Tag String tag); 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/support/ConditionBuildContext.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.support; 2 | 3 | import com.weweibuy.brms.model.po.ModelAttr; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * 条件构建上下文 13 | * 14 | * @author durenhao 15 | * @date 2020/11/29 13:35 16 | **/ 17 | @Builder 18 | @Data 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | public class ConditionBuildContext { 22 | 23 | private Integer maxIndex; 24 | 25 | private Integer conditionIndex; 26 | 27 | private List paramList; 28 | 29 | private String[] oriConditionAttrArr; 30 | 31 | private String oriConditionAttrName; 32 | 33 | private ModelAttr modelAttr; 34 | 35 | private Boolean nesting; 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/dto/req/RuleHitLogReqDTO.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.dto.req; 2 | 3 | import com.weweibuy.framework.common.core.model.dto.CommonPageRequest; 4 | import lombok.Data; 5 | 6 | import java.time.LocalDateTime; 7 | 8 | /** 9 | * @author durenhao 10 | * @date 2021/7/25 16:40 11 | **/ 12 | @Data 13 | public class RuleHitLogReqDTO extends CommonPageRequest { 14 | 15 | /** 16 | * 流水号 17 | */ 18 | private String requestNo; 19 | 20 | /** 21 | * 规则集key(package) 22 | */ 23 | private String ruleSetKey; 24 | 25 | /** 26 | * 议程组 27 | */ 28 | private String agendaGroup; 29 | 30 | /** 31 | * 规则key 32 | */ 33 | private String ruleKey; 34 | 35 | private LocalDateTime createTimeFrom; 36 | 37 | private LocalDateTime createTimeTo; 38 | 39 | 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/eum/ConditionLogicalOperatorEum.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.eum; 2 | 3 | import lombok.Getter; 4 | import lombok.RequiredArgsConstructor; 5 | 6 | import java.util.Arrays; 7 | import java.util.Optional; 8 | 9 | /** 10 | * 条件逻辑操作符 11 | * 12 | * @author durenhao 13 | * @date 2021/8/8 9:35 14 | **/ 15 | @Getter 16 | @RequiredArgsConstructor 17 | public enum ConditionLogicalOperatorEum { 18 | 19 | 20 | AND("&&", "并且"), 21 | 22 | OR("||", "或者"), 23 | ; 24 | 25 | 26 | private final String code; 27 | 28 | private final String desc; 29 | 30 | 31 | public static Optional fromCode(String code) { 32 | return Arrays.stream(ConditionLogicalOperatorEum.values()) 33 | .filter(c -> c.getCode().equals(code)) 34 | .findFirst(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/support/ConditionBuilder.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.support; 2 | 3 | import com.weweibuy.brms.model.po.ModelAttr; 4 | import com.weweibuy.brms.model.po.RuleCondition; 5 | import org.drools.template.model.Package; 6 | 7 | /** 8 | * 规则条件构建 9 | * 10 | * @author durenhao 11 | * @date 2020/11/13 22:58 12 | **/ 13 | public interface ConditionBuilder { 14 | 15 | /** 16 | * 匹配 17 | * 18 | * @param ruleCondition 19 | * @param modelAttr 20 | * @return 21 | */ 22 | boolean match(RuleCondition ruleCondition, ModelAttr modelAttr); 23 | 24 | /** 25 | * 构建 26 | * 27 | * @param rulePackage 28 | * @param ruleCondition 29 | * @param conditionBuildContext 30 | * @return 31 | */ 32 | String buildConditionStr(Package rulePackage, RuleCondition ruleCondition, ConditionBuildContext conditionBuildContext); 33 | 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /brms-service/src/test/java/com/weweibuy/brms/utils/DroolsCalculateUtilsTest.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.utils; 2 | 3 | import com.googlecode.aviator.AviatorEvaluator; 4 | import org.junit.Test; 5 | 6 | import java.math.BigDecimal; 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | public class DroolsCalculateUtilsTest { 11 | 12 | @Test 13 | public void calculate() throws Exception { 14 | Map env = new HashMap<>(); 15 | env.put("price", new BigDecimal(1000)); 16 | env.put("qty", new BigDecimal(3)); 17 | env.put("qty2", new BigDecimal("3.1")); 18 | Object execute = AviatorEvaluator.execute("price / qty + qty", env); 19 | Object executeB = AviatorEvaluator.execute("1 > 0"); 20 | Object execute1 = AviatorEvaluator.execute("qty < qty2 && qty > qty2 + 100", env); 21 | System.out.println(execute); 22 | System.out.println(execute1); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/repository/RuleHitLogRepository.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.repository; 2 | 3 | import com.weweibuy.brms.mapper.RuleHitLogMapper; 4 | import com.weweibuy.brms.model.example.RuleHitLogExample; 5 | import com.weweibuy.brms.model.po.RuleHitLog; 6 | import lombok.RequiredArgsConstructor; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author durenhao 13 | * @date 2020/11/14 20:05 14 | **/ 15 | @Repository 16 | @RequiredArgsConstructor 17 | public class RuleHitLogRepository { 18 | 19 | private final RuleHitLogMapper ruleHitLogMapper; 20 | 21 | public int insert(RuleHitLog ruleHitLog) { 22 | return ruleHitLogMapper.insertSelective(ruleHitLog); 23 | } 24 | 25 | 26 | public List select(RuleHitLogExample ruleHitLogExample) { 27 | return ruleHitLogMapper.selectByExample(ruleHitLogExample); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/support/RuleProcessContextHolder.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.support; 2 | 3 | import com.weweibuy.brms.model.context.RuleProcessContext; 4 | import lombok.AccessLevel; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.Optional; 8 | 9 | /** 10 | * @author durenhao 11 | * @date 2020/11/27 20:41 12 | **/ 13 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 14 | public class RuleProcessContextHolder { 15 | 16 | private static final ThreadLocal CONTEXT_THREAD_LOCAL = new ThreadLocal<>(); 17 | 18 | public static void putContext(RuleProcessContext context) { 19 | CONTEXT_THREAD_LOCAL.set(context); 20 | } 21 | 22 | 23 | public static Optional getContext() { 24 | return Optional.ofNullable(CONTEXT_THREAD_LOCAL.get()); 25 | } 26 | 27 | public static void clearContext() { 28 | CONTEXT_THREAD_LOCAL.remove(); 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/BrmsApplication.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms; 2 | 3 | import com.weweibuy.framework.common.core.model.constant.CommonConstant; 4 | import com.weweibuy.framework.rocketmq.annotation.EnableRocket; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.cache.annotation.EnableCaching; 8 | 9 | /** 10 | * 业务规则系统 11 | * 12 | * @author durenhao 13 | * @date 2020/11/8 11:32 14 | **/ 15 | @EnableRocket(basePackages = {"com.weweibuy.brms.BrmsApplication", 16 | "com.weweibuy.framework.common.lc.mq"}) 17 | @SpringBootApplication 18 | @EnableCaching 19 | public class BrmsApplication { 20 | 21 | public static void main(String[] args) { 22 | System.setProperty("drools.dateformat", CommonConstant.DateConstant.STANDARD_DATE_TIME_FORMAT_STR); 23 | SpringApplication.run(BrmsApplication.class, args); 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/repository/ModelAndAttrRepository.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.repository; 2 | 3 | import com.weweibuy.brms.model.po.Model; 4 | import com.weweibuy.brms.model.po.ModelAttr; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | /** 10 | * 模型与属性仓库 11 | * 12 | * @author durenhao 13 | * @date 2020/11/25 20:44 14 | **/ 15 | public interface ModelAndAttrRepository { 16 | 17 | /** 18 | * 查询模型 19 | * 20 | * @param modelKey 21 | * @return 22 | */ 23 | Optional selectModel(String modelKey); 24 | 25 | 26 | /** 27 | * 查询模型属性 28 | * 29 | * @param modelKey 30 | * @return 31 | */ 32 | List selectModelAttrByModelKey(String modelKey); 33 | 34 | 35 | /** 36 | * 查询模型属性 37 | * 38 | * @param modelKey 39 | * @param attrName 40 | * @return 41 | */ 42 | Optional selectModelAttr(String modelKey, String attrName); 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /brms-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8050 3 | 4 | 5 | spring: 6 | application: 7 | name: upms 8 | datasource: 9 | driver-class-name: com.mysql.cj.jdbc.Driver 10 | type: com.zaxxer.hikari.HikariDataSource 11 | url: jdbc:mysql://223.247.141.69:3306/webuy_brms?useUnicode=true&characterEncoding=UTF-8&allowMutiQueries=true&serverTimezone=Asia/Shanghai 12 | username: user01 13 | password: ak402507979 14 | jackson: 15 | date-format: yyyy-MM-dd HH:mm:ss 16 | time-zone: GMT+8 17 | 18 | mybatis: 19 | mapper-locations: classpath*:config/mybatis/mapper/**/*.xml 20 | 21 | rocket-mq: 22 | nameServer: 223.247.141.69:9876 23 | producer: 24 | group: BRMS_RULE_EXEC_RESULT_PG 25 | rule-result: 26 | topic: RULE_EXEC_RESULT_TOPIC 27 | consumer: 28 | rule: 29 | topic: RULE_EXEC_TOPIC 30 | common: 31 | local-cache: 32 | mq-evict: 33 | enable: true 34 | consumer-group: BRMS_LOCAL_CHAHE_EVICT_CG 35 | topic: LOCAL_CHAHE_EVICT_TOPIC 36 | tag: BRMS 37 | 38 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/model/po/RuleHitLog.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.model.po; 2 | 3 | import java.time.LocalDateTime; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class RuleHitLog { 8 | /** 9 | * id自增1 10 | */ 11 | private Long id; 12 | 13 | /** 14 | * 流水号 15 | */ 16 | private String requestNo; 17 | 18 | /** 19 | * 规则集key(package) 20 | */ 21 | private String ruleSetKey; 22 | 23 | /** 24 | * 议程组 25 | */ 26 | private String agendaGroup; 27 | 28 | /** 29 | * 规则key 30 | */ 31 | private String ruleKey; 32 | 33 | /** 34 | * 输入模型(Json) 35 | */ 36 | private String inputModel; 37 | 38 | /** 39 | * 输出模型(Json) 40 | */ 41 | private String outputModel; 42 | 43 | /** 44 | * 是否删除 45 | */ 46 | private Boolean deleted; 47 | 48 | /** 49 | * 创建时间 50 | */ 51 | private LocalDateTime createTime; 52 | 53 | /** 54 | * 更新时间 55 | */ 56 | private LocalDateTime updateTime; 57 | } -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/constant/RuleBuildConstant.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.constant; 2 | 3 | /** 4 | * @author durenhao 5 | * @date 2020/11/9 22:05 6 | **/ 7 | public interface RuleBuildConstant { 8 | 9 | String MAP_CLAZZ = "java.util.Map"; 10 | 11 | String COLLECTION_UTILS = "com.weweibuy.brms.utils.DroolsCollectionUtils"; 12 | 13 | String CALCULATE_UTILS = "com.weweibuy.brms.utils.DroolsCalculateUtils"; 14 | 15 | String MODEL = "$model"; 16 | 17 | String CONDITION_MODEL = "$model:Map"; 18 | 19 | String RESULT_MODEL = "resultModel"; 20 | 21 | String RESULT_MODEL_PUT = "resultModel.put($1, $2);"; 22 | 23 | String RULE_HIT_FLAG_NAME = "_hit"; 24 | 25 | String CALCULATE_UTILS_METHOD = "DroolsCalculateUtils.calculate(%s, %s, %s, %s)"; 26 | 27 | /** 28 | * 模型属性的分隔符 eg: user.name 29 | */ 30 | String MODEL_ATTR_SEPARATOR = "."; 31 | 32 | 33 | /** 34 | * 计算公式分隔符, 防止 [.] 被作为计算符号 35 | * user@name 36 | */ 37 | String FORMULA_ATTR_SEPARATOR = "@"; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/dto/resp/RuleHitLogRespDTO.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.dto.resp; 2 | 3 | import lombok.Data; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | /** 8 | * @author durenhao 9 | * @date 2021/7/25 16:38 10 | **/ 11 | @Data 12 | public class RuleHitLogRespDTO { 13 | 14 | /** 15 | * id自增1 16 | */ 17 | private Long id; 18 | 19 | /** 20 | * 流水号 21 | */ 22 | private String requestNo; 23 | 24 | /** 25 | * 规则集key(package) 26 | */ 27 | private String ruleSetKey; 28 | 29 | /** 30 | * 议程组 31 | */ 32 | private String agendaGroup; 33 | 34 | /** 35 | * 规则key 36 | */ 37 | private String ruleKey; 38 | 39 | /** 40 | * 输入模型(Json) 41 | */ 42 | private String inputModel; 43 | 44 | /** 45 | * 输出模型(Json) 46 | */ 47 | private String outputModel; 48 | 49 | /** 50 | * 创建时间 51 | */ 52 | private LocalDateTime createTime; 53 | 54 | /** 55 | * 更新时间 56 | */ 57 | private LocalDateTime updateTime; 58 | 59 | } 60 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/model/event/RuleHitLogEvent.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.model.event; 2 | 3 | import com.weweibuy.brms.model.po.RuleHitLog; 4 | import com.weweibuy.framework.common.core.utils.BeanCopyUtils; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | 8 | /** 9 | * 规则命中事件 10 | * 11 | * @author durenhao 12 | * @date 2020/11/14 18:24 13 | **/ 14 | @Data 15 | @Builder 16 | public class RuleHitLogEvent { 17 | 18 | /** 19 | * 流水号 20 | */ 21 | private String requestNo; 22 | 23 | /** 24 | * 规则集key(package) 25 | */ 26 | private String ruleSetKey; 27 | 28 | /** 29 | * 议程组 30 | */ 31 | private String agendaGroup; 32 | 33 | /** 34 | * 规则key 35 | */ 36 | private String ruleKey; 37 | 38 | /** 39 | * 输入模型(Json) 40 | */ 41 | private String inputModel; 42 | 43 | /** 44 | * 输出模型(Json) 45 | */ 46 | private String outputModel; 47 | 48 | 49 | public RuleHitLog toRuleHitLog() { 50 | return BeanCopyUtils.copy(this, RuleHitLog.class); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/model/po/ModelAttr.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.model.po; 2 | 3 | import java.time.LocalDateTime; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class ModelAttr { 8 | /** 9 | * id自增1 10 | */ 11 | private Long id; 12 | 13 | /** 14 | * 模型key 15 | */ 16 | private String modelKey; 17 | 18 | /** 19 | * 属性名称 20 | */ 21 | private String attrName; 22 | 23 | /** 24 | * 属性描述 25 | */ 26 | private String attrDesc; 27 | 28 | /** 29 | * 属性类型(STRING,NUMBER,BOOLEAN,DATE,COLLECTION) 30 | */ 31 | private String attrType; 32 | 33 | /** 34 | * 属性模型(适用于OBJECT类型属性) 35 | */ 36 | private String attrModelKeyRef; 37 | 38 | /** 39 | * 属性值来源(INPUT,DICT,ADDRESS) 40 | */ 41 | private String attrValueSource; 42 | 43 | /** 44 | * 是否删除 45 | */ 46 | private Boolean deleted; 47 | 48 | /** 49 | * 创建时间 50 | */ 51 | private LocalDateTime createTime; 52 | 53 | /** 54 | * 更新时间 55 | */ 56 | private LocalDateTime updateTime; 57 | } -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/model/po/RuleCondition.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.model.po; 2 | 3 | import java.time.LocalDateTime; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class RuleCondition { 8 | /** 9 | * id自增1 10 | */ 11 | private Long id; 12 | 13 | /** 14 | * 规则key 15 | */ 16 | private String ruleKey; 17 | 18 | /** 19 | * 属性名称 20 | */ 21 | private String attrName; 22 | 23 | /** 24 | * 条件符 25 | */ 26 | private String conditionOperator; 27 | 28 | /** 29 | * 条件值 30 | */ 31 | private String conditionValue; 32 | 33 | /** 34 | * 逻辑运算符(与下一个条件的逻辑运算符;取值: &&,|| ) 35 | */ 36 | private String logicalOperator; 37 | 38 | /** 39 | * 排序(多个条件通过order排序,值越小越靠前,并通过 logical_operator 字段进行连接) 40 | */ 41 | private Integer conditionOrder; 42 | 43 | /** 44 | * 是否删除 45 | */ 46 | private Boolean deleted; 47 | 48 | /** 49 | * 创建时间 50 | */ 51 | private LocalDateTime createTime; 52 | 53 | /** 54 | * 更新时间 55 | */ 56 | private LocalDateTime updateTime; 57 | } -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/dto/resp/RuleModelAttrRespDTO.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.dto.resp; 2 | 3 | import lombok.Data; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | /** 8 | * @author durenhao 9 | * @date 2021/7/25 16:55 10 | **/ 11 | @Data 12 | public class RuleModelAttrRespDTO { 13 | 14 | /** 15 | * id自增1 16 | */ 17 | private Long id; 18 | 19 | /** 20 | * 模型key 21 | */ 22 | private String modelKey; 23 | 24 | /** 25 | * 属性名称 26 | */ 27 | private String attrName; 28 | 29 | /** 30 | * 属性描述 31 | */ 32 | private String attrDesc; 33 | 34 | /** 35 | * 属性类型(STRING,NUMBER,BOOLEAN,DATE,COLLECTION) 36 | */ 37 | private String attrType; 38 | 39 | /** 40 | * 属性模型(适用于OBJECT类型属性) 41 | */ 42 | private String attrModelKeyRef; 43 | 44 | /** 45 | * 属性值来源(INPUT,DICT,ADDRESS) 46 | */ 47 | private String attrValueSource; 48 | 49 | /** 50 | * 创建时间 51 | */ 52 | private LocalDateTime createTime; 53 | 54 | /** 55 | * 更新时间 56 | */ 57 | private LocalDateTime updateTime; 58 | 59 | } 60 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/dto/resp/RuleConditionRespDTO.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.dto.resp; 2 | 3 | import lombok.Data; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | /** 8 | * @author durenhao 9 | * @date 2021/7/25 16:20 10 | **/ 11 | @Data 12 | public class RuleConditionRespDTO { 13 | 14 | /** 15 | * id自增1 16 | */ 17 | private Long id; 18 | 19 | /** 20 | * 规则key 21 | */ 22 | private String ruleKey; 23 | 24 | /** 25 | * 属性名称 26 | */ 27 | private String attrName; 28 | 29 | /** 30 | * 条件符 31 | */ 32 | private String conditionOperator; 33 | 34 | /** 35 | * 条件值 36 | */ 37 | private String conditionValue; 38 | 39 | /** 40 | * 逻辑运算符(与下一个条件的逻辑运算符;取值: &&,|| ) 41 | */ 42 | private String logicalOperator; 43 | 44 | /** 45 | * 排序(多个条件通过order排序,值越小越靠前,并通过 logical_operator 字段进行连接) 46 | */ 47 | private Integer conditionOrder; 48 | 49 | /** 50 | * 创建时间 51 | */ 52 | private LocalDateTime createTime; 53 | 54 | /** 55 | * 更新时间 56 | */ 57 | private LocalDateTime updateTime; 58 | 59 | } 60 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/model/po/RuleAction.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.model.po; 2 | 3 | import lombok.Data; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | @Data 8 | public class RuleAction { 9 | /** 10 | * id自增1 11 | */ 12 | private Long id; 13 | 14 | /** 15 | * 规则key 16 | */ 17 | private String ruleKey; 18 | 19 | /** 20 | * 属性名称 21 | */ 22 | private String attrName; 23 | 24 | /** 25 | * 动作值 26 | */ 27 | private String actionValue; 28 | 29 | /** 30 | * 动作值类型(INPUT:直接输入型; CALCULATE:计算型) 31 | */ 32 | private String actionValueType; 33 | 34 | /** 35 | * 动作值计算公式(CALCULATE 类型下有效) 36 | */ 37 | private String valueCalculateFormula; 38 | 39 | /** 40 | * 计算保留位数 41 | */ 42 | private Integer calculateScale; 43 | 44 | /** 45 | * 计算取整方式 46 | */ 47 | private String calculateRoundingMode; 48 | 49 | /** 50 | * 是否删除 51 | */ 52 | private Boolean deleted; 53 | 54 | /** 55 | * 创建时间 56 | */ 57 | private LocalDateTime createTime; 58 | 59 | /** 60 | * 更新时间 61 | */ 62 | private LocalDateTime updateTime; 63 | } -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/controller/RuleMangeController.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.controller; 2 | 3 | import com.weweibuy.brms.service.RuleManageService; 4 | import com.weweibuy.framework.common.core.model.dto.CommonCodeResponse; 5 | import lombok.RequiredArgsConstructor; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | /** 12 | * 规则管理接口 13 | * 14 | * @author durenhao 15 | * @date 2020/11/9 21:45 16 | **/ 17 | @RequiredArgsConstructor 18 | @RestController 19 | @RequestMapping("/rule/manage") 20 | public class RuleMangeController { 21 | 22 | private final RuleManageService ruleManageService; 23 | 24 | @GetMapping("/compile") 25 | public String compile(String ruleSetKey) { 26 | return ruleManageService.compile(ruleSetKey); 27 | } 28 | 29 | @PostMapping("/reload") 30 | public CommonCodeResponse reload(String ruleSetKey) { 31 | ruleManageService.reload(ruleSetKey); 32 | return CommonCodeResponse.success(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/controller/RuleExecController.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.controller; 2 | 3 | import com.weweibuy.brms.api.model.dto.RuleExecReqDTO; 4 | import com.weweibuy.brms.api.model.dto.RuleExecRespDTO; 5 | import com.weweibuy.brms.service.RuleExecService; 6 | import com.weweibuy.framework.common.core.model.dto.CommonDataResponse; 7 | import lombok.RequiredArgsConstructor; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RequestBody; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import javax.validation.Valid; 14 | 15 | /** 16 | * 规则执行接口 17 | * 18 | * @author durenhao 19 | * @date 2020/11/8 20:28 20 | **/ 21 | @RestController 22 | @RequestMapping("/rule") 23 | @RequiredArgsConstructor 24 | public class RuleExecController { 25 | 26 | private final RuleExecService ruleExecService; 27 | 28 | @PostMapping("/exec") 29 | public CommonDataResponse execRule(@RequestBody @Valid RuleExecReqDTO reqDTO) { 30 | return CommonDataResponse.success(ruleExecService.execRule(reqDTO)); 31 | } 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/dto/resp/RuleActionRespDTO.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.dto.resp; 2 | 3 | import lombok.Data; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | /** 8 | * @author durenhao 9 | * @date 2021/7/25 16:20 10 | **/ 11 | @Data 12 | public class RuleActionRespDTO { 13 | 14 | /** 15 | * id自增1 16 | */ 17 | private Long id; 18 | 19 | /** 20 | * 规则key 21 | */ 22 | private String ruleKey; 23 | 24 | /** 25 | * 属性名称 26 | */ 27 | private String attrName; 28 | 29 | /** 30 | * 动作值 31 | */ 32 | private String actionValue; 33 | 34 | /** 35 | * 动作值类型(INPUT:直接输入型; CALCULATE:计算型) 36 | */ 37 | private String actionValueType; 38 | 39 | /** 40 | * 动作值计算公式(CALCULATE 类型下有效) 41 | */ 42 | private String valueCalculateFormula; 43 | 44 | /** 45 | * 计算保留位数 46 | */ 47 | private Integer calculateScale; 48 | 49 | /** 50 | * 计算取整方式 51 | */ 52 | private String calculateRoundingMode; 53 | 54 | /** 55 | * 创建时间 56 | */ 57 | private LocalDateTime createTime; 58 | 59 | /** 60 | * 更新时间 61 | */ 62 | private LocalDateTime updateTime; 63 | 64 | } 65 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/cglib/RuleModelCreator.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.cglib; 2 | 3 | import org.springframework.asm.ClassWriter; 4 | import org.springframework.asm.Opcodes; 5 | import org.springframework.cglib.beans.BeanGenerator; 6 | 7 | import java.lang.reflect.Method; 8 | import java.util.Arrays; 9 | 10 | 11 | /** 12 | * @author durenhao 13 | * @date 2021/9/20 18:08 14 | **/ 15 | public class RuleModelCreator { 16 | 17 | 18 | public static void main(String[] args) throws Exception { 19 | BeanGenerator beanGenerator = new BeanGenerator(); 20 | ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES); 21 | classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "clazz/User", null, 22 | "java/lang/Object", null); 23 | classWriter.visitEnd(); 24 | 25 | 26 | beanGenerator.generateClass(classWriter); 27 | Object o = beanGenerator.create(); 28 | System.err.println(o); 29 | System.err.println(o.getClass()); 30 | Method[] declaredMethods = o.getClass().getDeclaredMethods(); 31 | Arrays.stream(declaredMethods) 32 | .forEach(m -> System.err.println(m.getName())); 33 | ; 34 | 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/mapper/RuleMapper.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.mapper; 2 | 3 | import com.weweibuy.brms.model.example.RuleExample; 4 | import com.weweibuy.brms.model.po.Rule; 5 | import java.util.List; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | @Mapper 10 | public interface RuleMapper { 11 | long countByExample(RuleExample example); 12 | 13 | int deleteByExample(RuleExample example); 14 | 15 | int deleteByPrimaryKey(Long id); 16 | 17 | int insert(Rule record); 18 | 19 | int insertSelective(Rule record); 20 | 21 | Rule selectOneByExample(RuleExample example); 22 | 23 | Rule selectOneByExampleForUpdate(RuleExample example); 24 | 25 | List selectByExampleForUpdate(RuleExample example); 26 | 27 | List selectByExampleWithLimit(@Param("example") RuleExample example, @Param("limit") Integer limit); 28 | 29 | List selectByExample(RuleExample example); 30 | 31 | Rule selectByPrimaryKey(Long id); 32 | 33 | int updateByExampleSelective(@Param("record") Rule record, @Param("example") RuleExample example); 34 | 35 | int updateByExample(@Param("record") Rule record, @Param("example") RuleExample example); 36 | 37 | int updateByPrimaryKeySelective(Rule record); 38 | 39 | int updateByPrimaryKey(Rule record); 40 | } -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/mapper/ModelMapper.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.mapper; 2 | 3 | import com.weweibuy.brms.model.example.ModelExample; 4 | import com.weweibuy.brms.model.po.Model; 5 | import java.util.List; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | @Mapper 10 | public interface ModelMapper { 11 | long countByExample(ModelExample example); 12 | 13 | int deleteByExample(ModelExample example); 14 | 15 | int deleteByPrimaryKey(Long id); 16 | 17 | int insert(Model record); 18 | 19 | int insertSelective(Model record); 20 | 21 | Model selectOneByExample(ModelExample example); 22 | 23 | Model selectOneByExampleForUpdate(ModelExample example); 24 | 25 | List selectByExampleForUpdate(ModelExample example); 26 | 27 | List selectByExampleWithLimit(@Param("example") ModelExample example, @Param("limit") Integer limit); 28 | 29 | List selectByExample(ModelExample example); 30 | 31 | Model selectByPrimaryKey(Long id); 32 | 33 | int updateByExampleSelective(@Param("record") Model record, @Param("example") ModelExample example); 34 | 35 | int updateByExample(@Param("record") Model record, @Param("example") ModelExample example); 36 | 37 | int updateByPrimaryKeySelective(Model record); 38 | 39 | int updateByPrimaryKey(Model record); 40 | } -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/dto/RuleExecReqDTO.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.dto; 2 | 3 | import com.weweibuy.brms.api.model.eum.MultipleRuleSetExecModelStrategyEum; 4 | import lombok.Data; 5 | 6 | import javax.validation.Valid; 7 | import javax.validation.constraints.NotBlank; 8 | import javax.validation.constraints.NotEmpty; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.Set; 12 | 13 | /** 14 | * 执行规则请求 15 | * 16 | * @author durenhao 17 | * @date 2020/11/8 20:30 18 | **/ 19 | @Data 20 | public class RuleExecReqDTO { 21 | 22 | @Valid 23 | @NotEmpty(message = "规则信息不能为空") 24 | private List ruleSet; 25 | 26 | /** 27 | * 请求模型 28 | */ 29 | @NotEmpty(message = "请求模型不能为空集合") 30 | private Map model; 31 | 32 | /** 33 | * 模型策略模式 模式 USE_ACTION_MODEL 34 | */ 35 | private MultipleRuleSetExecModelStrategyEum modelStrategy; 36 | 37 | @Data 38 | public static class RuleSetKeyReqDTO { 39 | 40 | /** 41 | * 规则集 42 | */ 43 | @NotBlank(message = "ruleSetKey 不能为空") 44 | private String ruleSetKey; 45 | 46 | /** 47 | * 规则名称 48 | */ 49 | private Set ruleNameList; 50 | 51 | /** 52 | * 议程组 53 | */ 54 | private String agendaGroup; 55 | 56 | } 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/mapper/RuleSetMapper.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.mapper; 2 | 3 | import com.weweibuy.brms.model.example.RuleSetExample; 4 | import com.weweibuy.brms.model.po.RuleSet; 5 | import java.util.List; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | @Mapper 10 | public interface RuleSetMapper { 11 | long countByExample(RuleSetExample example); 12 | 13 | int deleteByExample(RuleSetExample example); 14 | 15 | int deleteByPrimaryKey(Long id); 16 | 17 | int insert(RuleSet record); 18 | 19 | int insertSelective(RuleSet record); 20 | 21 | RuleSet selectOneByExample(RuleSetExample example); 22 | 23 | RuleSet selectOneByExampleForUpdate(RuleSetExample example); 24 | 25 | List selectByExampleForUpdate(RuleSetExample example); 26 | 27 | List selectByExampleWithLimit(@Param("example") RuleSetExample example, @Param("limit") Integer limit); 28 | 29 | List selectByExample(RuleSetExample example); 30 | 31 | RuleSet selectByPrimaryKey(Long id); 32 | 33 | int updateByExampleSelective(@Param("record") RuleSet record, @Param("example") RuleSetExample example); 34 | 35 | int updateByExample(@Param("record") RuleSet record, @Param("example") RuleSetExample example); 36 | 37 | int updateByPrimaryKeySelective(RuleSet record); 38 | 39 | int updateByPrimaryKey(RuleSet record); 40 | } -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/mapper/ModelAttrMapper.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.mapper; 2 | 3 | import com.weweibuy.brms.model.example.ModelAttrExample; 4 | import com.weweibuy.brms.model.po.ModelAttr; 5 | import java.util.List; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | @Mapper 10 | public interface ModelAttrMapper { 11 | long countByExample(ModelAttrExample example); 12 | 13 | int deleteByExample(ModelAttrExample example); 14 | 15 | int deleteByPrimaryKey(Long id); 16 | 17 | int insert(ModelAttr record); 18 | 19 | int insertSelective(ModelAttr record); 20 | 21 | ModelAttr selectOneByExample(ModelAttrExample example); 22 | 23 | ModelAttr selectOneByExampleForUpdate(ModelAttrExample example); 24 | 25 | List selectByExampleForUpdate(ModelAttrExample example); 26 | 27 | List selectByExampleWithLimit(@Param("example") ModelAttrExample example, @Param("limit") Integer limit); 28 | 29 | List selectByExample(ModelAttrExample example); 30 | 31 | ModelAttr selectByPrimaryKey(Long id); 32 | 33 | int updateByExampleSelective(@Param("record") ModelAttr record, @Param("example") ModelAttrExample example); 34 | 35 | int updateByExample(@Param("record") ModelAttr record, @Param("example") ModelAttrExample example); 36 | 37 | int updateByPrimaryKeySelective(ModelAttr record); 38 | 39 | int updateByPrimaryKey(ModelAttr record); 40 | } -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/mapper/RuleActionMapper.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.mapper; 2 | 3 | import com.weweibuy.brms.model.example.RuleActionExample; 4 | import com.weweibuy.brms.model.po.RuleAction; 5 | import java.util.List; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | @Mapper 10 | public interface RuleActionMapper { 11 | long countByExample(RuleActionExample example); 12 | 13 | int deleteByExample(RuleActionExample example); 14 | 15 | int deleteByPrimaryKey(Long id); 16 | 17 | int insert(RuleAction record); 18 | 19 | int insertSelective(RuleAction record); 20 | 21 | RuleAction selectOneByExample(RuleActionExample example); 22 | 23 | RuleAction selectOneByExampleForUpdate(RuleActionExample example); 24 | 25 | List selectByExampleForUpdate(RuleActionExample example); 26 | 27 | List selectByExampleWithLimit(@Param("example") RuleActionExample example, @Param("limit") Integer limit); 28 | 29 | List selectByExample(RuleActionExample example); 30 | 31 | RuleAction selectByPrimaryKey(Long id); 32 | 33 | int updateByExampleSelective(@Param("record") RuleAction record, @Param("example") RuleActionExample example); 34 | 35 | int updateByExample(@Param("record") RuleAction record, @Param("example") RuleActionExample example); 36 | 37 | int updateByPrimaryKeySelective(RuleAction record); 38 | 39 | int updateByPrimaryKey(RuleAction record); 40 | } -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/mapper/RuleHitLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.mapper; 2 | 3 | import com.weweibuy.brms.model.example.RuleHitLogExample; 4 | import com.weweibuy.brms.model.po.RuleHitLog; 5 | import java.util.List; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | @Mapper 10 | public interface RuleHitLogMapper { 11 | long countByExample(RuleHitLogExample example); 12 | 13 | int deleteByExample(RuleHitLogExample example); 14 | 15 | int deleteByPrimaryKey(Long id); 16 | 17 | int insert(RuleHitLog record); 18 | 19 | int insertSelective(RuleHitLog record); 20 | 21 | RuleHitLog selectOneByExample(RuleHitLogExample example); 22 | 23 | RuleHitLog selectOneByExampleForUpdate(RuleHitLogExample example); 24 | 25 | List selectByExampleForUpdate(RuleHitLogExample example); 26 | 27 | List selectByExampleWithLimit(@Param("example") RuleHitLogExample example, @Param("limit") Integer limit); 28 | 29 | List selectByExample(RuleHitLogExample example); 30 | 31 | RuleHitLog selectByPrimaryKey(Long id); 32 | 33 | int updateByExampleSelective(@Param("record") RuleHitLog record, @Param("example") RuleHitLogExample example); 34 | 35 | int updateByExample(@Param("record") RuleHitLog record, @Param("example") RuleHitLogExample example); 36 | 37 | int updateByPrimaryKeySelective(RuleHitLog record); 38 | 39 | int updateByPrimaryKey(RuleHitLog record); 40 | } -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/repository/ConditionAndActionRepository.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.repository; 2 | 3 | import com.weweibuy.brms.mapper.RuleActionMapper; 4 | import com.weweibuy.brms.mapper.RuleConditionMapper; 5 | import com.weweibuy.brms.model.example.RuleActionExample; 6 | import com.weweibuy.brms.model.example.RuleConditionExample; 7 | import com.weweibuy.brms.model.po.RuleAction; 8 | import com.weweibuy.brms.model.po.RuleCondition; 9 | import lombok.RequiredArgsConstructor; 10 | import org.springframework.stereotype.Repository; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * @author durenhao 16 | * @date 2020/11/8 21:44 17 | **/ 18 | @Repository 19 | @RequiredArgsConstructor 20 | public class ConditionAndActionRepository { 21 | 22 | private final RuleConditionMapper ruleConditionMapper; 23 | 24 | private final RuleActionMapper ruleActionMapper; 25 | 26 | 27 | public List selectRuleCondition(String ruleKey) { 28 | return ruleConditionMapper.selectByExample(RuleConditionExample.newAndCreateCriteria() 29 | .andDeletedEqualTo(false) 30 | .andRuleKeyEqualTo(ruleKey) 31 | .example()); 32 | } 33 | 34 | public List selectRuleAction(String ruleKey) { 35 | return ruleActionMapper.selectByExample(RuleActionExample.newAndCreateCriteria() 36 | .andDeletedEqualTo(false) 37 | .andRuleKeyEqualTo(ruleKey) 38 | .example()); 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/mapper/RuleSetModelMapper.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.mapper; 2 | 3 | import com.weweibuy.brms.model.example.RuleSetModelExample; 4 | import com.weweibuy.brms.model.po.RuleSetModel; 5 | import java.util.List; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | @Mapper 10 | public interface RuleSetModelMapper { 11 | long countByExample(RuleSetModelExample example); 12 | 13 | int deleteByExample(RuleSetModelExample example); 14 | 15 | int deleteByPrimaryKey(Long id); 16 | 17 | int insert(RuleSetModel record); 18 | 19 | int insertSelective(RuleSetModel record); 20 | 21 | RuleSetModel selectOneByExample(RuleSetModelExample example); 22 | 23 | RuleSetModel selectOneByExampleForUpdate(RuleSetModelExample example); 24 | 25 | List selectByExampleForUpdate(RuleSetModelExample example); 26 | 27 | List selectByExampleWithLimit(@Param("example") RuleSetModelExample example, @Param("limit") Integer limit); 28 | 29 | List selectByExample(RuleSetModelExample example); 30 | 31 | RuleSetModel selectByPrimaryKey(Long id); 32 | 33 | int updateByExampleSelective(@Param("record") RuleSetModel record, @Param("example") RuleSetModelExample example); 34 | 35 | int updateByExample(@Param("record") RuleSetModel record, @Param("example") RuleSetModelExample example); 36 | 37 | int updateByPrimaryKeySelective(RuleSetModel record); 38 | 39 | int updateByPrimaryKey(RuleSetModel record); 40 | } -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/repository/JdbcRuleSetModelRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.repository; 2 | 3 | import com.weweibuy.brms.mapper.RuleSetModelMapper; 4 | import com.weweibuy.brms.api.model.eum.ModelTypeEum; 5 | import com.weweibuy.brms.model.example.RuleSetModelExample; 6 | import com.weweibuy.brms.model.po.RuleSetModel; 7 | import lombok.RequiredArgsConstructor; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.List; 11 | import java.util.Optional; 12 | 13 | /** 14 | * @author durenhao 15 | * @date 2020/11/8 21:35 16 | **/ 17 | @Repository 18 | @RequiredArgsConstructor 19 | public class JdbcRuleSetModelRepositoryImpl implements RuleSetModelRepository { 20 | 21 | private final RuleSetModelMapper ruleSetModelMapper; 22 | 23 | 24 | public List selectRuleSetModel(String ruleSetKey) { 25 | return ruleSetModelMapper.selectByExample(RuleSetModelExample.newAndCreateCriteria() 26 | .andDeletedEqualTo(false) 27 | .andRuleSetKeyEqualTo(ruleSetKey) 28 | .example()); 29 | } 30 | 31 | @Override 32 | public Optional selectRuleSetModel(String ruleSetKey, ModelTypeEum modelType) { 33 | return Optional.ofNullable(ruleSetModelMapper.selectOneByExample(RuleSetModelExample.newAndCreateCriteria() 34 | .andDeletedEqualTo(false) 35 | .andRuleSetKeyEqualTo(ruleSetKey) 36 | .andModelTypeEqualTo(modelType.toString()) 37 | .example())); 38 | } 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/mapper/RuleConditionMapper.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.mapper; 2 | 3 | import com.weweibuy.brms.model.example.RuleConditionExample; 4 | import com.weweibuy.brms.model.po.RuleCondition; 5 | import java.util.List; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | @Mapper 10 | public interface RuleConditionMapper { 11 | long countByExample(RuleConditionExample example); 12 | 13 | int deleteByExample(RuleConditionExample example); 14 | 15 | int deleteByPrimaryKey(Long id); 16 | 17 | int insert(RuleCondition record); 18 | 19 | int insertSelective(RuleCondition record); 20 | 21 | RuleCondition selectOneByExample(RuleConditionExample example); 22 | 23 | RuleCondition selectOneByExampleForUpdate(RuleConditionExample example); 24 | 25 | List selectByExampleForUpdate(RuleConditionExample example); 26 | 27 | List selectByExampleWithLimit(@Param("example") RuleConditionExample example, @Param("limit") Integer limit); 28 | 29 | List selectByExample(RuleConditionExample example); 30 | 31 | RuleCondition selectByPrimaryKey(Long id); 32 | 33 | int updateByExampleSelective(@Param("record") RuleCondition record, @Param("example") RuleConditionExample example); 34 | 35 | int updateByExample(@Param("record") RuleCondition record, @Param("example") RuleConditionExample example); 36 | 37 | int updateByPrimaryKeySelective(RuleCondition record); 38 | 39 | int updateByPrimaryKey(RuleCondition record); 40 | } -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/repository/cache/CacheRuleAndSetRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.repository.cache; 2 | 3 | import com.weweibuy.brms.model.po.Rule; 4 | import com.weweibuy.brms.model.po.RuleSet; 5 | import com.weweibuy.brms.repository.RuleAndSetRepository; 6 | import lombok.RequiredArgsConstructor; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.cache.annotation.CacheConfig; 9 | import org.springframework.cache.annotation.CacheEvict; 10 | import org.springframework.cache.annotation.Cacheable; 11 | import org.springframework.context.annotation.Primary; 12 | import org.springframework.stereotype.Component; 13 | 14 | import java.util.List; 15 | import java.util.Optional; 16 | 17 | /** 18 | * @author durenhao 19 | * @date 2020/11/25 21:40 20 | **/ 21 | @Slf4j 22 | @Component 23 | @RequiredArgsConstructor 24 | @Primary 25 | @CacheConfig(cacheNames = "rule_and_set_cache", keyGenerator = "classMethodParamNameCacheKeyGenerator") 26 | public class CacheRuleAndSetRepositoryImpl implements RuleAndSetRepository { 27 | 28 | private final RuleAndSetRepository delegate; 29 | 30 | @Override 31 | @Cacheable 32 | public Optional selectRuleSet(String ruleSetKey) { 33 | return delegate.selectRuleSet(ruleSetKey); 34 | } 35 | 36 | @Override 37 | @Cacheable 38 | public List selectRule(String ruleSetKey) { 39 | return delegate.selectRule(ruleSetKey); 40 | } 41 | 42 | @CacheEvict(allEntries = true) 43 | public void evict() { 44 | log.warn("刷新: {} 全部缓存成功 ", "rule_and_set_cache"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/support/KieBaseHolder.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.support; 2 | 3 | import com.weweibuy.brms.manager.RuleBuildManager; 4 | import lombok.RequiredArgsConstructor; 5 | import org.drools.core.impl.InternalKieContainer; 6 | import org.drools.core.impl.KnowledgeBaseImpl; 7 | import org.kie.api.KieBase; 8 | import org.kie.api.io.ResourceType; 9 | import org.kie.internal.utils.KieHelper; 10 | import org.springframework.stereotype.Component; 11 | 12 | import java.util.concurrent.ConcurrentHashMap; 13 | 14 | /** 15 | * @author durenhao 16 | * @date 2020/11/8 21:16 17 | **/ 18 | @Component 19 | @RequiredArgsConstructor 20 | public class KieBaseHolder { 21 | 22 | private final ConcurrentHashMap kieBaseMap = new ConcurrentHashMap<>(); 23 | 24 | private final RuleBuildManager ruleBuildManager; 25 | 26 | public KieBase findKieBase(String key) { 27 | return kieBaseMap.computeIfAbsent(key, this::buildKieBase); 28 | } 29 | 30 | public void remove(String key) { 31 | KieBase remove = kieBaseMap.remove(key); 32 | if (remove != null) { 33 | KnowledgeBaseImpl knowledgeBase = (KnowledgeBaseImpl) remove; 34 | InternalKieContainer kieContainer = knowledgeBase.getKieContainer(); 35 | knowledgeBase.setKieContainer(null); 36 | kieContainer.dispose(); 37 | } 38 | } 39 | 40 | 41 | private KieBase buildKieBase(String key) { 42 | KieHelper kieHelper = new KieHelper(); 43 | kieHelper.addContent(ruleBuildManager.buildRuleStr(key), ResourceType.DRL); 44 | return kieHelper.build(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/repository/cache/CacheRuleSetModelRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.repository.cache; 2 | 3 | import com.weweibuy.brms.api.model.eum.ModelTypeEum; 4 | import com.weweibuy.brms.model.po.RuleSetModel; 5 | import com.weweibuy.brms.repository.RuleSetModelRepository; 6 | import lombok.RequiredArgsConstructor; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.cache.annotation.CacheConfig; 9 | import org.springframework.cache.annotation.CacheEvict; 10 | import org.springframework.cache.annotation.Cacheable; 11 | import org.springframework.context.annotation.Primary; 12 | import org.springframework.stereotype.Component; 13 | 14 | import java.util.List; 15 | import java.util.Optional; 16 | 17 | /** 18 | * @author durenhao 19 | * @date 2020/11/25 20:52 20 | **/ 21 | @Slf4j 22 | @Component 23 | @Primary 24 | @RequiredArgsConstructor 25 | @CacheConfig(cacheNames = "rule_set_model_cache", keyGenerator = "classMethodParamNameCacheKeyGenerator") 26 | public class CacheRuleSetModelRepositoryImpl implements RuleSetModelRepository { 27 | 28 | private final RuleSetModelRepository delegate; 29 | 30 | @Override 31 | @Cacheable 32 | public List selectRuleSetModel(String ruleSetKey) { 33 | return delegate.selectRuleSetModel(ruleSetKey); 34 | } 35 | 36 | @Override 37 | @Cacheable 38 | public Optional selectRuleSetModel(String ruleSetKey, ModelTypeEum modelType) { 39 | return delegate.selectRuleSetModel(ruleSetKey, modelType); 40 | } 41 | 42 | @CacheEvict(allEntries = true) 43 | public void evict() { 44 | log.warn("刷新: {} 全部缓存成功 ", "rule_set_model_cache"); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/config/CacheConfig.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.config; 2 | 3 | import com.github.benmanes.caffeine.cache.Caffeine; 4 | import com.weweibuy.framework.common.lc.key.ClassMethodParamNameCacheKeyGenerator; 5 | import org.springframework.cache.CacheManager; 6 | import org.springframework.cache.caffeine.CaffeineCacheManager; 7 | import org.springframework.cache.interceptor.KeyGenerator; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.context.annotation.Primary; 11 | 12 | import java.util.concurrent.TimeUnit; 13 | 14 | /** 15 | * 缓存配置 16 | * 17 | * @author durenhao 18 | * @date 2020/11/26 22:35 19 | **/ 20 | @Configuration 21 | public class CacheConfig { 22 | 23 | /** 24 | * 25 | * @return 26 | */ 27 | @Bean 28 | public CacheManager caffeineCacheManager() { 29 | return buildCacheManager(100, 2000, 1, TimeUnit.DAYS); 30 | } 31 | 32 | 33 | private CaffeineCacheManager buildCacheManager(Integer initSize, Integer maxSize, long duration, TimeUnit unit) { 34 | CaffeineCacheManager cacheManager = new CaffeineCacheManager(); 35 | Caffeine caffeine = Caffeine.newBuilder() 36 | .initialCapacity(initSize) 37 | .maximumSize(maxSize) 38 | .expireAfterWrite(duration, unit); 39 | cacheManager.setAllowNullValues(true); 40 | cacheManager.setCaffeine(caffeine); 41 | return cacheManager; 42 | } 43 | 44 | @Bean 45 | @Primary 46 | public KeyGenerator classMethodParamNameCacheKeyGenerator() { 47 | return new ClassMethodParamNameCacheKeyGenerator(); 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/eum/OperatorEum.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.eum; 2 | 3 | import lombok.Getter; 4 | import lombok.RequiredArgsConstructor; 5 | 6 | import java.util.Arrays; 7 | import java.util.Map; 8 | import java.util.Optional; 9 | import java.util.function.Function; 10 | import java.util.stream.Collectors; 11 | 12 | /** 13 | * 条件操作符 14 | * 15 | * @author durenhao 16 | * @date 2020/11/12 21:48 17 | **/ 18 | @Getter 19 | @RequiredArgsConstructor 20 | public enum OperatorEum { 21 | 22 | GREATER_THAN(">", "大于"), 23 | 24 | GREATER_THAN_or_equal(">=", "大于等于"), 25 | 26 | LESS_THAN("<", "小于"), 27 | 28 | LESS_THAN_OR_EQUAL("<=", "小于等于"), 29 | 30 | EQUAL_TO("==", "等于"), 31 | 32 | NOT_EQUAL_TO("!=", "不等于"), 33 | 34 | MEMBER_OF("memberOf", "memberOf"), 35 | 36 | ALL_MEMBER_OF("all memberOf", "all memberOf"), 37 | 38 | NOT_MEMBER_OF("not memberOf", "not memberOf"), 39 | 40 | NOT_ALL_MEMBER_OF("not all memberOf", "not all memberOf"), 41 | 42 | CONTAINS("contains", "包含"), 43 | 44 | NOT_CONTAINS("not contains", "不包含"), 45 | 46 | CONTAINS_ALL("contains all", "全包含"), 47 | 48 | NTO_CONTAINS_ALL("not contains all", "全不包含"), 49 | 50 | ; 51 | 52 | private final String code; 53 | 54 | private final String desc; 55 | 56 | private static Map operatorEumMap; 57 | 58 | static { 59 | operatorEumMap = Arrays.stream(OperatorEum.values()) 60 | .collect(Collectors.toMap(OperatorEum::getCode, Function.identity(), (o, n) -> n)); 61 | } 62 | 63 | 64 | public static Optional operatorEum(String code) { 65 | return Optional.ofNullable(operatorEumMap.get(code)); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/manager/RuleQueryManager.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.manager; 2 | 3 | import com.weweibuy.brms.api.model.eum.ModelTypeEum; 4 | import com.weweibuy.brms.model.po.ModelAttr; 5 | import com.weweibuy.brms.model.po.Rule; 6 | import com.weweibuy.brms.model.po.RuleSetModel; 7 | import com.weweibuy.brms.repository.ModelAndAttrRepository; 8 | import com.weweibuy.brms.repository.RuleAndSetRepository; 9 | import com.weweibuy.brms.repository.RuleSetModelRepository; 10 | import lombok.RequiredArgsConstructor; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.util.List; 14 | import java.util.Optional; 15 | 16 | /** 17 | * 规则查询管理 18 | * 19 | * @author durenhao 20 | * @date 2020/11/25 20:38 21 | **/ 22 | @Component 23 | @RequiredArgsConstructor 24 | public class RuleQueryManager { 25 | 26 | private final RuleSetModelRepository ruleSetModelRepository; 27 | 28 | private final ModelAndAttrRepository modelAndAttrRepository; 29 | 30 | private final RuleAndSetRepository ruleAndSetRepository; 31 | 32 | 33 | /** 34 | * 查询 ruleSetKey 模型属性 35 | * 36 | * @param ruleSetKey 37 | * @param modelTypeEum 38 | * @return 39 | */ 40 | public Optional> queryModelAttr(String ruleSetKey, ModelTypeEum modelTypeEum) { 41 | return ruleSetModelRepository.selectRuleSetModel(ruleSetKey, modelTypeEum) 42 | .map(RuleSetModel::getModelKey) 43 | .map(modelAndAttrRepository::selectModelAttrByModelKey); 44 | } 45 | 46 | 47 | 48 | /** 49 | * 查询规则 50 | * 51 | * @param ruleSetKey 52 | * @return 53 | */ 54 | public List queryRule(String ruleSetKey) { 55 | return ruleAndSetRepository.selectRule(ruleSetKey); 56 | } 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/utils/DroolsCollectionUtils.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.utils; 2 | 3 | import com.weweibuy.framework.common.core.model.constant.CommonConstant; 4 | import lombok.AccessLevel; 5 | import lombok.NoArgsConstructor; 6 | import org.apache.commons.lang3.StringUtils; 7 | 8 | import java.util.Arrays; 9 | import java.util.Collection; 10 | import java.util.Collections; 11 | import java.util.List; 12 | import java.util.stream.Collectors; 13 | 14 | /** 15 | * @author durenhao 16 | * @date 2020/11/13 23:10 17 | **/ 18 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 19 | public class DroolsCollectionUtils { 20 | 21 | public static boolean containsAll(Object o, Object o2) { 22 | if (o == null) { 23 | return false; 24 | } 25 | if (o instanceof Collection) { 26 | if (o2 instanceof Collection) { 27 | return ((Collection) o).containsAll((Collection) o2); 28 | } 29 | return ((Collection) o).contains(o2); 30 | } 31 | return false; 32 | } 33 | 34 | public static boolean allMemberOf(Object o, Object o2) { 35 | if (o2 == null) { 36 | return false; 37 | } 38 | if (o2 instanceof Collection) { 39 | if (o instanceof Collection) { 40 | return ((Collection) o2).containsAll((Collection) o); 41 | } 42 | return ((Collection) o2).contains(o); 43 | } 44 | return false; 45 | } 46 | 47 | public static List toList(String str) { 48 | if (StringUtils.isBlank(str)) { 49 | return Collections.emptyList(); 50 | } 51 | return Arrays.stream(str.split(CommonConstant.COMMA_STR)) 52 | .collect(Collectors.toList()); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/model/po/Rule.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.model.po; 2 | 3 | import lombok.Data; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | @Data 8 | public class Rule { 9 | /** 10 | * id自增1 11 | */ 12 | private Long id; 13 | 14 | /** 15 | * 规则key 16 | */ 17 | private String ruleKey; 18 | 19 | /** 20 | * 规则描述 21 | */ 22 | private String ruleDesc; 23 | 24 | /** 25 | * 规则集key(package) 26 | */ 27 | private String ruleSetKey; 28 | 29 | /** 30 | * 规则录入方式(CODING:编码式录入; SELECT:选择式录入 ) 31 | */ 32 | private String ruleEnterType; 33 | 34 | /** 35 | * 规则condition代码(CODING方式) 36 | */ 37 | private String ruleConditionText; 38 | 39 | /** 40 | * 规则action代码(CODING方式) 41 | */ 42 | private String ruleActionText; 43 | 44 | /** 45 | * 规则import内容代码(CODING方式) 46 | */ 47 | private String ruleImportText; 48 | 49 | /** 50 | * activation-group 51 | */ 52 | private String activationGroup; 53 | 54 | /** 55 | * agenda-group 56 | */ 57 | private String agendaGroup; 58 | 59 | /** 60 | * no-loop(false 或 true) 61 | */ 62 | private String noLoop; 63 | 64 | /** 65 | * date-effective(格式yyyy-MM-DD HH:mm:ss) 66 | */ 67 | private String dateEffective; 68 | 69 | /** 70 | * date-expires(格式yyyy-MM-DD HH:mm:ss) 71 | */ 72 | private String dateExpires; 73 | 74 | /** 75 | * salience(优先级,值越大优先级越高) 76 | */ 77 | private Integer salience; 78 | 79 | /** 80 | * 是否删除 81 | */ 82 | private Boolean deleted; 83 | 84 | /** 85 | * 创建时间 86 | */ 87 | private LocalDateTime createTime; 88 | 89 | /** 90 | * 更新时间 91 | */ 92 | private LocalDateTime updateTime; 93 | } -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/mq/RuleExecMessageConsumer.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.mq; 2 | 3 | import com.weweibuy.brms.api.model.dto.RuleExecRespDTO; 4 | import com.weweibuy.brms.api.model.message.RuleExecMessage; 5 | import com.weweibuy.brms.api.model.message.RuleExecResultMessage; 6 | import com.weweibuy.brms.service.RuleExecService; 7 | import com.weweibuy.framework.common.core.utils.BeanCopyUtils; 8 | import com.weweibuy.framework.rocketmq.annotation.Payload; 9 | import com.weweibuy.framework.rocketmq.annotation.RocketConsumerHandler; 10 | import com.weweibuy.framework.rocketmq.annotation.RocketListener; 11 | import com.weweibuy.framework.rocketmq.core.producer.RocketProducerRegister; 12 | import lombok.RequiredArgsConstructor; 13 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 14 | import org.springframework.stereotype.Component; 15 | 16 | /** 17 | * 消费MQ消息 18 | * 19 | * @author durenhao 20 | * @date 2020/12/4 22:20 21 | **/ 22 | @Component 23 | @RocketListener(topic = "rocket-mq.consumer.rule.topic", group = "BRMS_RULE_CG") 24 | @RequiredArgsConstructor 25 | @ConditionalOnBean(RocketProducerRegister.class) 26 | public class RuleExecMessageConsumer { 27 | 28 | private final RuleExecService ruleExecService; 29 | 30 | private final RuleExecResultProvider ruleExecResultProvider; 31 | 32 | @RocketConsumerHandler 33 | public void onMessage(@Payload RuleExecMessage message) { 34 | RuleExecRespDTO ruleExecRespDTO = ruleExecService.execRule(message); 35 | String callBackTag = message.getCallBackTag(); 36 | RuleExecResultMessage resultMessage = BeanCopyUtils.copy(ruleExecRespDTO, RuleExecResultMessage.class); 37 | resultMessage.setReqNo(message.getReqNo()); 38 | ruleExecResultProvider.send(resultMessage, callBackTag); 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/repository/cache/CacheModelAndAttrRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.repository.cache; 2 | 3 | import com.weweibuy.brms.model.po.Model; 4 | import com.weweibuy.brms.model.po.ModelAttr; 5 | import com.weweibuy.brms.repository.ModelAndAttrRepository; 6 | import lombok.RequiredArgsConstructor; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.cache.annotation.CacheConfig; 9 | import org.springframework.cache.annotation.CacheEvict; 10 | import org.springframework.cache.annotation.Cacheable; 11 | import org.springframework.context.annotation.Primary; 12 | import org.springframework.stereotype.Component; 13 | 14 | import java.util.List; 15 | import java.util.Optional; 16 | 17 | /** 18 | * @author durenhao 19 | * @date 2020/11/25 20:50 20 | **/ 21 | @Slf4j 22 | @Component 23 | @Primary 24 | @RequiredArgsConstructor 25 | @CacheConfig(cacheNames = "model_and_attr_cache", keyGenerator = "classMethodParamNameCacheKeyGenerator") 26 | public class CacheModelAndAttrRepositoryImpl implements ModelAndAttrRepository { 27 | 28 | private final ModelAndAttrRepository delegate; 29 | 30 | @Override 31 | public Optional selectModel(String modelKey) { 32 | return delegate.selectModel(modelKey); 33 | } 34 | 35 | @Override 36 | @Cacheable 37 | public List selectModelAttrByModelKey(String modelKey) { 38 | return delegate.selectModelAttrByModelKey(modelKey); 39 | } 40 | 41 | @Override 42 | @Cacheable 43 | public Optional selectModelAttr(String modelKey, String attrName) { 44 | return delegate.selectModelAttr(modelKey, attrName); 45 | } 46 | 47 | @CacheEvict(allEntries = true) 48 | public void evict() { 49 | log.warn("刷新: {} 全部缓存成功 ", "model_and_attr_cache"); 50 | } 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /brms-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | brms 7 | com.weweibuy 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | brms-api 13 | 14 | 15 | 16 | com.weweibuy.framework 17 | common-feign 18 | 19 | 20 | 21 | spring-boot-starter-validation 22 | org.springframework.boot 23 | 24 | 25 | 26 | com.weweibuy.framework 27 | rocketmq 28 | true 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-source-plugin 38 | 39 | 40 | 41 | compile 42 | 43 | 44 | jar-no-fork 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/model/dto/resp/RuleRespDTO.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api.model.dto.resp; 2 | 3 | import lombok.Data; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | /** 8 | * @author durenhao 9 | * @date 2021/7/25 10:37 10 | **/ 11 | @Data 12 | public class RuleRespDTO { 13 | 14 | /** 15 | * id自增1 16 | */ 17 | private Long id; 18 | 19 | /** 20 | * 规则key 21 | */ 22 | private String ruleKey; 23 | 24 | /** 25 | * 规则描述 26 | */ 27 | private String ruleDesc; 28 | 29 | /** 30 | * 规则集key(package) 31 | */ 32 | private String ruleSetKey; 33 | 34 | /** 35 | * 规则录入方式(CODING:编码式录入; SELECT:选择式录入 ) 36 | */ 37 | private String ruleEnterType; 38 | 39 | /** 40 | * 规则condition代码(CODING方式) 41 | */ 42 | private String ruleConditionText; 43 | 44 | /** 45 | * 规则action代码(CODING方式) 46 | */ 47 | private String ruleActionText; 48 | 49 | /** 50 | * 规则import内容代码(CODING方式) 51 | */ 52 | private String ruleImportText; 53 | 54 | /** 55 | * activation-group 56 | */ 57 | private String activationGroup; 58 | 59 | /** 60 | * agenda-group 61 | */ 62 | private String agendaGroup; 63 | 64 | /** 65 | * no-loop(false 或 true) 66 | */ 67 | private String noLoop; 68 | 69 | /** 70 | * date-effective(格式yyyy-MM-DD HH:mm:ss) 71 | */ 72 | private String dateEffective; 73 | 74 | /** 75 | * date-expires(格式yyyy-MM-DD HH:mm:ss) 76 | */ 77 | private String dateExpires; 78 | 79 | /** 80 | * salience(优先级,值越大优先级越高) 81 | */ 82 | private Integer salience; 83 | 84 | /** 85 | * 创建时间 86 | */ 87 | private LocalDateTime createTime; 88 | 89 | /** 90 | * 更新时间 91 | */ 92 | private LocalDateTime updateTime; 93 | 94 | } 95 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/repository/JdbcModelAndAttrRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.repository; 2 | 3 | import com.weweibuy.brms.mapper.ModelAttrMapper; 4 | import com.weweibuy.brms.mapper.ModelMapper; 5 | import com.weweibuy.brms.model.example.ModelAttrExample; 6 | import com.weweibuy.brms.model.example.ModelExample; 7 | import com.weweibuy.brms.model.po.Model; 8 | import com.weweibuy.brms.model.po.ModelAttr; 9 | import lombok.RequiredArgsConstructor; 10 | import org.springframework.stereotype.Repository; 11 | 12 | import java.util.List; 13 | import java.util.Optional; 14 | 15 | /** 16 | * @author durenhao 17 | * @date 2020/11/8 21:35 18 | **/ 19 | @Repository 20 | @RequiredArgsConstructor 21 | public class JdbcModelAndAttrRepositoryImpl implements ModelAndAttrRepository{ 22 | 23 | private final ModelMapper modelMapper; 24 | 25 | private final ModelAttrMapper modelAttrMapper; 26 | 27 | 28 | public Optional selectModel(String modelKey) { 29 | return Optional.ofNullable(modelMapper.selectOneByExample(ModelExample.newAndCreateCriteria() 30 | .andDeletedEqualTo(false) 31 | .andModelKeyEqualTo(modelKey) 32 | .example())); 33 | } 34 | 35 | 36 | public List selectModelAttrByModelKey(String modelKey) { 37 | return modelAttrMapper.selectByExample(ModelAttrExample.newAndCreateCriteria() 38 | .andDeletedEqualTo(false) 39 | .andModelKeyEqualTo(modelKey) 40 | .example()); 41 | } 42 | 43 | 44 | public Optional selectModelAttr(String modelKey, String attrName) { 45 | return Optional.ofNullable(modelAttrMapper.selectOneByExample(ModelAttrExample.newAndCreateCriteria() 46 | .andDeletedEqualTo(false) 47 | .andModelKeyEqualTo(modelKey) 48 | .andAttrNameEqualTo(attrName) 49 | .example())); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/manager/RuleHitLogLogManager.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.manager; 2 | 3 | import com.weweibuy.brms.model.event.RuleHitLogEvent; 4 | import com.weweibuy.brms.repository.RuleHitLogRepository; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.context.event.EventListener; 7 | import org.springframework.stereotype.Component; 8 | import reactor.core.publisher.UnicastProcessor; 9 | import reactor.core.scheduler.Schedulers; 10 | 11 | import java.time.Duration; 12 | import java.util.List; 13 | 14 | /** 15 | * 操作日志管理 16 | * 17 | * @author durenhao 18 | * @date 2019/11/16 17:35 19 | **/ 20 | @Slf4j 21 | @Component 22 | public class RuleHitLogLogManager { 23 | 24 | private final UnicastProcessor listener; 25 | 26 | private final RuleHitLogRepository ruleHitLogRepository; 27 | 28 | public RuleHitLogLogManager(RuleHitLogRepository ruleHitLogRepository) { 29 | this.ruleHitLogRepository = ruleHitLogRepository; 30 | this.listener = UnicastProcessor.create(); 31 | init(); 32 | } 33 | 34 | private void init() { 35 | listener.publish() 36 | .autoConnect() 37 | .onBackpressureDrop() 38 | .bufferTimeout(200, Duration.ofMinutes(1), Schedulers.single()) 39 | .subscribe(this::doStatistics); 40 | } 41 | 42 | /** 43 | * 保存日志 44 | * 45 | * @param eventList 46 | */ 47 | private void doStatistics(List eventList) { 48 | try { 49 | eventList.stream() 50 | .map(RuleHitLogEvent::toRuleHitLog) 51 | .forEach(ruleHitLogRepository::insert); 52 | } catch (Exception e) { 53 | log.warn("保存规则命中日志异常: ", e); 54 | } 55 | } 56 | 57 | @EventListener 58 | public void onRuleHitLogEvent(RuleHitLogEvent event) { 59 | listener.onNext(event); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/repository/JdbcRuleAndSetRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.repository; 2 | 3 | import com.weweibuy.brms.mapper.RuleMapper; 4 | import com.weweibuy.brms.mapper.RuleSetMapper; 5 | import com.weweibuy.brms.model.example.RuleExample; 6 | import com.weweibuy.brms.model.example.RuleSetExample; 7 | import com.weweibuy.brms.model.po.Rule; 8 | import com.weweibuy.brms.model.po.RuleSet; 9 | import lombok.RequiredArgsConstructor; 10 | import org.apache.commons.lang3.StringUtils; 11 | import org.springframework.stereotype.Repository; 12 | 13 | import java.util.List; 14 | import java.util.Optional; 15 | 16 | /** 17 | * @author durenhao 18 | * @date 2020/11/8 21:31 19 | **/ 20 | @Repository 21 | @RequiredArgsConstructor 22 | public class JdbcRuleAndSetRepositoryImpl implements RuleAndSetRepository { 23 | 24 | private final RuleMapper ruleMapper; 25 | 26 | private final RuleSetMapper ruleSetMapper; 27 | 28 | public Optional selectRuleSet(String ruleSetKey) { 29 | return Optional.ofNullable(ruleSetMapper.selectOneByExample(RuleSetExample.newAndCreateCriteria() 30 | .andDeletedEqualTo(false) 31 | .andRuleSetKeyEqualTo(ruleSetKey) 32 | .example())); 33 | } 34 | 35 | 36 | public List selectRule(String ruleSetKey) { 37 | return ruleMapper.selectByExample(RuleExample.newAndCreateCriteria() 38 | .andDeletedEqualTo(false) 39 | .when(StringUtils.isNotBlank(ruleSetKey), 40 | c -> c.andRuleSetKeyEqualTo(ruleSetKey)) 41 | .example()); 42 | } 43 | 44 | public Optional selectRuleByRuleKey(String ruleKey) { 45 | return Optional.ofNullable(ruleMapper.selectOneByExample(RuleExample.newAndCreateCriteria() 46 | .andDeletedEqualTo(false) 47 | .andRuleKeyEqualTo(ruleKey) 48 | .example())); 49 | } 50 | 51 | public List selectRuleSet(String ruleSetKey, String ruleSetName) { 52 | return ruleSetMapper.selectByExample(RuleSetExample.newAndCreateCriteria() 53 | .andDeletedEqualTo(false) 54 | .when(StringUtils.isNotBlank(ruleSetKey), 55 | c -> c.andRuleSetKeyEqualTo(ruleSetKey)) 56 | .when(StringUtils.isNotBlank(ruleSetName), 57 | c -> c.andRuleSetNameLike("%" + ruleSetName + "%")) 58 | .example()); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/support/DrlBuildSupport.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.support; 2 | 3 | import com.weweibuy.brms.api.model.constant.RuleBuildConstant; 4 | import com.weweibuy.framework.common.core.model.constant.CommonConstant; 5 | import org.drools.decisiontable.parser.LhsBuilder; 6 | 7 | import java.util.Arrays; 8 | import java.util.stream.Collectors; 9 | 10 | /** 11 | * @author durenhao 12 | * @date 2020/11/12 21:01 13 | **/ 14 | public class DrlBuildSupport { 15 | 16 | private static final String STR_FORMAT = "\"%s\""; 17 | 18 | private static final String COLLECTION_FORMAT = "[%s]"; 19 | 20 | private static final String ACTION_COLLECTION_FORMAT = "DroolsCollectionUtils.toList(%s)"; 21 | 22 | 23 | public static String formatString(String stringValue) { 24 | return String.format(STR_FORMAT, stringValue); 25 | } 26 | 27 | public static String formatStringCollection(String stringValue) { 28 | return Arrays.stream(stringValue.split(CommonConstant.COMMA_STR)) 29 | .map(DrlBuildSupport::formatString) 30 | .collect(Collectors.joining(",", "[", "]")); 31 | } 32 | 33 | public static String formatNumberCollection(String stringValue) { 34 | return String.format(COLLECTION_FORMAT, stringValue); 35 | } 36 | 37 | public static String formatActionCollection(String stringValue) { 38 | return String.format(ACTION_COLLECTION_FORMAT, stringValue); 39 | } 40 | 41 | 42 | public static String buildConditionStr(String template, String param) { 43 | LhsBuilder lhsBuilder = new LhsBuilder(0, 0, RuleBuildConstant.CONDITION_MODEL); 44 | lhsBuilder.addTemplate(0, 0, template); 45 | lhsBuilder.addCellValue(0, 0, param); 46 | return lhsBuilder.getResult(); 47 | } 48 | 49 | public static String buildNestingConditionStr(String[] oriAttr) { 50 | String[] attr = new String[oriAttr.length - 1]; 51 | System.arraycopy(oriAttr, 0, attr, 0, oriAttr.length - 1); 52 | 53 | StringBuilder stringBuilder = new StringBuilder(); 54 | for (int i = 0; i < attr.length; i++) { 55 | for (int j = 0; j <= i; j++) { 56 | stringBuilder.append(attr[j]); 57 | if (j != i) { 58 | stringBuilder.append("."); 59 | } 60 | } 61 | stringBuilder.append(" != null"); 62 | if (i != attr.length - 1) { 63 | stringBuilder.append(" && "); 64 | } 65 | } 66 | return stringBuilder.toString(); 67 | } 68 | 69 | 70 | } 71 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/service/RuleManageService.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.service; 2 | 3 | import com.weweibuy.brms.manager.RuleBuildManager; 4 | import com.weweibuy.brms.support.KieBaseHolder; 5 | import com.weweibuy.framework.common.core.utils.JackJsonUtils; 6 | import com.weweibuy.framework.common.lc.event.LocalCacheEvictedEvent; 7 | import com.weweibuy.framework.common.lc.mq.LocalCacheEvictProducer; 8 | import com.weweibuy.framework.common.lc.mq.message.LocalCacheEvictMessage; 9 | import lombok.RequiredArgsConstructor; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.apache.commons.lang3.StringUtils; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.context.event.EventListener; 14 | import org.springframework.stereotype.Service; 15 | 16 | import java.util.Collections; 17 | import java.util.Set; 18 | 19 | /** 20 | * @author durenhao 21 | * @date 2020/11/9 21:47 22 | **/ 23 | @Slf4j 24 | @Service 25 | @RequiredArgsConstructor 26 | public class RuleManageService { 27 | 28 | private final RuleBuildManager ruleBuildManager; 29 | 30 | private final KieBaseHolder kieBaseHolder; 31 | 32 | @Autowired(required = false) 33 | private LocalCacheEvictProducer localCacheEvictProducer; 34 | 35 | 36 | public String compile(String ruleSetKey) { 37 | return ruleBuildManager.buildRuleStr(ruleSetKey); 38 | } 39 | 40 | public void reload(String ruleSetKey) { 41 | Set singleton = Collections.singleton(ruleSetKey); 42 | String write = JackJsonUtils.writeValue(singleton); 43 | LocalCacheEvictedEvent localCacheEvictedEvent = new LocalCacheEvictedEvent(write); 44 | LocalCacheEvictMessage message = LocalCacheEvictMessage.evict(null, null, localCacheEvictedEvent); 45 | localCacheEvictProducer.send(message); 46 | } 47 | 48 | @EventListener 49 | public void onCacheEvicted(LocalCacheEvictedEvent localCacheEvictedEvent) { 50 | // 是否重新加载规则 51 | String body = localCacheEvictedEvent.getBody(); 52 | if (StringUtils.isNotBlank(body)) { 53 | Set set = JackJsonUtils.readValue(body, Set.class); 54 | set.forEach(this::doReload); 55 | } 56 | } 57 | 58 | 59 | public void doReload(String ruleSetKey) { 60 | try { 61 | kieBaseHolder.remove(ruleSetKey); 62 | kieBaseHolder.findKieBase(ruleSetKey); 63 | log.warn("重新加载规则: {}, 完成", ruleSetKey); 64 | } catch (Exception e) { 65 | log.error("重新加载规则: {}, 失败", ruleSetKey, e); 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /brms-api/src/main/java/com/weweibuy/brms/api/RuleQueryApi.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.api; 2 | 3 | import com.weweibuy.brms.api.model.dto.req.RuleHitLogReqDTO; 4 | import com.weweibuy.brms.api.model.dto.resp.*; 5 | import com.weweibuy.framework.common.core.model.dto.CommonDataResponse; 6 | import com.weweibuy.framework.common.core.model.dto.CommonPageRequest; 7 | import com.weweibuy.framework.common.core.model.dto.CommonPageResult; 8 | import org.springframework.cloud.openfeign.SpringQueryMap; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RequestParam; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * @author durenhao 17 | * @date 2021/7/25 17:00 18 | **/ 19 | public interface RuleQueryApi { 20 | 21 | @GetMapping("/rule/query/rule-set/list") 22 | CommonDataResponse> ruleSet(@RequestParam("ruleSetKey") String ruleSetKey, @RequestParam("ruleSetName") String ruleSetName, 23 | @SpringQueryMap CommonPageRequest pageRequest); 24 | 25 | @GetMapping("/rule/query/rule-set") 26 | CommonDataResponse ruleSet(@RequestParam("ruleSetKey") String ruleSetKey); 27 | 28 | @GetMapping("/rule/query/rule/list") 29 | CommonDataResponse> ruleList(@RequestParam("ruleSetKey") String ruleSetKey, @SpringQueryMap CommonPageRequest pageRequest); 30 | 31 | @GetMapping("/rule/query/rule-set/model") 32 | CommonDataResponse> ruleSetModel(@RequestParam("ruleSetKey") String ruleSetKey); 33 | 34 | @GetMapping("/rule/query/model/attr") 35 | CommonDataResponse> ruleSetModelAttr(@RequestParam("modelKey") String modelKey); 36 | 37 | @GetMapping("/rule/query/rule/condition") 38 | CommonDataResponse> ruleCondition(@RequestParam("ruleKey") String ruleKey); 39 | 40 | @GetMapping("/rule/query/rule/action") 41 | CommonDataResponse> ruleAction(@RequestParam("ruleKey") String ruleKey); 42 | 43 | @GetMapping("/rule/query/rule/hit-log/list") 44 | CommonDataResponse> ruleHitLog(@SpringQueryMap RuleHitLogReqDTO query); 45 | 46 | @GetMapping("/rule/query/rule") 47 | CommonDataResponse rule(@RequestParam("ruleKey") String ruleKey); 48 | 49 | @GetMapping("/rule/query/model") 50 | CommonDataResponse model(@RequestParam("modelKey") String modelKey); 51 | 52 | } 53 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/support/RuleTranslateHelper.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.support; 2 | 3 | import com.weweibuy.brms.api.model.eum.ModelAttrTypeEum; 4 | import com.weweibuy.brms.model.po.Model; 5 | import com.weweibuy.brms.model.po.ModelAttr; 6 | import com.weweibuy.brms.model.po.RuleSetModel; 7 | import com.weweibuy.brms.repository.JdbcModelAndAttrRepositoryImpl; 8 | import lombok.RequiredArgsConstructor; 9 | import org.apache.commons.collections4.CollectionUtils; 10 | import org.apache.commons.lang3.StringUtils; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.util.HashMap; 14 | import java.util.List; 15 | import java.util.Map; 16 | import java.util.Optional; 17 | import java.util.stream.Collectors; 18 | 19 | /** 20 | * @author durenhao 21 | * @date 2021/7/27 22:40 22 | **/ 23 | @Component 24 | @RequiredArgsConstructor 25 | public class RuleTranslateHelper { 26 | 27 | private final JdbcModelAndAttrRepositoryImpl modelAndAttrRepository; 28 | 29 | 30 | public Map translateAttr(RuleSetModel ruleSetModel, String keySeparator) { 31 | Map container = new HashMap<>(); 32 | modelAndAttrRepository.selectModel(ruleSetModel.getModelKey()) 33 | .ifPresent(m -> translateAttr(m, "", m.getModelDesc(), keySeparator, container)); 34 | return container; 35 | } 36 | 37 | private void translateAttr(Model model, String lastKey, String lastName, String keySeparator, Map container) { 38 | List modelAttrList = modelAndAttrRepository.selectModelAttrByModelKey(model.getModelKey()); 39 | Map> isObjectMap = modelAttrList.stream() 40 | .collect(Collectors.groupingBy(a -> ModelAttrTypeEum.OBJECT.toString().equals(a.getAttrType()))); 41 | List noObjectAttrList = isObjectMap.get(false); 42 | if (CollectionUtils.isNotEmpty(noObjectAttrList)) { 43 | noObjectAttrList.forEach(a -> 44 | container.put(key(lastKey, a.getAttrName(), keySeparator), lastName + "." + a.getAttrDesc())); 45 | } 46 | List objectAttrList = isObjectMap.get(true); 47 | if (CollectionUtils.isNotEmpty(objectAttrList)) { 48 | objectAttrList.forEach(a -> modelAndAttrRepository.selectModel(a.getAttrModelKeyRef()) 49 | .ifPresent(m -> translateAttr(m, key(lastKey, a.getAttrName(), keySeparator), 50 | lastName + "." + a.getAttrDesc(), keySeparator, container))); 51 | } 52 | 53 | } 54 | 55 | private String key(String lastKey, String currentKey, String keySeparator) { 56 | return Optional.ofNullable(lastKey) 57 | .filter(StringUtils::isNotBlank) 58 | .map(l -> l + keySeparator + currentKey) 59 | .orElse(currentKey); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/support/RuleModelHelper.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.support; 2 | 3 | import com.weweibuy.brms.api.model.dto.RuleExecReqDTO; 4 | import com.weweibuy.brms.manager.RuleQueryManager; 5 | import com.weweibuy.brms.model.context.RuleProcessContext; 6 | import com.weweibuy.brms.api.model.eum.ModelAttrTypeEum; 7 | import com.weweibuy.brms.model.po.ModelAttr; 8 | import com.weweibuy.brms.model.po.Rule; 9 | import com.weweibuy.brms.repository.ModelAndAttrRepository; 10 | import com.weweibuy.framework.common.core.exception.Exceptions; 11 | import lombok.RequiredArgsConstructor; 12 | import org.springframework.stereotype.Component; 13 | 14 | import java.util.List; 15 | import java.util.Map; 16 | import java.util.stream.Collectors; 17 | 18 | /** 19 | * @author durenhao 20 | * @date 2020/11/25 21:00 21 | **/ 22 | @Component 23 | @RequiredArgsConstructor 24 | public class RuleModelHelper { 25 | 26 | private final RuleQueryManager ruleQueryManager; 27 | 28 | private final ModelAndAttrRepository modelAndAttrRepository; 29 | 30 | 31 | /** 32 | * 对不存在的属性赋空值 33 | * 34 | * @param inputModel 35 | * @param modelAttrList 36 | * @return 37 | */ 38 | public void fixModel(Map inputModel, List modelAttrList) { 39 | modelAttrList.stream() 40 | .forEach(modelAttr -> { 41 | String attrName = modelAttr.getAttrName(); 42 | Object nestModelObject = inputModel.get(attrName); 43 | if (nestModelObject == null) { 44 | inputModel.put(attrName, null); 45 | } else if (ModelAttrTypeEum.OBJECT.toString().equals(modelAttr.getAttrType())) { 46 | if (!(nestModelObject instanceof Map)) { 47 | throw Exceptions.business(String.format("输入模型: %s, 错误", modelAttr.getModelKey())); 48 | } 49 | Map nestModelMap = (Map) nestModelObject; 50 | String attrModelKeyRef = modelAttr.getAttrModelKeyRef(); 51 | List modelAttrs = modelAndAttrRepository.selectModelAttrByModelKey(attrModelKeyRef); 52 | fixModel(nestModelMap, modelAttrs); 53 | } 54 | }); 55 | } 56 | 57 | public void bingProcessContext(RuleExecReqDTO execReqDTO) { 58 | RuleProcessContext ruleProcessContext = newProcessContext(execReqDTO); 59 | RuleProcessContextHolder.putContext(ruleProcessContext); 60 | } 61 | 62 | 63 | /** 64 | * @param execReqDTO 65 | * @return 66 | */ 67 | public RuleProcessContext newProcessContext(RuleExecReqDTO execReqDTO) { 68 | 69 | List ruleSet = execReqDTO.getRuleSet(); 70 | List ruleSetKeyList = ruleSet.stream() 71 | .map(RuleExecReqDTO.RuleSetKeyReqDTO::getRuleSetKey) 72 | .collect(Collectors.toList()); 73 | 74 | List processRuleSetList = ruleSetKeyList.stream() 75 | .map(rs -> { 76 | List ruleList = ruleQueryManager.queryRule(rs); 77 | List processRuleList = ruleList.stream() 78 | .map(rule -> RuleProcessContext.processRule(rule, false)) 79 | .collect(Collectors.toList()); 80 | return RuleProcessContext.processRuleSet(rs, processRuleList); 81 | }) 82 | .collect(Collectors.toList()); 83 | 84 | return RuleProcessContext.ruleProcessContext(false, processRuleSetList); 85 | 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /brms-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | brms 7 | com.weweibuy 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | brms-service 13 | 14 | 15 | 16 | 17 | com.weweibuy 18 | brms-api 19 | 20 | 21 | 22 | com.weweibuy.framework 23 | common-log 24 | 25 | 26 | 27 | com.weweibuy.framework 28 | common-mvc 29 | 30 | 31 | 32 | com.weweibuy.framework 33 | common-db 34 | 35 | 36 | 37 | com.weweibuy.framework 38 | common-core 39 | 40 | 41 | 42 | com.weweibuy.framework 43 | rocketmq 44 | 45 | 46 | 47 | com.weweibuy.framework 48 | common-local-cache 49 | 50 | 51 | 52 | org.drools 53 | drools-compiler 54 | ${drools.verion} 55 | 56 | 57 | 58 | org.kie 59 | kie-spring 60 | ${drools.verion} 61 | 62 | 63 | org.springframework 64 | spring-tx 65 | 66 | 67 | org.springframework 68 | spring-beans 69 | 70 | 71 | org.springframework 72 | spring-core 73 | 74 | 75 | org.springframework 76 | spring-context 77 | 78 | 79 | 80 | 81 | 82 | io.projectreactor 83 | reactor-core 84 | 85 | 86 | 87 | org.scijava 88 | parsington 89 | 90 | 91 | 92 | com.alibaba 93 | QLExpress 94 | 3.3.0 95 | 96 | 97 | 98 | com.googlecode.aviator 99 | aviator 100 | 5.2.7 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/controller/RuleQueryController.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.controller; 2 | 3 | import com.weweibuy.brms.api.model.dto.req.RuleHitLogReqDTO; 4 | import com.weweibuy.brms.api.model.dto.resp.*; 5 | import com.weweibuy.brms.service.RuleQueryService; 6 | import com.weweibuy.framework.common.core.model.dto.CommonDataResponse; 7 | import com.weweibuy.framework.common.core.model.dto.CommonPageRequest; 8 | import com.weweibuy.framework.common.core.model.dto.CommonPageResult; 9 | import lombok.RequiredArgsConstructor; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * 规则查询接口 19 | * 20 | * @author durenhao 21 | * @date 2021/7/23 21:36 22 | **/ 23 | @RequiredArgsConstructor 24 | @RestController 25 | @RequestMapping("/rule/query") 26 | public class RuleQueryController { 27 | 28 | private final RuleQueryService ruleQueryService; 29 | 30 | @GetMapping("/rule-set/list") 31 | public CommonDataResponse> ruleSet(String ruleSetKey, String ruleSetName, 32 | CommonPageRequest pageRequest) { 33 | return CommonDataResponse.success(ruleQueryService.ruleSet(ruleSetKey, ruleSetName, pageRequest)); 34 | } 35 | 36 | @GetMapping("/rule-set") 37 | public CommonDataResponse ruleSet(@RequestParam String ruleSetKey) { 38 | return CommonDataResponse.success(ruleQueryService.ruleSet(ruleSetKey)); 39 | } 40 | 41 | @GetMapping("/rule") 42 | public CommonDataResponse rule(@RequestParam String ruleKey) { 43 | return CommonDataResponse.success(ruleQueryService.rule(ruleKey)); 44 | } 45 | 46 | @GetMapping("/rule/list") 47 | public CommonDataResponse> ruleList(String ruleSetKey, CommonPageRequest pageRequest) { 48 | return CommonDataResponse.success(ruleQueryService.ruleList(ruleSetKey, pageRequest)); 49 | } 50 | 51 | @GetMapping("/rule-set/model") 52 | public CommonDataResponse> ruleSetModel(@RequestParam String ruleSetKey) { 53 | return CommonDataResponse.success(ruleQueryService.ruleSetModel(ruleSetKey)); 54 | } 55 | 56 | @GetMapping("/model") 57 | public CommonDataResponse model(@RequestParam String modelKey) { 58 | return CommonDataResponse.success(ruleQueryService.model(modelKey)); 59 | } 60 | 61 | @GetMapping("/model/attr") 62 | public CommonDataResponse> ruleSetModelAttr(@RequestParam String modelKey) { 63 | return CommonDataResponse.success(ruleQueryService.ruleSetModelAttr(modelKey)); 64 | } 65 | 66 | 67 | @GetMapping("/rule/condition") 68 | public CommonDataResponse> ruleCondition(@RequestParam String ruleKey) { 69 | return CommonDataResponse.success(ruleQueryService.ruleCondition(ruleKey)); 70 | } 71 | 72 | @GetMapping("/rule/action") 73 | public CommonDataResponse> ruleAction(@RequestParam String ruleKey) { 74 | return CommonDataResponse.success(ruleQueryService.ruleAction(ruleKey)); 75 | } 76 | 77 | @GetMapping("/rule/hit-log/list") 78 | public CommonDataResponse> ruleHitLog(RuleHitLogReqDTO query) { 79 | return CommonDataResponse.success(ruleQueryService.ruleHitLog(query)); 80 | } 81 | 82 | /** 83 | * 翻译规则 84 | * 85 | * @param ruleKey 86 | * @return 87 | */ 88 | @GetMapping("/rule/translate") 89 | public CommonDataResponse ruleTranslate(@RequestParam String ruleKey) { 90 | return CommonDataResponse.success(ruleQueryService.ruleTranslate(ruleKey)); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/support/NotCollectionConditionBuilder.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.support; 2 | 3 | import com.weweibuy.brms.api.model.eum.ModelAttrTypeEum; 4 | import com.weweibuy.brms.api.model.eum.OperatorEum; 5 | import com.weweibuy.brms.model.po.ModelAttr; 6 | import com.weweibuy.brms.model.po.RuleCondition; 7 | import com.weweibuy.framework.common.core.exception.Exceptions; 8 | import com.weweibuy.framework.common.core.utils.DateTimeUtils; 9 | import org.apache.commons.lang3.StringUtils; 10 | import org.drools.template.model.Package; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * @author durenhao 17 | * @date 2020/11/14 9:48 18 | **/ 19 | @Component 20 | public class NotCollectionConditionBuilder implements ConditionBuilder { 21 | @Override 22 | public boolean match(RuleCondition ruleCondition, ModelAttr modelAttr) { 23 | ModelAttrTypeEum modelAttrTypeEum = ModelAttrTypeEum.valueOf(modelAttr.getAttrType()); 24 | return !(ModelAttrTypeEum.COLLECTION_NUMBER.equals(modelAttrTypeEum) || ModelAttrTypeEum.COLLECTION_STRING.equals(modelAttrTypeEum)); 25 | } 26 | 27 | @Override 28 | public String buildConditionStr(Package rulePackage, RuleCondition ruleCondition, ConditionBuildContext conditionBuildContext) { 29 | ModelAttr modelAttr = conditionBuildContext.getModelAttr(); 30 | List paramList = conditionBuildContext.getParamList(); 31 | int index = conditionBuildContext.getConditionIndex(); 32 | 33 | String attrName = ruleCondition.getAttrName(); 34 | String template = String.format("%s %s %s", attrName, ruleCondition.getConditionOperator(), "$" + (index + 1)); 35 | 36 | if (conditionBuildContext.getNesting()) { 37 | String conditionStr = DrlBuildSupport.buildNestingConditionStr(conditionBuildContext.getOriConditionAttrArr()); 38 | template = String.format("%s && %s", conditionStr, template); 39 | } 40 | if (conditionBuildContext.getMaxIndex() != 0) { 41 | template = "(" + template + ")"; 42 | } 43 | 44 | String paramStr = paramStr(ruleCondition, modelAttr); 45 | paramList.add(paramStr); 46 | return template; 47 | } 48 | 49 | private String paramStr(RuleCondition ruleCondition, ModelAttr modelAttr) { 50 | String attrValue = ruleCondition.getConditionValue(); 51 | String attrType = modelAttr.getAttrType(); 52 | String conditionOperator = ruleCondition.getConditionOperator(); 53 | 54 | ModelAttrTypeEum modelAttrTypeEum = ModelAttrTypeEum.valueOf(attrType); 55 | 56 | if (StringUtils.equalsAny(conditionOperator, OperatorEum.ALL_MEMBER_OF.getCode(), OperatorEum.NOT_ALL_MEMBER_OF.getCode())) { 57 | throw Exceptions.business(String.format("属性: %s, 类型:%s, 不支持操作符:%s", modelAttr.getAttrName(), attrType, conditionOperator)); 58 | } 59 | 60 | if (conditionOperator.equals(OperatorEum.MEMBER_OF.getCode()) || conditionOperator.equals(OperatorEum.NOT_MEMBER_OF.getCode())) { 61 | switch (modelAttrTypeEum) { 62 | case NUMBER: 63 | return DrlBuildSupport.formatNumberCollection(attrValue); 64 | case STRING: 65 | return DrlBuildSupport.formatStringCollection(attrValue); 66 | default: 67 | throw Exceptions.business(String.format("操作符: %s, 不支持的数据类型: %s", conditionOperator, modelAttrTypeEum)); 68 | } 69 | } 70 | 71 | switch (modelAttrTypeEum) { 72 | case NUMBER: 73 | return attrValue; 74 | case STRING: 75 | return DrlBuildSupport.formatString(attrValue); 76 | case DATE_DAY: 77 | return DateTimeUtils.strDateToMilli(attrValue) + ""; 78 | case DATE_SECOND: 79 | return DateTimeUtils.strDateTimeToMilli(attrValue) + ""; 80 | case BOOLEAN: 81 | return attrValue; 82 | default: 83 | } 84 | return attrValue; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/model/context/RuleProcessContext.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.model.context; 2 | 3 | import com.weweibuy.brms.api.model.constant.RuleBuildConstant; 4 | import com.weweibuy.brms.api.model.dto.RuleExecProcessRespDTO; 5 | import com.weweibuy.brms.api.model.dto.RuleExecRespDTO; 6 | import com.weweibuy.brms.model.po.Rule; 7 | import com.weweibuy.framework.common.core.utils.BeanCopyUtils; 8 | import lombok.Data; 9 | 10 | import java.util.*; 11 | import java.util.stream.Collectors; 12 | 13 | /** 14 | * @author durenhao 15 | * @date 2020/11/27 20:21 16 | **/ 17 | @Data 18 | public class RuleProcessContext { 19 | 20 | private Boolean hit; 21 | 22 | private Map processRuleSetMap; 23 | 24 | 25 | @Data 26 | public static class ProcessRuleSet { 27 | 28 | private String ruleSet; 29 | 30 | private Map processRuleMap; 31 | 32 | 33 | public RuleExecProcessRespDTO toRuleExecProcessRespDTO(){ 34 | 35 | RuleExecProcessRespDTO ruleExecProcessRespDTO = new RuleExecProcessRespDTO(); 36 | ruleExecProcessRespDTO.setRuleSet(ruleSet); 37 | 38 | List collect = processRuleMap.values().stream() 39 | .sorted(Comparator.comparing(ProcessRule::getSalience).reversed()) 40 | .map(ProcessRule::toProcessRuleDTO) 41 | .collect(Collectors.toList()); 42 | ruleExecProcessRespDTO.setRule(collect); 43 | return ruleExecProcessRespDTO; 44 | 45 | } 46 | 47 | } 48 | 49 | @Data 50 | public static class ProcessRule { 51 | 52 | private String name; 53 | 54 | private Boolean hit; 55 | 56 | private String agendaGroup; 57 | 58 | private Integer salience; 59 | 60 | 61 | public RuleExecProcessRespDTO.ProcessRuleDTO toProcessRuleDTO() { 62 | return BeanCopyUtils.copy(this, RuleExecProcessRespDTO.ProcessRuleDTO.class); 63 | } 64 | 65 | 66 | } 67 | 68 | public static ProcessRule processRule(Rule rule, Boolean hit) { 69 | ProcessRule processRule = new ProcessRule(); 70 | processRule.setName(rule.getRuleKey()); 71 | processRule.setHit(hit); 72 | processRule.setAgendaGroup(rule.getAgendaGroup()); 73 | processRule.setSalience(Optional.ofNullable(rule.getSalience()).orElse(0)); 74 | return processRule; 75 | } 76 | 77 | public static ProcessRuleSet processRuleSet(String ruleSetKey, List ruleList) { 78 | ProcessRuleSet processRuleSet = new ProcessRuleSet(); 79 | processRuleSet.setRuleSet(ruleSetKey); 80 | Map ruleLinkedHashMap = new LinkedHashMap<>(); 81 | ruleList.forEach(r -> ruleLinkedHashMap.put(r.getName(), r)); 82 | processRuleSet.setProcessRuleMap(ruleLinkedHashMap); 83 | return processRuleSet; 84 | } 85 | 86 | public static RuleProcessContext ruleProcessContext(Boolean hit, List ruleSetList) { 87 | RuleProcessContext ruleProcessContext = new RuleProcessContext(); 88 | ruleProcessContext.setHit(hit); 89 | Map ruleSetLinkedHashMap = new LinkedHashMap<>(); 90 | ruleSetList.forEach(r -> ruleSetLinkedHashMap.put(r.getRuleSet(), r)); 91 | ruleProcessContext.setProcessRuleSetMap(ruleSetLinkedHashMap); 92 | return ruleProcessContext; 93 | } 94 | 95 | 96 | 97 | public RuleExecRespDTO toRuleExecRespDTO(Map resultModel){ 98 | 99 | resultModel.remove(RuleBuildConstant.RULE_HIT_FLAG_NAME); 100 | 101 | RuleExecRespDTO ruleExecRespDTO = new RuleExecRespDTO(); 102 | ruleExecRespDTO.setHit(hit); 103 | ruleExecRespDTO.setModel(resultModel); 104 | 105 | List collect = processRuleSetMap.values().stream() 106 | .map(ProcessRuleSet::toRuleExecProcessRespDTO) 107 | .collect(Collectors.toList()); 108 | ruleExecRespDTO.setProcess(collect); 109 | return ruleExecRespDTO; 110 | 111 | } 112 | 113 | 114 | } 115 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/drools/RuleLogEventListener.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.drools; 2 | 3 | import com.weweibuy.brms.api.model.constant.RuleBuildConstant; 4 | import com.weweibuy.brms.model.context.RuleProcessContext; 5 | import com.weweibuy.brms.model.event.RuleHitLogEvent; 6 | import com.weweibuy.brms.support.RuleProcessContextHolder; 7 | import com.weweibuy.framework.common.core.concurrent.LogExceptionThreadFactory; 8 | import com.weweibuy.framework.common.core.utils.IdWorker; 9 | import com.weweibuy.framework.common.core.utils.JackJsonUtils; 10 | import com.weweibuy.framework.common.log.support.LogTraceContext; 11 | import lombok.RequiredArgsConstructor; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.drools.core.common.DefaultAgenda; 14 | import org.drools.core.common.DefaultFactHandle; 15 | import org.kie.api.definition.rule.Rule; 16 | import org.kie.api.event.rule.AfterMatchFiredEvent; 17 | import org.kie.api.event.rule.DefaultAgendaEventListener; 18 | import org.kie.api.runtime.KieRuntime; 19 | import org.kie.api.runtime.rule.Agenda; 20 | import org.kie.api.runtime.rule.FactHandle; 21 | import org.springframework.context.ApplicationContext; 22 | import org.springframework.stereotype.Component; 23 | 24 | import java.util.Map; 25 | import java.util.concurrent.LinkedBlockingQueue; 26 | import java.util.concurrent.ThreadPoolExecutor; 27 | import java.util.concurrent.TimeUnit; 28 | 29 | @Slf4j 30 | @Component 31 | @RequiredArgsConstructor 32 | public class RuleLogEventListener extends DefaultAgendaEventListener { 33 | 34 | private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(1, 1, 35 | 0L, TimeUnit.MILLISECONDS, 36 | new LinkedBlockingQueue(100), new LogExceptionThreadFactory("rule-hit-log-"), new ThreadPoolExecutor.DiscardPolicy()); 37 | 38 | private final ApplicationContext applicationContext; 39 | 40 | 41 | @Override 42 | public void afterMatchFired(AfterMatchFiredEvent event) { 43 | 44 | 45 | try { 46 | KieRuntime kieRuntime = event.getKieRuntime(); 47 | Agenda agenda = kieRuntime.getAgenda(); 48 | String agendaGroupName = ""; 49 | if (agenda instanceof DefaultAgenda) { 50 | agendaGroupName = ((DefaultAgenda) agenda).getFocus().getName(); 51 | } 52 | 53 | Object global = kieRuntime.getGlobal(RuleBuildConstant.RESULT_MODEL); 54 | Rule rule = event.getMatch().getRule(); 55 | String packageName = rule.getPackageName(); 56 | String name = rule.getName(); 57 | 58 | processContext(packageName, name, agendaGroupName); 59 | 60 | FactHandle factHandle = event.getMatch().getFactHandles().get(0); 61 | String inputModel = ""; 62 | if (factHandle instanceof DefaultFactHandle) { 63 | inputModel = JackJsonUtils.writeValue(((DefaultFactHandle) factHandle).getObject()); 64 | } 65 | 66 | Map resultMap = (Map) global; 67 | resultMap.put(RuleBuildConstant.RULE_HIT_FLAG_NAME, true); 68 | String outputModel = JackJsonUtils.writeValue(global); 69 | RuleHitLogEvent logEvent = RuleHitLogEvent.builder() 70 | .ruleSetKey(packageName) 71 | .ruleKey(name) 72 | .agendaGroup(agendaGroupName) 73 | .inputModel(inputModel) 74 | .outputModel(outputModel) 75 | .requestNo(LogTraceContext.getTraceCode().orElse(IdWorker.nextStringId())) 76 | .build(); 77 | pushHitEvent(logEvent); 78 | } catch (Exception e) { 79 | log.warn("输出规则命中日志异常: ", e); 80 | } 81 | } 82 | 83 | 84 | private void processContext(String packageName, String ruleName, String agendaGroupName) { 85 | RuleProcessContextHolder.getContext().map(c -> { 86 | c.setHit(true); 87 | return c; 88 | }) 89 | .map(RuleProcessContext::getProcessRuleSetMap) 90 | .map(map -> map.get(packageName)) 91 | .map(RuleProcessContext.ProcessRuleSet::getProcessRuleMap) 92 | .map(map -> map.get(ruleName)) 93 | .ifPresent(rule -> { 94 | rule.setHit(true); 95 | rule.setAgendaGroup(agendaGroupName); 96 | }); 97 | 98 | } 99 | 100 | private void pushHitEvent(RuleHitLogEvent event) { 101 | EXECUTOR.execute(() -> applicationContext.publishEvent(event)); 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/support/MultipleConditionBuilder.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.support; 2 | 3 | import com.weweibuy.brms.model.po.Model; 4 | import com.weweibuy.brms.model.po.ModelAttr; 5 | import com.weweibuy.brms.model.po.RuleCondition; 6 | import com.weweibuy.brms.repository.ModelAndAttrRepository; 7 | import com.weweibuy.framework.common.core.exception.Exceptions; 8 | import lombok.RequiredArgsConstructor; 9 | import org.apache.commons.lang3.StringUtils; 10 | import org.drools.template.model.Condition; 11 | import org.drools.template.model.Package; 12 | import org.springframework.stereotype.Component; 13 | 14 | import java.util.ArrayList; 15 | import java.util.Comparator; 16 | import java.util.List; 17 | import java.util.stream.Collectors; 18 | 19 | /** 20 | * @author durenhao 21 | * @date 2020/11/14 10:13 22 | **/ 23 | @Component 24 | @RequiredArgsConstructor 25 | public class MultipleConditionBuilder { 26 | 27 | private final List conditionBuilderList; 28 | 29 | private final ModelAndAttrRepository modelAndAttrRepository; 30 | 31 | public Condition buildCondition(Package rulePackage, List ruleConditionList, String modelKey) { 32 | Condition condition = new Condition(); 33 | StringBuilder stringBuilder = new StringBuilder(); 34 | List paramList = new ArrayList<>(); 35 | ruleConditionList = ruleConditionList.stream() 36 | .sorted(Comparator.comparing(RuleCondition::getConditionOrder)) 37 | .collect(Collectors.toList()); 38 | for (int i = 0; i < ruleConditionList.size(); i++) { 39 | RuleCondition ruleCondition = ruleConditionList.get(i); 40 | // TODO 对象类型的支持 41 | String attrName = ruleCondition.getAttrName(); 42 | ModelAttr modelAttr = null; 43 | boolean nesting = false; 44 | String[] attrArr = null; 45 | if (attrName.indexOf('.') != -1) { 46 | // 对象类型 47 | attrArr = attrName.split("\\."); 48 | if (attrArr.length == 1) { 49 | throw Exceptions.business("对象类型属性错误"); 50 | } 51 | 52 | modelAttr = lastModelAttr(attrArr, modelKey, 0); 53 | nesting = true; 54 | } else { 55 | modelAttr = modelAttr(attrName, modelKey); 56 | } 57 | ConditionBuildContext context = ConditionBuildContext.builder() 58 | .maxIndex(ruleConditionList.size() - 1) 59 | .conditionIndex(i) 60 | .modelAttr(modelAttr) 61 | .oriConditionAttrName(attrName) 62 | .oriConditionAttrArr(attrArr) 63 | .nesting(nesting) 64 | .paramList(paramList) 65 | .build(); 66 | stringBuilder.append(matchAndBuild(rulePackage, ruleCondition, context)); 67 | 68 | if (StringUtils.isNotBlank(ruleCondition.getLogicalOperator()) && i < ruleConditionList.size() - 1) { 69 | stringBuilder.append(" ") 70 | .append(ruleCondition.getLogicalOperator()) 71 | .append(" "); 72 | } 73 | } 74 | String conditionStr = DrlBuildSupport.buildConditionStr(stringBuilder.toString(), paramList.stream().collect(Collectors.joining(","))); 75 | condition.setSnippet(conditionStr); 76 | return condition; 77 | } 78 | 79 | private String matchAndBuild(Package rulePackage, RuleCondition ruleCondition, ConditionBuildContext conditionBuildContext) { 80 | return conditionBuilderList.stream() 81 | .filter(c -> c.match(ruleCondition, conditionBuildContext.getModelAttr())) 82 | .findFirst() 83 | .map(c -> c.buildConditionStr(rulePackage, ruleCondition, conditionBuildContext)) 84 | .orElseThrow(() -> Exceptions.business("无法匹配对应的规则构建器")); 85 | } 86 | 87 | public ModelAttr modelAttr(String attrName, String modelKey) { 88 | return modelAndAttrRepository.selectModelAttr(modelKey, attrName) 89 | .orElseThrow(() -> Exceptions.business(String.format("模型: %s, 属性 %s 不存在", modelKey, attrName))); 90 | } 91 | 92 | private ModelAttr lastModelAttr(String[] split, String modelKey, int index) { 93 | if (index == split.length - 1) { 94 | return modelAttr(split[index], modelKey); 95 | } else { 96 | ModelAttr modelAttr = modelAttr(split[index], modelKey); 97 | String attrModelKeyRef = modelAttr.getAttrModelKeyRef(); 98 | String key = modelAndAttrRepository.selectModel(attrModelKeyRef) 99 | .map(Model::getModelKey) 100 | .orElseThrow(() -> Exceptions.business(String.format("模型: %s, 不存在", attrModelKeyRef))); 101 | return lastModelAttr(split, key, ++index); 102 | } 103 | 104 | } 105 | 106 | 107 | } 108 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/service/RuleExecService.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.service; 2 | 3 | import com.weweibuy.brms.api.model.constant.RuleBuildConstant; 4 | import com.weweibuy.brms.api.model.dto.RuleExecReqDTO; 5 | import com.weweibuy.brms.api.model.dto.RuleExecRespDTO; 6 | import com.weweibuy.brms.api.model.eum.ModelTypeEum; 7 | import com.weweibuy.brms.api.model.eum.MultipleRuleSetExecModelStrategyEum; 8 | import com.weweibuy.brms.drools.RuleLogEventListener; 9 | import com.weweibuy.brms.manager.RuleQueryManager; 10 | import com.weweibuy.brms.model.context.RuleProcessContext; 11 | import com.weweibuy.brms.model.po.ModelAttr; 12 | import com.weweibuy.brms.support.KieBaseHolder; 13 | import com.weweibuy.brms.support.RuleModelHelper; 14 | import com.weweibuy.brms.support.RuleProcessContextHolder; 15 | import com.weweibuy.framework.common.core.exception.Exceptions; 16 | import lombok.RequiredArgsConstructor; 17 | import org.apache.commons.collections4.CollectionUtils; 18 | import org.apache.commons.lang3.StringUtils; 19 | import org.kie.api.KieBase; 20 | import org.kie.api.runtime.KieSession; 21 | import org.springframework.stereotype.Service; 22 | 23 | import java.util.HashMap; 24 | import java.util.List; 25 | import java.util.Map; 26 | import java.util.Set; 27 | 28 | /** 29 | * 规则执行服务 30 | * 31 | * @author durenhao 32 | * @date 2020/11/8 20:45 33 | **/ 34 | @Service 35 | @RequiredArgsConstructor 36 | public class RuleExecService { 37 | 38 | private final KieBaseHolder kieBaseHolder; 39 | 40 | private final RuleLogEventListener ruleLogEventListener; 41 | 42 | private final RuleQueryManager ruleQueryManager; 43 | 44 | private final RuleModelHelper ruleModelHelper; 45 | 46 | /** 47 | * 执行规则 48 | * 49 | * @param reqDTO 50 | * @return 51 | */ 52 | public Map doExecRule(RuleExecReqDTO reqDTO) { 53 | List ruleSet = reqDTO.getRuleSet(); 54 | MultipleRuleSetExecModelStrategyEum modelStrategy = reqDTO.getModelStrategy(); 55 | 56 | Map resultMap = reqDTO.getModel(); 57 | for (RuleExecReqDTO.RuleSetKeyReqDTO ruleSetKeyReqDTO : ruleSet) { 58 | List modelAttrList = ruleQueryManager.queryModelAttr(ruleSetKeyReqDTO.getRuleSetKey(), ModelTypeEum.INPUT) 59 | .orElseThrow(() -> Exceptions.business("规则模型不存在")); 60 | // fix 属性 对不存在的属性赋空值 61 | ruleModelHelper.fixModel(resultMap, modelAttrList); 62 | // 执行规则 63 | resultMap = doExecRule(ruleSetKeyReqDTO.getRuleSetKey(), ruleSetKeyReqDTO.getRuleNameList(), 64 | ruleSetKeyReqDTO.getAgendaGroup(), resultMap); 65 | // 没有命中规则 则跳出 66 | if (!(Boolean) resultMap.get(RuleBuildConstant.RULE_HIT_FLAG_NAME)) { 67 | break; 68 | } 69 | } 70 | return resultMap; 71 | } 72 | 73 | 74 | /** 75 | * 执行规则 76 | * 77 | * @param reqDTO 78 | * @return 79 | */ 80 | public RuleExecRespDTO execRule(RuleExecReqDTO reqDTO) { 81 | RuleProcessContext ruleProcessContext = ruleModelHelper.newProcessContext(reqDTO); 82 | RuleProcessContextHolder.putContext(ruleProcessContext); 83 | try { 84 | Map execRule = doExecRule(reqDTO); 85 | // ruleProcessContext 86 | return ruleProcessContext.toRuleExecRespDTO(execRule); 87 | } finally { 88 | RuleProcessContextHolder.clearContext(); 89 | } 90 | } 91 | 92 | 93 | /** 94 | * 执行规则 95 | * 96 | * @param ruleSetKey 97 | * @param ruleNameList 98 | * @param agendaGroup 99 | * @param model 100 | * @return 101 | */ 102 | public Map doExecRule(String ruleSetKey, Set ruleNameList, String agendaGroup, 103 | Map model) { 104 | KieBase kieBase = kieBaseHolder.findKieBase(ruleSetKey); 105 | KieSession kieSession = kieBase.newKieSession(); 106 | try { 107 | // 日志监听 108 | kieSession.addEventListener(ruleLogEventListener); 109 | Map result = new HashMap<>(); 110 | result.put(RuleBuildConstant.RULE_HIT_FLAG_NAME, false); 111 | kieSession.setGlobal(RuleBuildConstant.RESULT_MODEL, result); 112 | if (StringUtils.isNotBlank(agendaGroup)) { 113 | kieSession.getAgenda().getAgendaGroup(agendaGroup).setFocus(); 114 | } 115 | kieSession.insert(model); 116 | if (CollectionUtils.isNotEmpty(ruleNameList)) { 117 | kieSession.fireAllRules(match -> ruleNameList.contains(match.getRule().getName())); 118 | } else { 119 | kieSession.fireAllRules(); 120 | } 121 | return result; 122 | } finally { 123 | kieSession.dispose(); 124 | } 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/utils/DroolsCalculateUtils.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.utils; 2 | 3 | import com.ql.util.express.DefaultContext; 4 | import com.ql.util.express.ExpressRunner; 5 | import com.weweibuy.brms.api.model.constant.RuleBuildConstant; 6 | import com.weweibuy.framework.common.core.exception.Exceptions; 7 | import lombok.AccessLevel; 8 | import lombok.NoArgsConstructor; 9 | import org.apache.commons.collections4.CollectionUtils; 10 | import org.apache.commons.lang3.StringUtils; 11 | import org.scijava.parsington.ExpressionParser; 12 | import org.scijava.parsington.Variable; 13 | import org.scijava.parsington.eval.DefaultEvaluator; 14 | 15 | import java.math.BigDecimal; 16 | import java.math.RoundingMode; 17 | import java.util.*; 18 | import java.util.stream.Collectors; 19 | 20 | /** 21 | * 计算工具 22 | * 23 | * @author durenhao 24 | * @date 2020/11/30 22:12 25 | **/ 26 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 27 | public class DroolsCalculateUtils { 28 | 29 | /** 30 | * 计算 31 | * 32 | * @param model 模型 33 | * @param formula 计算公式 34 | * @param scale 保留位数 35 | * @return 36 | */ 37 | public static Number calculate(Map model, String formula, Integer scale, String roundingMode) { 38 | 39 | if (StringUtils.isBlank(formula)) { 40 | throw Exceptions.business("计算公式错误"); 41 | } 42 | 43 | ExpressRunner expressRunner = new ExpressRunner(); 44 | DefaultContext context = new DefaultContext(); 45 | context.putAll(model); 46 | 47 | Object result = qlExpressCalculate(model, formula); 48 | 49 | BigDecimal bigDecimal = new BigDecimal(result.toString()); 50 | if (scale != null && StringUtils.isNotBlank(roundingMode)) { 51 | bigDecimal = bigDecimal.setScale(scale, RoundingMode.valueOf(roundingMode)); 52 | } 53 | return bigDecimal; 54 | } 55 | 56 | /** 57 | * QLExpress 计算 58 | * https://github.com/alibaba/QLExpress 59 | * 60 | * @param model 61 | * @param formula 62 | * @return 63 | */ 64 | public static Object qlExpressCalculate(Map model, String formula) { 65 | ExpressRunner expressRunner = new ExpressRunner(); 66 | DefaultContext context = new DefaultContext<>(); 67 | context.putAll(model); 68 | 69 | try { 70 | return expressRunner.execute(formula, context, null, true, false); 71 | } catch (Exception e) { 72 | throw Exceptions.formatBusiness("计算公式: %s, 错误: %s", formula, e.getMessage()); 73 | } 74 | } 75 | 76 | /** 77 | * 使用 scijava 进行计算 78 | * https://github.com/scijava/parsington 79 | * 80 | * @return 81 | */ 82 | public static Object scijavaCalculate(Map model, String formula) { 83 | ExpressionParser expressionParser = new ExpressionParser(); 84 | DefaultEvaluator evaluator = new DefaultEvaluator(expressionParser); 85 | LinkedList objects = expressionParser.parsePostfix(formula); 86 | 87 | List variableNameList = objects.stream() 88 | .filter(o -> o instanceof Variable) 89 | .map(o -> (Variable) o) 90 | .collect(Collectors.toList()); 91 | 92 | if (CollectionUtils.isNotEmpty(variableNameList)) { 93 | variableNameList.forEach(name -> 94 | evaluator.set(name, getValue(name.getToken(), model))); 95 | } 96 | try { 97 | return evaluator.evaluate(objects); 98 | } catch (Exception e) { 99 | throw Exceptions.formatBusiness("计算公式: %s, 错误: %s", formula, e.getMessage()); 100 | } 101 | } 102 | 103 | 104 | private static Number getValue(String name, Map model) { 105 | return getValueFromMap(name, model) 106 | .map(Object::toString) 107 | .map(Double::valueOf) 108 | .orElseThrow(() -> Exceptions.formatBusiness("计算属性: %s 不存在或对应值错误", name)); 109 | } 110 | 111 | private static Optional getValueFromMap(String name, Map model) { 112 | if (name.indexOf(RuleBuildConstant.FORMULA_ATTR_SEPARATOR) == -1) { 113 | return Optional.ofNullable(model.get(name)); 114 | } 115 | 116 | String[] nameArr = name.split(RuleBuildConstant.FORMULA_ATTR_SEPARATOR); 117 | Object value = null; 118 | for (int i = 0; i < nameArr.length; i++) { 119 | value = model.get(nameArr[i]); 120 | if (i != nameArr.length - 1) { 121 | if (!(value instanceof Map)) { 122 | throw Exceptions.formatBusiness("计算属性: %s 中 %s 不存在或对应值错误", name, nameArr[i]); 123 | } 124 | model = (Map) value; 125 | } 126 | } 127 | return Optional.ofNullable(value); 128 | 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/support/ActionBuilder.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.support; 2 | 3 | import com.weweibuy.brms.api.model.constant.RuleBuildConstant; 4 | import com.weweibuy.brms.api.model.eum.ModelAttrTypeEum; 5 | import com.weweibuy.brms.api.model.eum.RuleActionValueTypeEum; 6 | import com.weweibuy.brms.model.po.ModelAttr; 7 | import com.weweibuy.brms.model.po.RuleAction; 8 | import com.weweibuy.brms.repository.ModelAndAttrRepository; 9 | import com.weweibuy.framework.common.core.exception.Exceptions; 10 | import com.weweibuy.framework.common.core.utils.DateTimeUtils; 11 | import lombok.RequiredArgsConstructor; 12 | import org.apache.commons.lang3.StringUtils; 13 | import org.drools.decisiontable.parser.ActionType; 14 | import org.drools.decisiontable.parser.RhsBuilder; 15 | import org.drools.template.model.Consequence; 16 | import org.drools.template.model.Import; 17 | import org.drools.template.model.Package; 18 | import org.springframework.stereotype.Component; 19 | 20 | import java.math.RoundingMode; 21 | import java.util.List; 22 | import java.util.Optional; 23 | 24 | /** 25 | * @author durenhao 26 | * @date 2020/11/14 11:14 27 | **/ 28 | @Component 29 | @RequiredArgsConstructor 30 | public class ActionBuilder { 31 | 32 | private final ModelAndAttrRepository modelAndAttrRepository; 33 | 34 | public Consequence buildRuleAction(Package rulePackage, String outputModelKey, RuleAction ruleAction) { 35 | RhsBuilder rhsBuilder = new RhsBuilder(ActionType.Code.ACTION, 0, 0, null); 36 | Consequence consequence = new Consequence(); 37 | 38 | String attrKey = ruleAction.getAttrName(); 39 | 40 | RuleActionValueTypeEum valueType = RuleActionValueTypeEum.valueOf(ruleAction.getActionValueType()); 41 | String paramStr = null; 42 | switch (valueType) { 43 | case INPUT: 44 | paramStr = paramInputStr(rulePackage, outputModelKey, attrKey, ruleAction.getActionValue()); 45 | break; 46 | case CALCULATE: 47 | paramStr = paramCalculateStr(rulePackage, outputModelKey, ruleAction); 48 | break; 49 | default: 50 | throw Exceptions.formatBusiness("不支持的规则动作值类型: %s", valueType); 51 | } 52 | 53 | 54 | String resultModelPut = RuleBuildConstant.RESULT_MODEL_PUT; 55 | rhsBuilder.addTemplate(0, 0, resultModelPut); 56 | rhsBuilder.addCellValue(0, 0, DrlBuildSupport.formatString(attrKey) + "," + paramStr); 57 | consequence.setSnippet(rhsBuilder.getResult()); 58 | return consequence; 59 | } 60 | 61 | 62 | private String paramCalculateStr(Package rulePackage, String outputModelKey, RuleAction ruleAction) { 63 | String formula = ruleAction.getValueCalculateFormula(); 64 | Integer scale = ruleAction.getCalculateScale(); 65 | String roundingMode = Optional.ofNullable(ruleAction.getCalculateRoundingMode()) 66 | .filter(StringUtils::isNotBlank) 67 | .orElse(RoundingMode.HALF_UP.toString()); 68 | String calculateUtilsMethod = RuleBuildConstant.CALCULATE_UTILS_METHOD; 69 | 70 | addImportNecessary(rulePackage, RuleBuildConstant.CALCULATE_UTILS); 71 | formula = DrlBuildSupport.formatString(formula); 72 | roundingMode = DrlBuildSupport.formatString(roundingMode); 73 | return String.format(calculateUtilsMethod, RuleBuildConstant.MODEL, formula, scale, roundingMode); 74 | } 75 | 76 | 77 | private String paramInputStr(Package rulePackage, String modelKey, String attrName, String attrValue) { 78 | ModelAttr modelAttr = modelAndAttrRepository.selectModelAttr(modelKey, attrName) 79 | .orElseThrow(() -> Exceptions.business(String.format("模型: %s, 属性 %s 不存在", modelKey, attrName))); 80 | String attrType = modelAttr.getAttrType(); 81 | 82 | ModelAttrTypeEum modelAttrTypeEum = ModelAttrTypeEum.valueOf(attrType); 83 | switch (modelAttrTypeEum) { 84 | case NUMBER: 85 | return attrValue; 86 | case STRING: 87 | return DrlBuildSupport.formatString(attrValue); 88 | case DATE_DAY: 89 | return DateTimeUtils.strDateToMilli(attrValue) + ""; 90 | case DATE_SECOND: 91 | return DateTimeUtils.strDateTimeToMilli(attrValue) + ""; 92 | case BOOLEAN: 93 | return attrValue; 94 | case COLLECTION_NUMBER: 95 | case COLLECTION_STRING: 96 | addImportNecessary(rulePackage, RuleBuildConstant.COLLECTION_UTILS); 97 | return DrlBuildSupport.formatActionCollection(attrValue); 98 | default: 99 | } 100 | return attrValue; 101 | } 102 | 103 | 104 | private void addImportNecessary(Package rulePackage, String importClazzName) { 105 | List importList = rulePackage.getImports(); 106 | boolean b = importList.stream() 107 | .anyMatch(i -> i.getClassName().equals(importClazzName)); 108 | if (!b) { 109 | Import anImport = new Import(); 110 | anImport.setClassName(importClazzName); 111 | rulePackage.addImport(anImport); 112 | } 113 | } 114 | 115 | 116 | } 117 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/support/CollectionConditionBuilder.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.support; 2 | 3 | import com.weweibuy.brms.api.model.constant.RuleBuildConstant; 4 | import com.weweibuy.brms.api.model.eum.ModelAttrTypeEum; 5 | import com.weweibuy.brms.api.model.eum.OperatorEum; 6 | import com.weweibuy.brms.model.po.ModelAttr; 7 | import com.weweibuy.brms.model.po.RuleCondition; 8 | import com.weweibuy.framework.common.core.exception.Exceptions; 9 | import org.drools.template.model.Import; 10 | import org.drools.template.model.Package; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * @author durenhao 17 | * @date 2020/11/13 23:00 18 | **/ 19 | @Component 20 | public class CollectionConditionBuilder implements ConditionBuilder { 21 | 22 | @Override 23 | public boolean match(RuleCondition ruleCondition, ModelAttr modelAttr) { 24 | ModelAttrTypeEum modelAttrTypeEum = ModelAttrTypeEum.valueOf(modelAttr.getAttrType()); 25 | return ModelAttrTypeEum.COLLECTION_NUMBER.equals(modelAttrTypeEum) || ModelAttrTypeEum.COLLECTION_STRING.equals(modelAttrTypeEum); 26 | } 27 | 28 | 29 | @Override 30 | public String buildConditionStr(Package rulePackage, RuleCondition ruleCondition, ConditionBuildContext conditionBuildContext) { 31 | ModelAttr modelAttr = conditionBuildContext.getModelAttr(); 32 | List paramList = conditionBuildContext.getParamList(); 33 | String attrName = modelAttr.getAttrName(); 34 | 35 | String conditionOperator = ruleCondition.getConditionOperator(); 36 | OperatorEum operatorEum = OperatorEum.operatorEum(conditionOperator) 37 | .orElseThrow(() -> Exceptions.business(conditionOperator + " :对应的操作不存在")); 38 | String template = null; 39 | int index = conditionBuildContext.getConditionIndex(); 40 | switch (operatorEum) { 41 | case ALL_MEMBER_OF: 42 | template = String.format("DroolsCollectionUtils.allMemberOf(%s, $%s)", attrName, index + 1); 43 | addCollectionImportNecessary(rulePackage); 44 | break; 45 | case NOT_ALL_MEMBER_OF: 46 | template = String.format("!DroolsCollectionUtils.allMemberOf(%s, $%s)", attrName, index + 1); 47 | addCollectionImportNecessary(rulePackage); 48 | break; 49 | case CONTAINS_ALL: 50 | template = String.format("DroolsCollectionUtils.containsAll(%s, $%s)", attrName, index + 1); 51 | addCollectionImportNecessary(rulePackage); 52 | break; 53 | case NTO_CONTAINS_ALL: 54 | template = String.format("!DroolsCollectionUtils.containsAll(%s, $%s)", attrName, index + 1); 55 | addCollectionImportNecessary(rulePackage); 56 | break; 57 | default: 58 | template = String.format("%s %s $%s", attrName, ruleCondition.getConditionOperator(), index + 1); 59 | } 60 | 61 | if (conditionBuildContext.getNesting()) { 62 | String[] oriConditionAttrArr = conditionBuildContext.getOriConditionAttrArr(); 63 | String nestingConditionStr = DrlBuildSupport.buildNestingConditionStr(oriConditionAttrArr); 64 | // 对象类型 user.dept in $1 --> (user != null && user.dept in $1) 65 | template = String.format("%s && %s", nestingConditionStr, template); 66 | } 67 | if (conditionBuildContext.getMaxIndex() != 0) { 68 | template = "(" + template + ")"; 69 | } 70 | 71 | paramList.add(paramStr(ruleCondition, modelAttr)); 72 | return template; 73 | } 74 | 75 | private String paramStr(RuleCondition ruleCondition, ModelAttr modelAttr) { 76 | String conditionOperator = ruleCondition.getConditionOperator(); 77 | String attrValue = ruleCondition.getConditionValue(); 78 | String attrType = modelAttr.getAttrType(); 79 | 80 | OperatorEum operatorEum = OperatorEum.operatorEum(conditionOperator) 81 | .orElseThrow(() -> Exceptions.business(conditionOperator + " :对应的操作不存在")); 82 | ModelAttrTypeEum modelAttrTypeEum = ModelAttrTypeEum.valueOf(modelAttr.getAttrType()); 83 | 84 | switch (operatorEum) { 85 | case CONTAINS_ALL: 86 | case NTO_CONTAINS_ALL: 87 | case ALL_MEMBER_OF: 88 | case NOT_ALL_MEMBER_OF: 89 | if (ModelAttrTypeEum.COLLECTION_NUMBER.equals(modelAttrTypeEum)) { 90 | return DrlBuildSupport.formatNumberCollection(attrValue); 91 | } 92 | if (ModelAttrTypeEum.COLLECTION_STRING.equals(modelAttrTypeEum)) { 93 | return DrlBuildSupport.formatStringCollection(attrValue); 94 | } 95 | throw Exceptions.business(String.format("操作符: %s, 不支持的数据类型: %s", operatorEum, modelAttrTypeEum)); 96 | default: 97 | if (ModelAttrTypeEum.COLLECTION_STRING.equals(modelAttrTypeEum)) { 98 | return DrlBuildSupport.formatString(attrValue); 99 | } 100 | return attrValue; 101 | } 102 | } 103 | 104 | private void addCollectionImportNecessary(Package rulePackage) { 105 | List importList = rulePackage.getImports(); 106 | boolean b = importList.stream() 107 | .anyMatch(i -> i.getClassName().equals(RuleBuildConstant.COLLECTION_UTILS)); 108 | if (!b) { 109 | Import anImport = new Import(); 110 | anImport.setClassName(RuleBuildConstant.COLLECTION_UTILS); 111 | rulePackage.addImport(anImport); 112 | } 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /brms-service/src/main/resources/generator/generatorConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 42 | 43 | 44 | 45 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 63 | 64 | 65 | 66 | 67 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 |
79 | 80 | 81 | 82 |
83 | 84 | 85 | 86 |
87 | 88 | 89 | 90 | 91 |
92 | 93 | 94 | 95 |
96 | 97 | 98 | 99 |
100 | 101 | 102 | 103 |
104 | 105 | 106 | 107 |
108 | 109 | 110 | 111 |
112 | 113 |
114 |
115 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.weweibuy 8 | brms 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | brms-api 13 | brms-service 14 | 15 | 16 | 17 | UTF-8 18 | 1.8 19 | 1.8 20 | 1.2-SNAPSHOT 21 | 1.3.2 22 | 1.3.7 23 | 7.44.0.Final 24 | 2.0.0 25 | 26 | 27 | 28 | 29 | 30 | 31 | com.weweibuy.framework 32 | weweibuy-framework 33 | ${weweibuy-framework.version} 34 | pom 35 | import 36 | 37 | 38 | 39 | com.weweibuy 40 | brms-service 41 | ${project.version} 42 | 43 | 44 | 45 | com.weweibuy 46 | brms-api 47 | ${project.version} 48 | 49 | 50 | 51 | org.scijava 52 | parsington 53 | ${scijava.parsington.version} 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | org.springframework.boot 67 | spring-boot-starter-test 68 | test 69 | 70 | 71 | org.junit.jupiter 72 | junit-jupiter 73 | 74 | 75 | org.junit.vintage 76 | junit-vintage-engine 77 | 78 | 79 | org.mockito 80 | mockito-junit-jupiter 81 | 82 | 83 | 84 | 85 | 86 | junit 87 | junit 88 | test 89 | 90 | 91 | 92 | org.projectlombok 93 | lombok 94 | provided 95 | 96 | 97 | 98 | 99 | 100 | 101 | dev 102 | 103 | true 104 | 105 | 106 | dev 107 | 108 | 109 | 110 | 111 | 112 | org.mybatis.generator 113 | mybatis-generator-maven-plugin 114 | ${mybatis-generator-maven-plugin.version} 115 | 116 | true 117 | true 118 | src/main/resources/generator/generatorConfig.xml 119 | 120 | 121 | 122 | mysql 123 | mysql-connector-java 124 | 8.0.16 125 | 126 | 127 | 128 | com.weweibuy.framework 129 | mybatis-plugin 130 | ${weweibuy-framework.version} 131 | 132 | 133 | 134 | com.itfsw 135 | mybatis-generator-plugin 136 | ${itfsw-mybatis-generator-plugin.version} 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | rel 148 | 149 | rel 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/manager/RuleBuildManager.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.manager; 2 | 3 | import com.weweibuy.brms.api.model.constant.RuleBuildConstant; 4 | import com.weweibuy.brms.api.model.eum.ModelTypeEum; 5 | import com.weweibuy.brms.api.model.eum.RuleEnterTypeEum; 6 | import com.weweibuy.brms.model.po.Rule; 7 | import com.weweibuy.brms.model.po.*; 8 | import com.weweibuy.brms.repository.ConditionAndActionRepository; 9 | import com.weweibuy.brms.repository.RuleAndSetRepository; 10 | import com.weweibuy.brms.repository.RuleSetModelRepository; 11 | import com.weweibuy.brms.support.ActionBuilder; 12 | import com.weweibuy.brms.support.MultipleConditionBuilder; 13 | import com.weweibuy.framework.common.core.exception.Exceptions; 14 | import lombok.RequiredArgsConstructor; 15 | import org.apache.commons.collections4.CollectionUtils; 16 | import org.apache.commons.lang3.StringUtils; 17 | import org.drools.template.model.*; 18 | import org.drools.template.model.Package; 19 | import org.springframework.stereotype.Component; 20 | 21 | import java.util.Arrays; 22 | import java.util.List; 23 | import java.util.Objects; 24 | import java.util.Set; 25 | import java.util.stream.Collectors; 26 | 27 | /** 28 | * @author durenhao 29 | * @date 2020/11/8 21:19 30 | **/ 31 | @Component 32 | @RequiredArgsConstructor 33 | public class RuleBuildManager { 34 | 35 | private final ConditionAndActionRepository conditionAndActionRepository; 36 | 37 | private final RuleAndSetRepository ruleAndSetRepository; 38 | 39 | private final RuleSetModelRepository ruleSetModelRepository; 40 | 41 | private final MultipleConditionBuilder multipleConditionBuilder; 42 | 43 | private final ActionBuilder actionBuilder; 44 | 45 | 46 | /** 47 | * 构建规则集 string 48 | * 49 | * @param ruleSetKey 50 | * @return 51 | */ 52 | public String buildRuleStr(String ruleSetKey) { 53 | RuleSet ruleSet = ruleAndSetRepository.selectRuleSet(ruleSetKey) 54 | .orElseThrow(() -> Exceptions.business(String.format("规则集: %s不存在", ruleSetKey))); 55 | 56 | List ruleSetModel = ruleSetModelRepository.selectRuleSetModel(ruleSetKey); 57 | RuleSetModel inputRuleSetModel = ruleSetModel.stream() 58 | .filter(rm -> ModelTypeEum.INPUT.toString().equals(rm.getModelType())) 59 | .findFirst() 60 | .orElseThrow(() -> Exceptions.business(String.format("规则集: %s对应的输入模型不存在", ruleSetKey))); 61 | 62 | 63 | RuleSetModel outputRuleSetModel = ruleSetModel.stream() 64 | .filter(rm -> ModelTypeEum.OUTPUT.toString().equals(rm.getModelType())) 65 | .findFirst() 66 | .orElseThrow(() -> Exceptions.business(String.format("规则集: %s对应的输出模型不存在", ruleSetKey))); 67 | 68 | String inputModelKey = inputRuleSetModel.getModelKey(); 69 | String outputModelKey = outputRuleSetModel.getModelKey(); 70 | 71 | Package rulePackage = new Package(ruleSetKey); 72 | 73 | Import anImport = new Import(); 74 | anImport.setClassName(RuleBuildConstant.MAP_CLAZZ); 75 | rulePackage.addImport(anImport); 76 | 77 | Global global = new Global(); 78 | global.setClassName(RuleBuildConstant.MAP_CLAZZ); 79 | global.setIdentifier(RuleBuildConstant.RESULT_MODEL); 80 | rulePackage.addVariable(global); 81 | 82 | ruleAndSetRepository.selectRule(ruleSetKey).stream() 83 | .map(rule -> buildDRule(rulePackage, rule, inputModelKey, outputModelKey)) 84 | .forEach(rulePackage::addRule); 85 | 86 | DRLOutput out = new DRLOutput(); 87 | rulePackage.renderDRL(out); 88 | return out.getDRL(); 89 | } 90 | 91 | /** 92 | * 构建规则 93 | * 94 | * @param rulePackage 95 | * @param rule 96 | * @param inputModelKey 97 | * @param outputModelKey 98 | * @return 99 | */ 100 | public org.drools.template.model.Rule buildDRule(Package rulePackage, Rule rule, String inputModelKey, String outputModelKey) { 101 | 102 | String ruleEnterType = rule.getRuleEnterType(); 103 | RuleEnterTypeEum ruleEnterTypeEum = RuleEnterTypeEum.valueOf(ruleEnterType); 104 | 105 | switch (ruleEnterTypeEum) { 106 | case CODING: 107 | return buildCodingTypeDRule(rulePackage, rule, inputModelKey); 108 | case SELECT: 109 | return buildSelectTypeDRule(rulePackage, rule, inputModelKey, outputModelKey); 110 | default: 111 | throw Exceptions.business("未知的规则录入类型" + ruleEnterTypeEum); 112 | } 113 | 114 | } 115 | 116 | /** 117 | * 代码模式 118 | * 119 | * @param rulePackage 120 | * @param rule 121 | * @param modelKey 122 | * @return 123 | */ 124 | public org.drools.template.model.Rule buildCodingTypeDRule(Package rulePackage, Rule rule, String modelKey) { 125 | org.drools.template.model.Rule dRule = newDRuleWithProperties(rule); 126 | Condition condition = new Condition(); 127 | condition.setSnippet(rule.getRuleConditionText()); 128 | Consequence consequence = new Consequence(); 129 | consequence.setSnippet(rule.getRuleActionText()); 130 | dRule.addCondition(condition); 131 | dRule.addConsequence(consequence); 132 | String ruleImportText = rule.getRuleImportText(); 133 | List imports = rulePackage.getImports(); 134 | if (StringUtils.isNotBlank(ruleImportText)) { 135 | Set importClazzSet = imports.stream() 136 | .map(Import::getClassName) 137 | .collect(Collectors.toSet()); 138 | String[] strings = ruleImportText.split(";"); 139 | Arrays.stream(strings) 140 | .filter(StringUtils::isNotBlank) 141 | .map(String::trim) 142 | .filter(str -> !importClazzSet.contains(str)) 143 | .map(str -> { 144 | Import anImport = new Import(); 145 | anImport.setClassName(str); 146 | return anImport; 147 | }) 148 | .forEach(rulePackage::addImport); 149 | } 150 | return dRule; 151 | } 152 | 153 | /** 154 | * 选择输入模式 155 | * 156 | * @param rulePackage 157 | * @param rule 158 | * @param inputModelKey 159 | * @param outputModelKey 160 | * @return 161 | */ 162 | public org.drools.template.model.Rule buildSelectTypeDRule(Package rulePackage, Rule rule, String inputModelKey, String outputModelKey) { 163 | List ruleConditionList = conditionAndActionRepository.selectRuleCondition(rule.getRuleKey()); 164 | List ruleActionList = conditionAndActionRepository.selectRuleAction(rule.getRuleKey()); 165 | org.drools.template.model.Rule dRule = newDRuleWithProperties(rule); 166 | 167 | if (CollectionUtils.isNotEmpty(ruleConditionList)) { 168 | Condition condition = buildCondition(rulePackage, ruleConditionList, inputModelKey); 169 | dRule.addCondition(condition); 170 | } 171 | 172 | ruleActionList.stream() 173 | .map(r -> buildRuleAction(rulePackage, outputModelKey, r)) 174 | .forEach(dRule::addConsequence); 175 | return dRule; 176 | } 177 | 178 | 179 | private org.drools.template.model.Rule newDRuleWithProperties(Rule rule) { 180 | org.drools.template.model.Rule dRule = new org.drools.template.model.Rule( 181 | rule.getRuleKey(), null, rule.getId().intValue()); 182 | 183 | ruleProperties(rule, dRule); 184 | return dRule; 185 | } 186 | 187 | 188 | public Condition buildCondition(Package rulePackage, List ruleConditionList, String modelKey) { 189 | return multipleConditionBuilder.buildCondition(rulePackage, ruleConditionList, modelKey); 190 | } 191 | 192 | public Consequence buildRuleAction(Package rulePackage, String outputModelKey, RuleAction ruleAction) { 193 | return actionBuilder.buildRuleAction(rulePackage, outputModelKey, ruleAction); 194 | } 195 | 196 | private void ruleProperties(Rule rule, org.drools.template.model.Rule dRule) { 197 | if (StringUtils.isNotBlank(rule.getAgendaGroup())) { 198 | dRule.setAgendaGroup(rule.getAgendaGroup()); 199 | } 200 | if (StringUtils.isNotBlank(rule.getActivationGroup())) { 201 | dRule.setActivationGroup(rule.getActivationGroup()); 202 | } 203 | if (StringUtils.isNotBlank(rule.getNoLoop())) { 204 | dRule.setNoLoop(Boolean.valueOf(rule.getNoLoop())); 205 | } 206 | if (Objects.nonNull(rule.getSalience())) { 207 | dRule.setSalience(rule.getSalience()); 208 | } 209 | if (StringUtils.isNotBlank(rule.getDateEffective())) { 210 | dRule.setDateEffective(rule.getDateEffective()); 211 | } 212 | if (StringUtils.isNotBlank(rule.getDateExpires())) { 213 | dRule.setDateExpires(rule.getDateExpires()); 214 | } 215 | } 216 | 217 | } 218 | -------------------------------------------------------------------------------- /brms-service/src/main/java/com/weweibuy/brms/service/RuleQueryService.java: -------------------------------------------------------------------------------- 1 | package com.weweibuy.brms.service; 2 | 3 | import com.github.pagehelper.Page; 4 | import com.weweibuy.brms.api.model.constant.RuleBuildConstant; 5 | import com.weweibuy.brms.api.model.dto.req.RuleHitLogReqDTO; 6 | import com.weweibuy.brms.api.model.dto.resp.*; 7 | import com.weweibuy.brms.api.model.eum.ModelTypeEum; 8 | import com.weweibuy.brms.api.model.eum.RuleActionValueTypeEum; 9 | import com.weweibuy.brms.model.example.RuleHitLogExample; 10 | import com.weweibuy.brms.model.po.*; 11 | import com.weweibuy.brms.repository.*; 12 | import com.weweibuy.brms.support.RuleTranslateHelper; 13 | import com.weweibuy.framework.common.core.exception.Exceptions; 14 | import com.weweibuy.framework.common.core.model.dto.CommonPageRequest; 15 | import com.weweibuy.framework.common.core.model.dto.CommonPageResult; 16 | import com.weweibuy.framework.common.core.utils.BeanCopyUtils; 17 | import com.weweibuy.framework.common.db.utils.PageHelperUtils; 18 | import lombok.RequiredArgsConstructor; 19 | import org.apache.commons.collections4.CollectionUtils; 20 | import org.apache.commons.lang3.StringUtils; 21 | import org.springframework.stereotype.Service; 22 | 23 | import java.util.*; 24 | import java.util.stream.Collectors; 25 | 26 | /** 27 | * 规则查询服务 28 | * 29 | * @author durenhao 30 | * @date 2021/7/23 21:47 31 | **/ 32 | @Service 33 | @RequiredArgsConstructor 34 | public class RuleQueryService { 35 | 36 | private final JdbcRuleAndSetRepositoryImpl ruleAndSetRepository; 37 | 38 | private final JdbcRuleSetModelRepositoryImpl ruleSetModelRepository; 39 | 40 | private final ConditionAndActionRepository conditionAndActionRepository; 41 | 42 | private final RuleHitLogRepository ruleHitLogRepository; 43 | 44 | private final JdbcModelAndAttrRepositoryImpl modelAndAttrRepository; 45 | 46 | private final RuleTranslateHelper ruleTranslateHelper; 47 | 48 | public CommonPageResult ruleSet(String ruleSetKey, String ruleSetName, CommonPageRequest pageRequest) { 49 | Page objectPage = PageHelperUtils.startPage(pageRequest); 50 | List dtoList = ruleAndSetRepository.selectRuleSet(ruleSetKey, ruleSetName) 51 | .stream() 52 | .map(r -> BeanCopyUtils.copy(r, RuleSetRespDTO.class)) 53 | .collect(Collectors.toList()); 54 | return CommonPageResult.withTotalAndList(objectPage.getTotal(), dtoList); 55 | } 56 | 57 | public RuleSetRespDTO ruleSet(String ruleSetKey) { 58 | return ruleAndSetRepository.selectRuleSet(ruleSetKey) 59 | .map(r -> BeanCopyUtils.copy(r, RuleSetRespDTO.class)) 60 | .orElse(null); 61 | } 62 | 63 | public CommonPageResult ruleList(String ruleSetKey, CommonPageRequest pageRequest) { 64 | Page objectPage = PageHelperUtils.startPage(pageRequest); 65 | List ruleList = ruleAndSetRepository.selectRule(ruleSetKey); 66 | List ruleRespDTOS = BeanCopyUtils.copyCollection(ruleList, Rule.class, RuleRespDTO.class); 67 | return CommonPageResult.withTotalAndList(objectPage.getTotal(), ruleRespDTOS); 68 | } 69 | 70 | public List ruleSetModel(String ruleSetKey) { 71 | List ruleSetModelList = ruleSetModelRepository.selectRuleSetModel(ruleSetKey); 72 | return BeanCopyUtils.copyCollection(ruleSetModelList, RuleSetModel.class, RuleSetModelRespDTO.class); 73 | } 74 | 75 | public List ruleCondition(String ruleKey) { 76 | List ruleConditionList = conditionAndActionRepository.selectRuleCondition(ruleKey); 77 | return BeanCopyUtils.copyCollection(ruleConditionList, RuleCondition.class, RuleConditionRespDTO.class); 78 | } 79 | 80 | public List ruleAction(String ruleKey) { 81 | List ruleConditionList = conditionAndActionRepository.selectRuleAction(ruleKey); 82 | return BeanCopyUtils.copyCollection(ruleConditionList, RuleAction.class, RuleActionRespDTO.class); 83 | 84 | } 85 | 86 | public CommonPageResult ruleHitLog(RuleHitLogReqDTO query) { 87 | Page page = PageHelperUtils.startPage(query); 88 | List logList = ruleHitLogRepository.select(toRuleHitLogExample(query)); 89 | List dtoList = BeanCopyUtils.copyCollection(logList, RuleHitLog.class, RuleHitLogRespDTO.class); 90 | return CommonPageResult.withTotalAndList(page.getTotal(), dtoList); 91 | } 92 | 93 | private RuleHitLogExample toRuleHitLogExample(RuleHitLogReqDTO query) { 94 | return Optional.ofNullable(query) 95 | .map(q -> RuleHitLogExample.newAndCreateCriteria() 96 | .andDeletedEqualTo(false) 97 | .when(StringUtils.isNotBlank(q.getRuleSetKey()), c -> c.andRuleSetKeyEqualTo(q.getRuleSetKey())) 98 | .when(StringUtils.isNotBlank(q.getRuleKey()), c -> c.andRuleKeyEqualTo(q.getRuleKey())) 99 | .when(StringUtils.isNotBlank(q.getRequestNo()), c -> c.andRequestNoEqualTo(q.getRequestNo())) 100 | .when(StringUtils.isNotBlank(q.getAgendaGroup()), c -> c.andAgendaGroupEqualTo(q.getAgendaGroup())) 101 | .when(Objects.nonNull(q.getCreateTimeFrom()), c -> c.andCreateTimeGreaterThanOrEqualTo(q.getCreateTimeFrom())) 102 | .when(Objects.nonNull(q.getCreateTimeTo()), c -> c.andCreateTimeLessThanOrEqualTo(q.getCreateTimeTo())) 103 | .example()) 104 | .orElse(null); 105 | } 106 | 107 | public List ruleSetModelAttr(String modelKey) { 108 | List modelAttrList = modelAndAttrRepository.selectModelAttrByModelKey(modelKey); 109 | return BeanCopyUtils.copyCollection(modelAttrList, ModelAttr.class, RuleModelAttrRespDTO.class); 110 | } 111 | 112 | public RuleTranslateRespDTO ruleTranslate(String ruleKey) { 113 | Rule rule = ruleAndSetRepository.selectRuleByRuleKey(ruleKey) 114 | .orElseThrow(() -> Exceptions.business("规则不存在")); 115 | List modelList = ruleSetModelRepository.selectRuleSetModel(rule.getRuleSetKey()); 116 | RuleSetModel inputModel = modelList.stream() 117 | .filter(r -> ModelTypeEum.INPUT.toString().equals(r.getModelType())) 118 | .findFirst() 119 | .orElse(null); 120 | 121 | 122 | RuleSetModel outputModel = modelList.stream() 123 | .filter(r -> ModelTypeEum.OUTPUT.toString().equals(r.getModelType())) 124 | .findFirst() 125 | .orElse(null); 126 | 127 | RuleTranslateRespDTO ruleTranslateRespDTO = new RuleTranslateRespDTO(); 128 | 129 | if (inputModel != null) { 130 | Map stringStringMap = ruleTranslateHelper.translateAttr(inputModel, RuleBuildConstant.MODEL_ATTR_SEPARATOR); 131 | 132 | List ruleConditionList = conditionAndActionRepository.selectRuleCondition(ruleKey); 133 | if (CollectionUtils.isNotEmpty(ruleConditionList)) { 134 | List collect = ruleConditionList.stream() 135 | .map(c -> { 136 | String desc = stringStringMap.get(c.getAttrName()); 137 | return desc + " " + c.getConditionOperator() + " " + c.getConditionValue(); 138 | }) 139 | .collect(Collectors.toList()); 140 | ruleTranslateRespDTO.setCondition(collect); 141 | } 142 | } 143 | 144 | if (outputModel != null) { 145 | Map stringStringMap = ruleTranslateHelper.translateAttr(outputModel, "."); 146 | 147 | Map inputMap = Optional.ofNullable(inputModel) 148 | .map(i -> ruleTranslateHelper.translateAttr(i, RuleBuildConstant.FORMULA_ATTR_SEPARATOR)) 149 | .orElse(Collections.emptyMap()); 150 | 151 | List ruleActionList = conditionAndActionRepository.selectRuleAction(ruleKey); 152 | if (CollectionUtils.isNotEmpty(ruleActionList)) { 153 | List collect = ruleActionList.stream() 154 | .map(a -> 155 | RuleActionValueTypeEum.fromValue(a.getActionValueType()) 156 | .map(t -> actionDesc(t, a, stringStringMap.get(a.getAttrName()), inputMap)) 157 | .orElse("")) 158 | .collect(Collectors.toList()); 159 | ruleTranslateRespDTO.setAction(collect); 160 | } 161 | } 162 | 163 | return ruleTranslateRespDTO; 164 | } 165 | 166 | 167 | private String actionDesc(RuleActionValueTypeEum actionValueType, RuleAction ruleAction, 168 | String attrDesc, Map inputMap) { 169 | switch (actionValueType) { 170 | case INPUT: 171 | return attrDesc + " = " + ruleAction.getActionValue(); 172 | case CALCULATE: 173 | String anElse = Optional.ofNullable(ruleAction.getValueCalculateFormula()) 174 | .map(s -> Arrays.stream(s.split(" ")) 175 | .map(String::trim) 176 | .map(i -> Optional.ofNullable(inputMap.get(i)).orElse(i)) 177 | .collect(Collectors.joining(" "))) 178 | .orElse(""); 179 | return attrDesc + " = " + anElse; 180 | default: 181 | return ""; 182 | } 183 | } 184 | 185 | public RuleRespDTO rule(String ruleKey) { 186 | return ruleAndSetRepository.selectRuleByRuleKey(ruleKey) 187 | .map(r -> BeanCopyUtils.copy(r, RuleRespDTO.class)) 188 | .orElse(null); 189 | 190 | } 191 | 192 | public ModelRespDTO model(String modelKey) { 193 | return modelAndAttrRepository.selectModel(modelKey) 194 | .map(m -> BeanCopyUtils.copy(m, ModelRespDTO.class)) 195 | .orElse(null); 196 | } 197 | 198 | } 199 | -------------------------------------------------------------------------------- /brms-service/src/main/resources/config/mybatis/mapper/ModelMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | and ${criterion.condition} 21 | 22 | 23 | and ${criterion.condition} #{criterion.value} 24 | 25 | 26 | and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} 27 | 28 | 29 | and ${criterion.condition} 30 | 31 | #{listItem} 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | and ${criterion.condition} 50 | 51 | 52 | and ${criterion.condition} #{criterion.value} 53 | 54 | 55 | and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} 56 | 57 | 58 | and ${criterion.condition} 59 | 60 | #{listItem} 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | id, model_key, model_desc, is_delete, create_time, update_time 72 | 73 | 87 | 104 | 119 | 125 | 126 | delete from brms_model 127 | where id = #{id,jdbcType=BIGINT} 128 | 129 | 130 | delete from brms_model 131 | 132 | 133 | 134 | 135 | 136 | insert into brms_model (id, model_key, model_desc, 137 | is_delete, create_time, update_time 138 | ) 139 | values (#{id,jdbcType=BIGINT}, #{modelKey,jdbcType=VARCHAR}, #{modelDesc,jdbcType=VARCHAR}, 140 | #{deleted,jdbcType=TINYINT}, #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP} 141 | ) 142 | 143 | 144 | insert into brms_model 145 | 146 | 147 | id, 148 | 149 | 150 | model_key, 151 | 152 | 153 | model_desc, 154 | 155 | 156 | is_delete, 157 | 158 | 159 | create_time, 160 | 161 | 162 | update_time, 163 | 164 | 165 | 166 | 167 | #{id,jdbcType=BIGINT}, 168 | 169 | 170 | #{modelKey,jdbcType=VARCHAR}, 171 | 172 | 173 | #{modelDesc,jdbcType=VARCHAR}, 174 | 175 | 176 | #{deleted,jdbcType=TINYINT}, 177 | 178 | 179 | #{createTime,jdbcType=TIMESTAMP}, 180 | 181 | 182 | #{updateTime,jdbcType=TIMESTAMP}, 183 | 184 | 185 | 186 | 192 | 193 | update brms_model 194 | 195 | 196 | id = #{record.id,jdbcType=BIGINT}, 197 | 198 | 199 | model_key = #{record.modelKey,jdbcType=VARCHAR}, 200 | 201 | 202 | model_desc = #{record.modelDesc,jdbcType=VARCHAR}, 203 | 204 | 205 | is_delete = #{record.deleted,jdbcType=TINYINT}, 206 | 207 | 208 | create_time = #{record.createTime,jdbcType=TIMESTAMP}, 209 | 210 | 211 | update_time = #{record.updateTime,jdbcType=TIMESTAMP}, 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | update brms_model 220 | set id = #{record.id,jdbcType=BIGINT}, 221 | model_key = #{record.modelKey,jdbcType=VARCHAR}, 222 | model_desc = #{record.modelDesc,jdbcType=VARCHAR}, 223 | is_delete = #{record.deleted,jdbcType=TINYINT}, 224 | create_time = #{record.createTime,jdbcType=TIMESTAMP}, 225 | update_time = #{record.updateTime,jdbcType=TIMESTAMP} 226 | 227 | 228 | 229 | 230 | 231 | update brms_model 232 | 233 | 234 | model_key = #{modelKey,jdbcType=VARCHAR}, 235 | 236 | 237 | model_desc = #{modelDesc,jdbcType=VARCHAR}, 238 | 239 | 240 | is_delete = #{deleted,jdbcType=TINYINT}, 241 | 242 | 243 | create_time = #{createTime,jdbcType=TIMESTAMP}, 244 | 245 | 246 | update_time = #{updateTime,jdbcType=TIMESTAMP}, 247 | 248 | 249 | where id = #{id,jdbcType=BIGINT} 250 | 251 | 252 | update brms_model 253 | set model_key = #{modelKey,jdbcType=VARCHAR}, 254 | model_desc = #{modelDesc,jdbcType=VARCHAR}, 255 | is_delete = #{deleted,jdbcType=TINYINT}, 256 | create_time = #{createTime,jdbcType=TIMESTAMP}, 257 | update_time = #{updateTime,jdbcType=TIMESTAMP} 258 | where id = #{id,jdbcType=BIGINT} 259 | 260 | 272 | 285 | -------------------------------------------------------------------------------- /brms-service/src/main/resources/config/mybatis/mapper/RuleSetMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | and ${criterion.condition} 21 | 22 | 23 | and ${criterion.condition} #{criterion.value} 24 | 25 | 26 | and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} 27 | 28 | 29 | and ${criterion.condition} 30 | 31 | #{listItem} 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | and ${criterion.condition} 50 | 51 | 52 | and ${criterion.condition} #{criterion.value} 53 | 54 | 55 | and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} 56 | 57 | 58 | and ${criterion.condition} 59 | 60 | #{listItem} 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | id, rule_set_key, rule_set_name, is_delete, create_time, update_time 72 | 73 | 87 | 104 | 119 | 125 | 126 | delete from brms_rule_set 127 | where id = #{id,jdbcType=BIGINT} 128 | 129 | 130 | delete from brms_rule_set 131 | 132 | 133 | 134 | 135 | 136 | insert into brms_rule_set (id, rule_set_key, rule_set_name, 137 | is_delete, create_time, update_time 138 | ) 139 | values (#{id,jdbcType=BIGINT}, #{ruleSetKey,jdbcType=VARCHAR}, #{ruleSetName,jdbcType=VARCHAR}, 140 | #{deleted,jdbcType=BIT}, #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP} 141 | ) 142 | 143 | 144 | insert into brms_rule_set 145 | 146 | 147 | id, 148 | 149 | 150 | rule_set_key, 151 | 152 | 153 | rule_set_name, 154 | 155 | 156 | is_delete, 157 | 158 | 159 | create_time, 160 | 161 | 162 | update_time, 163 | 164 | 165 | 166 | 167 | #{id,jdbcType=BIGINT}, 168 | 169 | 170 | #{ruleSetKey,jdbcType=VARCHAR}, 171 | 172 | 173 | #{ruleSetName,jdbcType=VARCHAR}, 174 | 175 | 176 | #{deleted,jdbcType=BIT}, 177 | 178 | 179 | #{createTime,jdbcType=TIMESTAMP}, 180 | 181 | 182 | #{updateTime,jdbcType=TIMESTAMP}, 183 | 184 | 185 | 186 | 192 | 193 | update brms_rule_set 194 | 195 | 196 | id = #{record.id,jdbcType=BIGINT}, 197 | 198 | 199 | rule_set_key = #{record.ruleSetKey,jdbcType=VARCHAR}, 200 | 201 | 202 | rule_set_name = #{record.ruleSetName,jdbcType=VARCHAR}, 203 | 204 | 205 | is_delete = #{record.deleted,jdbcType=BIT}, 206 | 207 | 208 | create_time = #{record.createTime,jdbcType=TIMESTAMP}, 209 | 210 | 211 | update_time = #{record.updateTime,jdbcType=TIMESTAMP}, 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | update brms_rule_set 220 | set id = #{record.id,jdbcType=BIGINT}, 221 | rule_set_key = #{record.ruleSetKey,jdbcType=VARCHAR}, 222 | rule_set_name = #{record.ruleSetName,jdbcType=VARCHAR}, 223 | is_delete = #{record.deleted,jdbcType=BIT}, 224 | create_time = #{record.createTime,jdbcType=TIMESTAMP}, 225 | update_time = #{record.updateTime,jdbcType=TIMESTAMP} 226 | 227 | 228 | 229 | 230 | 231 | update brms_rule_set 232 | 233 | 234 | rule_set_key = #{ruleSetKey,jdbcType=VARCHAR}, 235 | 236 | 237 | rule_set_name = #{ruleSetName,jdbcType=VARCHAR}, 238 | 239 | 240 | is_delete = #{deleted,jdbcType=BIT}, 241 | 242 | 243 | create_time = #{createTime,jdbcType=TIMESTAMP}, 244 | 245 | 246 | update_time = #{updateTime,jdbcType=TIMESTAMP}, 247 | 248 | 249 | where id = #{id,jdbcType=BIGINT} 250 | 251 | 252 | update brms_rule_set 253 | set rule_set_key = #{ruleSetKey,jdbcType=VARCHAR}, 254 | rule_set_name = #{ruleSetName,jdbcType=VARCHAR}, 255 | is_delete = #{deleted,jdbcType=BIT}, 256 | create_time = #{createTime,jdbcType=TIMESTAMP}, 257 | update_time = #{updateTime,jdbcType=TIMESTAMP} 258 | where id = #{id,jdbcType=BIGINT} 259 | 260 | 272 | 285 | -------------------------------------------------------------------------------- /doc/sql/DDL.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat Premium Data Transfer 3 | 4 | Source Server : BD_Mysql 5 | Source Server Type : MySQL 6 | Source Server Version : 50622 7 | Source Host : 106.12.208.53:3306 8 | Source Schema : webuy_brms 9 | 10 | Target Server Type : MySQL 11 | Target Server Version : 50622 12 | File Encoding : 65001 13 | 14 | Date: 27/04/2021 23:20:35 15 | */ 16 | 17 | SET NAMES utf8mb4; 18 | SET FOREIGN_KEY_CHECKS = 0; 19 | 20 | -- ---------------------------- 21 | -- Table structure for brms_model 22 | -- ---------------------------- 23 | DROP TABLE IF EXISTS `brms_model`; 24 | CREATE TABLE `brms_model` ( 25 | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id自增1', 26 | `model_key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模型key', 27 | `model_desc` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '模型描述', 28 | `is_delete` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否删除', 29 | `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', 30 | `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', 31 | PRIMARY KEY (`id`) USING BTREE, 32 | UNIQUE INDEX `uk_model_key`(`model_key`) USING BTREE 33 | ) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '模型表' ROW_FORMAT = Compact; 34 | 35 | -- ---------------------------- 36 | -- Table structure for brms_model_attr 37 | -- ---------------------------- 38 | DROP TABLE IF EXISTS `brms_model_attr`; 39 | CREATE TABLE `brms_model_attr` ( 40 | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id自增1', 41 | `model_key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模型key', 42 | `attr_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '属性名称', 43 | `attr_desc` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '属性描述', 44 | `attr_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '属性类型(STRING,NUMBER,BOOLEAN,DATE,COLLECTION)', 45 | `attr_model_key_ref` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '属性模型(适用于OBJECT类型属性)', 46 | `attr_value_source` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '属性值来源(INPUT,DICT,ADDRESS)', 47 | `is_delete` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否删除', 48 | `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', 49 | `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', 50 | PRIMARY KEY (`id`) USING BTREE, 51 | UNIQUE INDEX `uk_model_key_attr_name`(`model_key`, `attr_name`) USING BTREE 52 | ) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '模型属性表' ROW_FORMAT = Compact; 53 | 54 | -- ---------------------------- 55 | -- Table structure for brms_rule 56 | -- ---------------------------- 57 | DROP TABLE IF EXISTS `brms_rule`; 58 | CREATE TABLE `brms_rule` ( 59 | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id自增1', 60 | `rule_key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '规则key', 61 | `rule_desc` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '规则描述', 62 | `rule_set_key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '规则集key(package)', 63 | `rule_enter_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'SELECT' COMMENT '规则录入方式(CODING:编码式录入; SELECT:选择式录入 )', 64 | `rule_condition_text` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '规则condition代码(CODING方式)', 65 | `rule_action_text` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '规则action代码(CODING方式)', 66 | `rule_import_text` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '规则import内容代码(CODING方式)', 67 | `activation_group` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'activation-group', 68 | `agenda_group` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'agenda-group', 69 | `no_loop` varchar(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'no-loop(false 或 true)', 70 | `date_effective` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'date-effective(格式yyyy-MM-DD HH:mm:ss)', 71 | `date_expires` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'date-expires(格式yyyy-MM-DD HH:mm:ss)', 72 | `salience` int(10) UNSIGNED NULL DEFAULT NULL COMMENT 'salience(优先级,值越大优先级越高)', 73 | `is_delete` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否删除', 74 | `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', 75 | `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', 76 | PRIMARY KEY (`id`) USING BTREE, 77 | UNIQUE INDEX `uk_rule_key`(`rule_key`) USING BTREE 78 | ) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '规则表' ROW_FORMAT = Compact; 79 | 80 | -- ---------------------------- 81 | -- Table structure for brms_rule_action 82 | -- ---------------------------- 83 | DROP TABLE IF EXISTS `brms_rule_action`; 84 | CREATE TABLE `brms_rule_action` ( 85 | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id自增1', 86 | `rule_key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '规则key', 87 | `attr_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '属性名称', 88 | `action_value` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '动作值', 89 | `action_value_type` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '动作值类型(INPUT:直接输入型; CALCULATE:计算型)', 90 | `value_calculate_formula` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '动作值计算公式(CALCULATE 类型下有效)', 91 | `calculate_scale` tinyint(3) UNSIGNED NULL DEFAULT NULL COMMENT '计算保留位数', 92 | `calculate_rounding_mode` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '计算取整方式', 93 | `is_delete` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否删除', 94 | `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', 95 | `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', 96 | PRIMARY KEY (`id`) USING BTREE, 97 | INDEX `idx_rule_key`(`rule_key`(20)) USING BTREE 98 | ) ENGINE = InnoDB AUTO_INCREMENT = 27 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '规则动作表(RHS)' ROW_FORMAT = Compact; 99 | 100 | -- ---------------------------- 101 | -- Table structure for brms_rule_condition 102 | -- ---------------------------- 103 | DROP TABLE IF EXISTS `brms_rule_condition`; 104 | CREATE TABLE `brms_rule_condition` ( 105 | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id自增1', 106 | `rule_key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '规则key', 107 | `attr_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '属性名称', 108 | `condition_operator` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '条件符', 109 | `condition_value` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '条件值', 110 | `logical_operator` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '逻辑运算符(与下一个条件的逻辑运算符;取值: &&,|| )', 111 | `condition_order` int(11) NOT NULL DEFAULT 0 COMMENT '排序(多个条件通过order排序,值越小越靠前,并通过 logical_operator 字段进行连接)', 112 | `is_delete` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否删除', 113 | `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', 114 | `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', 115 | PRIMARY KEY (`id`) USING BTREE, 116 | INDEX `idx_rule_key`(`rule_key`(20)) USING BTREE 117 | ) ENGINE = InnoDB AUTO_INCREMENT = 40 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '规则条件表(LHS)' ROW_FORMAT = Compact; 118 | 119 | -- ---------------------------- 120 | -- Table structure for brms_rule_hit_log 121 | -- ---------------------------- 122 | DROP TABLE IF EXISTS `brms_rule_hit_log`; 123 | CREATE TABLE `brms_rule_hit_log` ( 124 | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id自增1', 125 | `request_no` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '流水号', 126 | `rule_set_key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '规则集key(package)', 127 | `agenda_group` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '议程组', 128 | `rule_key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '规则key', 129 | `input_model` varchar(4000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '输入模型(Json)', 130 | `output_model` varchar(4000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '输出模型(Json)', 131 | `is_delete` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否删除', 132 | `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', 133 | `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', 134 | PRIMARY KEY (`id`) USING BTREE, 135 | INDEX `idx_request_no`(`request_no`(13)) USING BTREE 136 | ) ENGINE = InnoDB AUTO_INCREMENT = 208 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '规则命中日志表' ROW_FORMAT = Compact; 137 | 138 | -- ---------------------------- 139 | -- Table structure for brms_rule_set 140 | -- ---------------------------- 141 | DROP TABLE IF EXISTS `brms_rule_set`; 142 | CREATE TABLE `brms_rule_set` ( 143 | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id自增1', 144 | `rule_set_key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '规则集key(package)', 145 | `rule_set_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '规则集名称', 146 | `is_delete` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否删除', 147 | `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', 148 | `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', 149 | PRIMARY KEY (`id`) USING BTREE, 150 | UNIQUE INDEX `uk_namespace_rule_set_key`(`rule_set_key`) USING BTREE 151 | ) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '规则集表' ROW_FORMAT = Compact; 152 | 153 | -- ---------------------------- 154 | -- Table structure for brms_rule_set_model 155 | -- ---------------------------- 156 | DROP TABLE IF EXISTS `brms_rule_set_model`; 157 | CREATE TABLE `brms_rule_set_model` ( 158 | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id自增1', 159 | `model_key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模型key', 160 | `rule_set_key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '规则集key(package)', 161 | `model_type` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模型类型(INPUT:输入; OUTPUT:输出)', 162 | `is_delete` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否删除', 163 | `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', 164 | `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', 165 | PRIMARY KEY (`id`) USING BTREE 166 | ) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '规则模型关联表' ROW_FORMAT = Compact; 167 | 168 | SET FOREIGN_KEY_CHECKS = 1; 169 | --------------------------------------------------------------------------------