使用drools解决报关费问题
.
.
规则:
申报费:1票2元
进场费:1车200元
活动:9.5折
开始计算费用,上代码!
实体类:
package com.us.drools.bean; /** * 报关费 * @author qianye * @create 2021-03-02 9:30 */ public class Customs { /**车数*/ private int car; /**票数*/ private int vote; /**申报费*/ private double declaration; /**进场费*/ private double admission; /**活动*/ private double activity; /**金额*/ private double money; public Customs(int car,int vote) { super(); this.car = car; this.vote = vote; this.declaration = 2; this.admission = 200; this.activity = 0.95; this.money=0; } public int getCar() { return car; } public void setCar(int car) { this.car = car; } public int getVote() { return vote; } public void setVote(int vote) { this.vote = vote; } public double getDeclaration() { return declaration; } public void setDeclaration(double declaration) { this.declaration = declaration; } public double getAdmission() { return admission; } public void setAdmission(double admission) { this.admission = admission; } public double getActivity() { return activity; } public void setActivity(double activity) { this.activity = activity; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } @Override public String toString() { final StringBuilder sb = new StringBuilder("报关费{"); sb.append("车数=").append(car); sb.append(", 票数=").append(vote); sb.append(", 申报费=").append(declaration); sb.append(", 进场费=").append(admission); sb.append(", 活动=").append(activity); sb.append(", 金额=").append(money); sb.append('}'); return sb.toString(); } }
DRL文件:
package com.us; import com.us.drools.bean.Customs; //计算申报费 2元1票 rule "calculation of filing fee" salience 3 //优先级,数字越大执行优先级越高 when //申报费不等于0 $c: Customs(declaration != 0); then $c.setMoney($c.getDeclaration()*$c.getVote()); $c.setDeclaration(0); System.out.println("计算申报费:"+$c.toString()); //重新检查所有规则是否匹配条件,而不管其之前是否执行过 update($c); end //计算进场费 一车200元 rule "calculate the entry fee" salience 2 //优先级,数字越大执行优先级越高 when //进场费 不等于0 $c : Customs(admission!=0); then $c.setMoney($c.getMoney()+($c.getAdmission()*$c.getCar())); $c.setAdmission(0); System.out.println("计算进场费:"+$c.toString()); update($c); end //计算优惠活动 95折 rule "calculating offers" salience 1 //优先级,数字越大执行优先级越高 when //申报费等于0,进场费等于0,活动不等于0 $c : Customs(declaration==0,admission==0,activity!=0); then $c.setMoney($c.getMoney()*$c.getActivity()); $c.setActivity(0); System.out.println("计算优惠活动:"+$c.toString()); update($c); end //计算完毕 rule "is evaluated" dialect "java" when //申报费等于0,进场费等于0,钱不等于0 $c:Customs(declaration==0,admission==0,money!=0); then System.out.println("计算完毕:"+$c.toString()); end
调用代码:
@Test public void test1(){ try { KieBase kieBase = DroolsUtils.readRuleFileByFileName("customsCharges.drl"); KieSession ksession = kieBase.newKieSession(); Customs c1=new Customs(1,10);//传入车辆数量,票数,活动定死9.5折 System.out.println(c1.toString()); ksession.insert(c1); ksession.fireAllRules(); } catch (Throwable t) { t.printStackTrace(); } }
DroolsUtils工具类:
package com.us.drools.util; import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.file.FileWriter; import cn.hutool.core.util.RandomUtil; import org.apache.commons.lang3.StringUtils; import org.kie.api.KieBase; import org.kie.api.io.ResourceType; import org.kie.internal.builder.KnowledgeBuilder; import org.kie.internal.builder.KnowledgeBuilderError; import org.kie.internal.builder.KnowledgeBuilderErrors; import org.kie.internal.builder.KnowledgeBuilderFactory; import org.kie.internal.io.ResourceFactory; import java.util.Date; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Drool工具类 */ public class DroolsUtils { /** * 默认规则文件所在路径 */ private static final String RULES_PATH = "rules/"; /** * 字符串是否包含中文(包含中文标点符号) * * @param str 待校验字符串 * @return true 包含中文字符 false 不包含中文字符 */ public static boolean isContainChinese(String str) { if (StringUtils.isEmpty(str)) { return true; } Pattern p = Pattern.compile("[\u4E00-\u9FA5|\\!|\\,|\\。|\\(|\\)|\\《|\\》|\\“|\\”|\\?|\\:|\\;|\\【|\\】]"); Matcher m = p.matcher(str); if (m.find()) { return true; } return false; } /** * 生成规则文件到硬盘 * @param rules 规则字符串 * @return 文件名 */ public static String generateRuleFile(String rules){ Date date = new Date(); String format = DateUtil.format(date, "yyyyMMddHHmmssSSS"); format+= RandomUtil.randomInt(1000,9999); String fileName=format+=".drl"; FileWriter writer = new FileWriter("rules/"+format); writer.write(rules); return fileName; } /** * 读取本地规则文件 * @param fileName 文件名称 * @return * @throws Exception */ public static KieBase readRuleFileByFileName(String fileName) throws Exception { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add(ResourceFactory.newClassPathResource(RULES_PATH+fileName), ResourceType.DRL); KnowledgeBuilderErrors errors = kbuilder.getErrors(); if (errors.size() > 0) { for (KnowledgeBuilderError error: errors) { System.err.println(error); } throw new Exception("IllegalArgumentException,无法解析规则,出现错误文件:"+fileName); } KieBase kieBase = kbuilder.newKnowledgeBase().newStatefulKnowledgeSession().getKieBase(); return kieBase; } }
maven文件:
<!-- drools -->
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>6.5.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>6.5.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>6.5.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>6.5.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-templates</artifactId>
<version>6.5.0.Final</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-spring</artifactId>
<version>6.5.0.Final</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
最后看看运行结果:
第一种结果:
车辆数量:1,票数:10,活动定死9.5折
第二种结果:
车辆数量:2,票数:30,活动定死9.5折