drools简单实例之报关费问题

使用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折

 


 

 
posted @ 2021-03-15 11:54  千夜大魔王  阅读(160)  评论(0编辑  收藏  举报