我们假定如下情景:网站伴随业务产生而进行的积分发放操作。比如支付宝信用卡还款奖励积分等。
我们定义一下发放规则:
积分的发放参考因素有:交易笔数、交易金额数目、信用卡还款次数、生日特别优惠等。
定义规则:
// 过生日,则加10分,并且将当月交易比数翻倍后再计算积分
// 2011-01-08 - 2011-08-08每月信用卡还款3次以上,每满3笔赠送30分
// 当月购物总金额100以上,每100元赠送10分
// 当月购物次数5次以上,每五次赠送50分
// 特别的,如果全部满足了要求,则额外奖励100分
// 发生退货,扣减10分
addpoint.drl
subpoint.drl
运行结果
我们定义一下发放规则:
积分的发放参考因素有:交易笔数、交易金额数目、信用卡还款次数、生日特别优惠等。
定义规则:
// 过生日,则加10分,并且将当月交易比数翻倍后再计算积分
// 2011-01-08 - 2011-08-08每月信用卡还款3次以上,每满3笔赠送30分
// 当月购物总金额100以上,每100元赠送10分
// 当月购物次数5次以上,每五次赠送50分
// 特别的,如果全部满足了要求,则额外奖励100分
// 发生退货,扣减10分
// 退货金额大于100,扣减100分
pom.xml,kmdomule.xml请参考上个hello world 例子
PointDomain.java
package com.fei.drools.bean;
/**
* 积分计算对象
*/
public class PointDomain implements java.io.Serializable {
static final long serialVersionUID = 1L;
public PointDomain() {}
// 用户名
private String userName;
// 是否当日生日
private boolean birthDay;
// 增加积分数目
private long point;
// 当月购物次数
private int buyNums;
// 当月退货次数
private int backNums;
// 当月购物总金额
private double buyMoney;
// 当月退货总金额
private double backMondy;
// 当月信用卡还款次数
private int billThisMonth;
/**
* 记录积分发送流水,防止重复发放
* @param userName 用户名
* @param type 积分发放类型
*/
public void recordPointLog(String userName, String type){
System.out.println("增加对"+userName+"的类型为"+type+"的积分操作记录.");
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public boolean isBirthDay() {
return birthDay;
}
public void setBirthDay(boolean birthDay) {
this.birthDay = birthDay;
}
public long getPoint() {
return point;
}
public void setPoint(long point) {
this.point = point;
}
public int getBuyNums() {
return buyNums;
}
public void setBuyNums(int buyNums) {
this.buyNums = buyNums;
}
public int getBackNums() {
return backNums;
}
public void setBackNums(int backNums) {
this.backNums = backNums;
}
public double getBuyMoney() {
return buyMoney;
}
public void setBuyMoney(double buyMoney) {
this.buyMoney = buyMoney;
}
public double getBackMondy() {
return backMondy;
}
public void setBackMondy(double backMondy) {
this.backMondy = backMondy;
}
public int getBillThisMonth() {
return billThisMonth;
}
public void setBillThisMonth(int billThisMonth) {
this.billThisMonth = billThisMonth;
}
}
addpoint.drl
package com.fei.drools;
import com.fei.drools.bean.PointDomain;
rule birthdayPoint
// 过生日,则加10分,并且将当月交易比数翻倍后再计算积分
salience 100
lock-on-active true
when
$pointDomain : PointDomain(birthDay == true)
then
System.out.println ( "执行规则: "+drools.getRule().getName());
$pointDomain.setPoint($pointDomain.getPoint()+100);
$pointDomain.setBuyNums($pointDomain.getBuyNums()*2);
$pointDomain.setBuyMoney($pointDomain.getBuyMoney()*2);
$pointDomain.setBillThisMonth($pointDomain.getBillThisMonth()*2);
$pointDomain.recordPointLog($pointDomain.getUserName(),"birthdayPoint");
end
rule billThisMonthPoint
// 2016-01-01 - 2016-06-30每月分期还款3次以上,每满3笔赠送30分
salience 99
lock-on-active true
date-effective "31-dec-2015 23:59:59"
date-expires "30-jun-2016 23:59:59"
when
$pointDomain : PointDomain(billThisMonth >= 3)
then
System.out.println ( "执行规则: "+drools.getRule().getName());
$pointDomain.setPoint($pointDomain.getPoint()+$pointDomain.getBillThisMonth()/3*30);
$pointDomain.recordPointLog($pointDomain.getUserName(),"billThisMonthPoint");
end
rule buyMoneyPoint
// 当月购物总金额100以上,每100元赠送10分
salience 98
lock-on-active true
when
$pointDomain : PointDomain(buyMoney >= 100)
then
System.out.println ( "执行规则: "+drools.getRule().getName());
$pointDomain.setPoint($pointDomain.getPoint()+ (int)$pointDomain.getBuyMoney()/100 * 10);
$pointDomain.recordPointLog($pointDomain.getUserName(),"buyMoneyPoint");
end
rule buyNumsPoint
// 当月购物次数5次以上,每五次赠送50分
salience 97
lock-on-active true
when
$pointDomain : PointDomain(buyNums >= 5)
then
System.out.println ( "执行规则: "+drools.getRule().getName());
$pointDomain.setPoint($pointDomain.getPoint()+$pointDomain.getBuyNums()/5 * 50);
$pointDomain.recordPointLog($pointDomain.getUserName(),"buyNumsPoint");
end
rule allFitPoint
// 特别的,如果全部满足了要求,则额外奖励100分
salience 96
lock-on-active true
when
$pointDomain:PointDomain(buyNums >= 5 && billThisMonth >= 3 && buyMoney >= 100)
then
System.out.println ( "执行规则: "+drools.getRule().getName());
$pointDomain.setPoint($pointDomain.getPoint()+ 100);
$pointDomain.recordPointLog($pointDomain.getUserName(),"allFitPoint");
end
subpoint.drl
package com.fei.drools;
import com.fei.drools.bean.PointDomain;
rule subBackNumsPoint
// 发生退货,扣减10分
salience 10
lock-on-active true
when
$pointDomain : PointDomain(backNums >= 1)
then
System.out.println ( "执行规则: "+drools.getRule().getName());
$pointDomain.setPoint($pointDomain.getPoint()-10);
$pointDomain.recordPointLog($pointDomain.getUserName(),"subBackNumsPoint");
end
rule subBackMondyPoint
// 退货金额大于等于100,扣减100分
salience 9
lock-on-active true
when
$pointDomain : PointDomain(backMondy >= 100)
then
System.out.println ( "执行规则: "+drools.getRule().getName());
$pointDomain.setPoint($pointDomain.getPoint()-10);
$pointDomain.recordPointLog($pointDomain.getUserName(),"subBackMondyPoint");
endMainTest.java
package com.fei.drools;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import com.fei.drools.bean.Message;
import com.fei.drools.bean.PointDomain;
public class MainTest {
public static void main(String[] args) {
// hello();
point();
}
public static void hello(){
// load up the knowledge base
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-rules");
Message message = new Message();
message.setMsg("Hello World");
message.setStatus(Message.HELLO);
kSession.insert(message);
kSession.fireAllRules();
kSession.dispose();
}
public static void point(){
// load up the knowledge base
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-rules");
PointDomain pointDomain = new PointDomain();
pointDomain.setUserName("ko");
pointDomain.setBillThisMonth(3);
pointDomain.setBackMondy(100d);
pointDomain.setBuyMoney(500d);
pointDomain.setBackNums(1);
pointDomain.setBuyNums(5);
pointDomain.setBirthDay(true);
pointDomain.setPoint(0l);
// go !
kSession.insert(pointDomain);
kSession.fireAllRules();
System.out.println("积分 :"+pointDomain.getPoint());
}
}
运行结果
本文介绍了一个基于规则引擎的积分计算系统的设计与实现。该系统能够根据用户的交易行为自动计算并发放积分,涵盖生日奖励、购物金额及次数奖励等多种场景。

被折叠的 条评论
为什么被折叠?



