简介
规则引擎,全称为业务规则管理系统,英文名为BRMS(即Business Rule Management System)。规则引擎的主要思想是将应用程序中的业务决策部分分离出来,并使用预定义的语义模块编写业务决策(业务规则),由用户或开发者在需要时进行配置、管理。它可以接收数据输入,解释业务规则,并根据业务规则做出业务决策。规则引擎其实就是一个输入输出平台。
注册规则
操作示例
1. 引入依赖pom.xml
<dependency>
<groupId>cn.flyrise</groupId>
<artifactId>pai-common-rules</artifactId>
<version>1.1.0-SNAPSHOT</version>
</dependency>
2. 创建规则bean,实现Rule接口
import cn.flyrise.common.rules.annotation.Rule;
public class TestRule implements Rule {
@Override
public String getProjectName() {
//返回本工程的工程名称
return "pai-attendance";
}
@Override
public String getRuleName() {
//返回规则名称
return "积分规则";
}
}
3. 创建规则模型VO,使用RuleModel注解
目前支持基本类型的包装类型、数组、VO对象、List。
package cn.flyrise.pai.attendance.model.vo;
import cn.flyrise.common.rules.annotation.RuleModel;
import cn.flyrise.pai.points.model.TestRule;
import io.swagger.annotations.ApiModelProperty;
import java.util.Date;
import java.util.List;
@RuleModel(rules = {TestRule.class}, desc = "用户信息")
public class UserInfoVO {
@ApiModelProperty("用户Id")
private String userId;
@ApiModelProperty("用户名称")
private String userName;
@ApiModelProperty("用户积分")
private Integer userScore;
@ApiModelProperty("是否vip")
private Boolean vip;
@ApiModelProperty("联系电话")
private List<String> telephones;
@ApiModelProperty("生日")
private Date[] birthdays;
@ApiModelProperty("账户信息")
private UserAccountVO userAccountVO;
@ApiModelProperty("账户信息列表")
private List<UserAccountVO> userAccountVOList;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getUserScore() {
return userScore;
}
public void setUserScore(Integer userScore) {
this.userScore = userScore;
}
public Boolean getVip() {
return vip;
}
public void setVip(Boolean vip) {
this.vip = vip;
}
public List<String> getTelephones() {
return telephones;
}
public void setTelephones(List<String> telephones) {
this.telephones = telephones;
}
public Date[] getBirthdays() {
return birthdays;
}
public void setBirthdays(Date[] birthdays) {
this.birthdays = birthdays;
}
public UserAccountVO getUserAccountVO() {
return userAccountVO;
}
public void setUserAccountVO(UserAccountVO userAccountVO) {
this.userAccountVO = userAccountVO;
}
public List<UserAccountVO> getUserAccountVOList() {
return userAccountVOList;
}
public void setUserAccountVOList(List<UserAccountVO> userAccountVOList) {
this.userAccountVOList = userAccountVOList;
}
}
package cn.flyrise.pai.attendance.model.vo;
import cn.flyrise.common.rules.annotation.RuleModel;
import cn.flyrise.pai.points.model.TestRule;
import io.swagger.annotations.ApiModelProperty;
import java.util.Date;
import java.util.List;
@RuleModel(rules = {TestRule.class}, desc = "用户账户信息")
public class UserAccountVO {
@ApiModelProperty("用户Id")
private String userId;
@ApiModelProperty("账户名")
private String accountName;
@ApiModelProperty("余额")
private Double amount;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public Double getAmount() {
return amount;
}
public void setAmount(Double amount) {
this.amount = amount;
}
}
运行工程之后系统会根据实现Rule接口和RuleModel注解,自动注册规则到对应套件下。
配置规则
操作示例
1. 进入开发者后台——>套件——>规则管理
规则列表不能修改,名称来源于实现Rule接口的getRuleName()方法
2. 进入规则记录列表,点击条件配置
数据源来源于RuleModel注解的bean的属性
3. 配置完成
4. 支持函数
字符串函数
(1)charAt函数:返回字符串中指定的某个字符。
(2)indexOf函数:返回字符串中第一个查找到的下标index,从左边开始查找。
(3)lastIndexOf函数:返回字符串中第一个查找到的下标index,从右边开始查找。
(4)length函数:返回字符串的长度。(不用带括号)
(5)substr函数:返回字符串从指定位置开始,截取几个字符。
(6)substring函数:返回字符串中指定的几个字符。
(7)trim函数:清除字符串中的空格。
(8)toLowerCase函数:将字符串转换为小写。
(9)toUpperCase函数:将字符串转换为大写。
(10)endsWith函数:返回字符串是否以某段结尾。
(11)contains函数:返回字符串是否包含某段。
实现方式:利用java脚本引擎ScriptEngineManager,执行js内置的字符串函数
使用方式:编辑器输入字符串类型的值.会弹出提示
日期函数
(1)getDate函数:返回日期的“日”部分,值为1~31
(2)getDay函数:返回星期几,值为0~6,其中0表示星期日,1表示星期一,…,6表示星期六
(3)getHours函数:返回日期的“小时”部分,值为0~23。
(4)getMinutes函数:返回日期的“分钟”部分,值为0~59。
(5)getMonth函数:返回日期的“月”部分,值为0~11。其中0表示1月,2表示3月,…,11表示12月。
(6)getSeconds函数:返回日期的“秒”部分,值为0~59。
(7)getTime函数:返回系统时间。
(8)getTimezoneOffset函数:返回此地区的时差(当地时间与GMT格林威治标准时间的地区时差),单位为分钟。
(9)getYear函数:返回日期的“年”部分。返回值以1900年为基数,例如1999年为99。
(10)parse函数:返回从1970年1月1日零时整算起的毫秒数(当地时间)。
(11)setDate函数:设定日期的“日”部分,值为0~31。
(12)setHours函数:设定日期的“小时”部分,值为0~23。
(13)setMinutes函数:设定日期的“分钟”部分,值为0~59。
(14)setMonth函数:设定日期的“月”部分,值为0~11。其中0表示1月,…,11表示12月。
(15)setSeconds函数:设定日期的“秒”部分,值为0~59。
(16)setTime函数:设定时间。时间数值为1970年1月1日零时整算起的毫秒数。
(17)setYear函数:设定日期的“年”部分。
(18)toGMTString函数:转换日期成为字符串,为GMT格林威治标准时间。
实现方式:利用java脚本引擎ScriptEngineManager,执行js内置的日期函数
使用方式:编辑器输入日期类型的值.会弹出提示
数学函数
(1)abs函数:即Math.abs(以下同),返回一个数字的绝对值。
(2)acos函数:返回一个数字的反余弦值,结果为0~π弧度(radians)。
(3)asin函数:返回一个数字的反正弦值,结果为-π/2~π/2弧度。
(4)atan函数:返回一个数字的反正切值,结果为-π/2~π/2弧度。
(5)atan2函数:返回一个坐标的极坐标角度值。
(6)ceil函数:返回一个数字的最小整数值(大于或等于)。
(7)cos函数:返回一个数字的余弦值,结果为-1~1。
(8)exp函数:返回e(自然对数)的乘方值。
(9)floor函数:返回一个数字的最大整数值(小于或等于)。
(10)log函数:自然对数函数,返回一个数字的自然对数(e)值。
(11)max函数:返回两个数的最大值。
(12)min函数:返回两个数的最小值。
(13)pow函数:返回一个数字的乘方值。
(14)random函数:返回一个0~1的随机数值。
(15)round函数:返回一个数字的四舍五入值,类型是整数。
(16)sin函数:返回一个数字的正弦值,结果为-1~1。
(17)sqrt函数:返回一个数字的平方根值。
(18)tan函数:返回一个数字的正切值。
实现方式:利用java脚本引擎ScriptEngineManager,执行js内置的数学函数
使用方式:编辑器输入Math.会弹出提示
数组或集合函数
(1)join函数:转换并连接数组中的所有元素为一个字符串。
(2)length函数:数组的长度(不用带括号)。
(3)[index]:根据数组小标index获取元素。
(4)sort函数:将数组元素从小到大排序。
(5)includes函数:判断数组是否包含某元素
实现方式:利用java脚本引擎ScriptEngineManager,执行js内置的数组函数
使用方式:编辑器数组或集合类型的值.会弹出提示
自定义统计函数
max函数
返回给定数组或数组元素某属性的最大值。
请求参数
名称 | 类型 | 描述 | 是否必需 | 备注 |
---|---|---|---|---|
array | Array<> | 统计最大值的数组 | 是 | Array元素类型的可以是整型、浮点、时间、字符串、布尔和对象类型,当元素是对象类型时需指定key |
key | 字符串 | 对象类型元素的属性 | 否 | Array元素是对象类型时必须,且该属性的类型是整型、浮点、时间、字符串、布尔。 |
min函数
返回给定数组或数组元素某属性的最小值。
请求参数
名称 | 类型 | 描述 | 是否必需 | 备注 |
---|---|---|---|---|
array | Array<> | 统计最小值的数组 | 是 | Array元素类型的可以是整型、浮点、时间、字符串、布尔和对象类型,当元素是对象类型时需指定key |
key | 字符串 | 对象类型元素的属性 | 否 | Array元素是对象类型时必须,且该属性的类型是整型、浮点、时间、字符串、布尔。 |
sum函数
返回给定数组或数组元素某属性的和值。
请求参数
名称 | 类型 | 描述 | 是否必需 | 备注 |
---|---|---|---|---|
array | Array<> | 统计和值的数组 | 是 | Array元素类型的可以是整型、浮点和对象类型,当元素是对象类型时需指定key |
key | 字符串 | 对象类型元素的属性 | 否 | Array元素是对象类型时必须,且该属性的类型是整型、浮点。 |
average函数
返回给定数组或数组元素某属性的平均值(保留两位小数浮点型)。
请求参数
名称 | 类型 | 描述 | 是否必需 | 备注 |
---|---|---|---|---|
array | Array<> | 统计平均值的数组 | 是 | Array元素类型的可以是整型、浮点和对象类型,当元素是对象类型时需指定key |
key | 字符串 | 对象类型元素的属性 | 否 | Array元素是对象类型时必须,且该属性的类型是整型、浮点。 |
(5) median函数
返回给定数组的中值(保留两位小数浮点型)。
请求参数
名称 | 类型 | 描述 | 是否必需 | 备注 |
---|---|---|---|---|
array | Array<> | 统计中值的数组 | 是 | Array元素类型的可以是整型、浮点类型 |
rank函数
返回一个数值在给数组中的排位(小的排在前面)。
请求参数
名称 | 类型 | 描述 | 是否必需 | 备注 |
---|---|---|---|---|
array | Array<> | 统计排名的数组 | 是 | Array元素类型的可以是整型、浮点、时间、字符串、布尔类型 |
value | 同Array元素类型 | 统计排名的值 | 是 |
avedev函数
返回给定数组的平均绝对误差值(保留两位小数浮点型)。
请求参数
名称 | 类型 | 描述 | 是否必需 | 备注 |
---|---|---|---|---|
array | Array<> | 统计平均绝对误差值的数组 | 是 | Array元素类型的可以是整型、浮点类型 |
frequency函数
返回给定数组中出现次数最多的值。
请求参数
名称 | 类型 | 描述 | 是否必需 | 备注 |
---|---|---|---|---|
array | Array<> | 统计出现次数最多值的数组 | 是 | Array元素类型的可以是整型、浮点、时间、字符串、布尔类型 |
实现方式:编写自定义的函数,利用java脚本引擎ScriptEngineManager执行
使用方式:编辑器输入Statistic.会弹出提示
在线测试
点击调试工具进入在线测试,通过json文本给数据源中的属性赋值,点击执行可以得到当前规则配置的事件类型为输出的结果。
套件后端工程使用规则
public void Test() {
//@RuleModel注解的VO里面所有字段的值都不能为空
UserAccountVO userAccountVO = new UserAccountVO();
userAccountVO.setAccountName("张三");
userAccountVO.setAmount(100d);
UserInfoVO userInfoVO = new UserInfoVO();
userInfoVO.setUserId("123321");
userInfoVO.setUserName("张三");
userInfoVO.setUserScore(20);
userInfoVO.setVip(false);
userInfoVO.setBirthdays(new Date[]{new Date(), new Date()});
userInfoVO.setTelephones(Arrays.asList("13312345678", "0756-6122565"));
userInfoVO.setUserAccountVO(userAccountVO);
userInfoVO.setUserAccountVOList(Arrays.asList(userAccountVO, new UserAccountVO()));
/*执行规则得到返回值
套件是入驻企业安装时使用这个接口
*/
Reply<BusinessRuleVO> reply = ruleService.execute(new TestRule(), userInfoVO);
/*执行规则得到返回值
套件是运营企业安装时使用这个接口,parkId前端切换园区产生
*/
// Reply<BusinessRuleVO> reply = ruleService.execute(new TestRule(),null, userInfoVO);
if (reply.isSuccess()) {
//继续业务逻辑
BusinessRuleVO businessRuleVO = reply.getData();
JSONObject jsonObject = businessRuleVO.getObjectMap().get(userInfoVO.getClass().getSimpleName());
userInfoVO = JSONObject.toJavaObject(jsonObject, UserInfoVO.class);
System.out.println(JSON.toJSONString(userInfoVO));
} else {
//异常处理
}
}