Drools combat-credit card application

table of Contents

1. Calculation rules

2. Implementation steps

2.1. Create a maven project creditCardApply and configure the pom.xml file

2.2, create /resources/application.yml file

2.3, write configuration class DroolsConfig

2.4, write entity class CreditCardApplyInfo

2.5. Create a rule file creditCardApply.drl file under resources/rules

2.6, create RuleService

2.7, create RuleController

2.8, create the startup class DroolsApplication

2.9. Import static resource files to the resources/static directory


The Drools rule engine is used to check the legality of the applicant according to the rules. After the check is passed, the credit card limit is determined according to the rules. The final page effect is as follows:

1. Calculation rules

The legality check rules are as follows:

Rule number name description
1 Check academic qualifications and salary 1 If the applicant has neither a house nor a car, at the same time the degree is below college, and the monthly salary is less than 5000, then it will not be passed
2 Check academic qualifications and salary 2 If the applicant has neither a house nor a car, at the same time the degree is college or undergraduate, and the monthly salary is less than 3000, then it will not pass
3 Check academic qualifications and salary 3 If the applicant has neither a house nor a car, and a bachelor degree or above, and a monthly salary of less than 2000, and no credit card before, then it will not be approved
4 Check the number of credit cards the applicant has If the applicant's existing credit card number is greater than 10, then it will not be approved

Credit card limit determination rules:

Rule number name description
1 Rule 1 If the applicant has a house and a car, or the monthly income is more than 20,000, the credit card issued is 15,000
2 Rule 2 If the applicant does not have a house or a car, but the monthly income is between 10,000 and 20,000, the amount of credit card issued is 6,000
3 Rule 3 If the applicant does not have a house or a car, and the monthly income is below 10,000, the amount of credit card issued is 3,000
4 Rule 4 If the applicant has a house but no car or no house but a car, and the monthly income is less than 10,000, the credit card amount issued is 5,000
5 Rule 5 If the applicant has a house but no car or no house but a car, and the monthly income is between 10,000 and 20,000, then the credit card amount issued is 8,000

2. Implementation steps

2.1. Create a maven project creditCardApply and configure the pom.xml file

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starters</artifactId>
        <version>2.0.6.RELEASE</version>
    </parent>
    <groupId>org.example</groupId>
    <artifactId>creditCardApply</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <!--drools规则引擎-->
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-core</artifactId>
            <version>7.6.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-compiler</artifactId>
            <version>7.6.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-templates</artifactId>
            <version>7.6.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.kie</groupId>
            <artifactId>kie-api</artifactId>
            <version>7.6.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.kie</groupId>
            <artifactId>kie-spring</artifactId>
            <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>
            <version>7.6.0.Final</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>${project.artifactId}</finalName>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.*</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2.2, create /resources/application.yml file

server:
  port: 8080
spring:
  application:
    name: creditCardApply

2.3, write configuration class DroolsConfig

package com.itheima.drools.config;

import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieRepository;
import org.kie.api.runtime.KieContainer;
import org.kie.internal.io.ResourceFactory;
import org.kie.spring.KModuleBeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.io.IOException;

/**
 * 规则引擎配置类
 */
@Configuration
public class DroolsConfig
{
    //指定规则文件存放的目录
    private static final String RULES_PATH = "rules/";
    private final KieServices kieServices = KieServices.Factory.get();
    @Bean
    @ConditionalOnMissingBean
    public KieFileSystem kieFileSystem() throws IOException {
        System.setProperty("drools.dateformat","yyyy-MM-dd");
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        ResourcePatternResolver resourcePatternResolver =
                new PathMatchingResourcePatternResolver();
        Resource[] files =
                resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "*.*");
        String path = null;
        for (Resource file : files) {
            path = RULES_PATH + file.getFilename();
            kieFileSystem.write(ResourceFactory.newClassPathResource(path, "UTF-8"));
        }
        return kieFileSystem;
    }
    @Bean
    @ConditionalOnMissingBean
    public KieContainer kieContainer() throws IOException {
        KieRepository kieRepository = kieServices.getRepository();
        kieRepository.addKieModule(kieRepository::getDefaultReleaseId);
        KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem());
        kieBuilder.buildAll();
        return kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
    }
    @Bean
    @ConditionalOnMissingBean
    public KieBase kieBase() throws IOException {
        return kieContainer().getKieBase();
    }
    @Bean
    @ConditionalOnMissingBean
    public KModuleBeanFactoryPostProcessor kiePostProcessor() {
        return new KModuleBeanFactoryPostProcessor();
    }
}

2.4, write entity class CreditCardApplyInfo

package com.itheima.drools.entity;
/**
 * 信用卡申请信息
 */
public class CreditCardApplyInfo {
    public static final String EDUCATION_1 = "专科以下";
    public static final String EDUCATION_2 = "专科";
    public static final String EDUCATION_3 = "本科";
    public static final String EDUCATION_4 = "本科以上";

    private String name;
    private String sex;
    private int age;
    private String education;
    private String telephone;
    private double monthlyIncome = 0;//月收入
    private String address;

    private boolean hasHouse = false;//是否有房
    private boolean hasCar = false;//是否有车
    private int hasCreditCardCount = 0;//现持有信用卡数量

    private boolean checkResult = true;//审核是否通过
    private double quota = 0;//额度

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getEducation() {
        return education;
    }

    public void setEducation(String education) {
        this.education = education;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public double getMonthlyIncome() {
        return monthlyIncome;
    }

    public void setMonthlyIncome(double monthlyIncome) {
        this.monthlyIncome = monthlyIncome;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public boolean isHasHouse() {
        return hasHouse;
    }

    public void setHasHouse(boolean hasHouse) {
        this.hasHouse = hasHouse;
    }

    public boolean isHasCar() {
        return hasCar;
    }

    public void setHasCar(boolean hasCar) {
        this.hasCar = hasCar;
    }

    public int getHasCreditCardCount() {
        return hasCreditCardCount;
    }

    public void setHasCreditCardCount(int hasCreditCardCount) {
        this.hasCreditCardCount = hasCreditCardCount;
    }

    public boolean isCheckResult() {
        return checkResult;
    }

    public void setCheckResult(boolean checkResult) {
        this.checkResult = checkResult;
    }

    public double getQuota() {
        return quota;
    }

    public void setQuota(double quota) {
        this.quota = quota;
    }

    public String toString() {
        if(checkResult){
            return "审核通过,信用卡额度为:" + quota;
        }else {
            return "审核不通过";
        }
    }
}

2.5. Create a rule file creditCardApply.drl file under resources/rules

//当前规则文件负责处理两类规则:用户信息合法性检查、确定信用卡额度
package creditCardApply

import com.itheima.drools.entity.CreditCardApplyInfo

//用户信息合法性检查---共四个规则

rule "如果申请人既没房也没车,同时学历为大专以下,并且月薪少于5000,那么不通过"
    salience 100
    no-loop true
    when
        $c:CreditCardApplyInfo(hasHouse == false && hasCar == false && education == CreditCardApplyInfo.EDUCATION_1 && monthlyIncome < 5000)
    then
        $c.setCheckResult(false);
        drools.halt();
end

rule "如果申请人既没房也没车,同时学历为大专或本科,并且月薪少于3000,那么不通过"
    salience 10
    no-loop true
    when
        $c:CreditCardApplyInfo(hasCar == false &&
                                hasHouse == false &&
                                (education == CreditCardApplyInfo.EDUCATION_2  ||
                                education == CreditCardApplyInfo.EDUCATION_3) &&
                                monthlyIncome < 3000)
    then
        $c.setCheckResult(false);
        drools.halt();
end
rule "如果申请人既没房也没车,同时学历为本科以上,并且月薪少于2000,同时之前没有信用卡的,那么不通过"
    salience 10
    no-loop true
    when
        $c:CreditCardApplyInfo(hasCar == false &&
                                hasHouse == false &&
                                education == CreditCardApplyInfo.EDUCATION_4 &&
                                monthlyIncome < 2000 &&
                                hasCreditCardCount == 0)
    then
        $c.setCheckResult(false);
        drools.halt();
end
rule "如果申请人现有的信用卡数量大于10,那么不通过"
    salience 10
    no-loop true
    when
        $c:CreditCardApplyInfo(hasCreditCardCount > 10)


    then
        $c.setCheckResult(false);
        drools.halt();
end

//--------------------------------------------------------------------------
//确定额度
rule "如果申请人有房有车,或者月收入在20000以上,那么发放的信用卡额度为15000"
    salience 1
    no-loop true
    activation-group "quota_group"
    when
        $c:CreditCardApplyInfo(checkResult == true &&
                                ((hasHouse == true && hasCar == true) ||
                                (monthlyIncome > 20000)))
    then
        $c.setQuota(15000);
end
rule "如果申请人没房没车,但月收入在10000~20000之间,那么发放的信用卡额度为6000"
    salience 1
    no-loop true
    activation-group "quota_group"
    when
        $c:CreditCardApplyInfo(checkResult == true &&
                                hasHouse == false &&
                                hasCar == false &&
                                monthlyIncome >= 10000 &&
                                monthlyIncome <= 20000)
    then
        $c.setQuota(6000);
end
rule "如果申请人没房没车,月收入在10000以下,那么发放的信用卡额度为3000"
    salience 1
    no-loop true
    activation-group "quota_group"
    when
        $c:CreditCardApplyInfo(checkResult == true &&
                                        hasHouse == false &&
                                        hasCar == false &&
                                        monthlyIncome < 10000)
    then
        $c.setQuota(3000);
end
rule "如果申请人有房没车或者没房但有车,月收入在10000以下,那么发放的信用卡额度为5000"
    salience 1
    no-loop true
    activation-group "quota_group"
    when
        $c:CreditCardApplyInfo(checkResult == true &&
                                ((hasHouse == true && hasCar == false) ||
                                (hasHouse == false && hasCar == true)) &&
                                monthlyIncome < 10000)
    then
        $c.setQuota(5000);
end
rule "如果申请人有房没车或者是没房但有车,月收入在10000~20000之间,那么发放的信用卡额度为8000"
    salience 1
    no-loop true
    activation-group "quota_group"
    when
        $c:CreditCardApplyInfo(checkResult == true &&
                                ((hasHouse == true && hasCar == false) ||
                                (hasHouse == false && hasCar == true)) &&
                                monthlyIncome >= 10000 &&
                                monthlyIncome <= 20000)
    then
        $c.setQuota(8000);
end

2.6, create RuleService

package com.itheima.drools.service;

import com.itheima.drools.entity.CreditCardApplyInfo;
import org.kie.api.KieBase;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RuleService
{
    @Autowired
    private KieBase kieBase;

    //调用Drools规则引擎实现信用卡申请
    public CreditCardApplyInfo creditCardApply(CreditCardApplyInfo creditCardApplyInfo)
    {
        KieSession session = kieBase.newKieSession();
        session.insert(creditCardApplyInfo);
        session.fireAllRules();
        session.dispose();
        return creditCardApplyInfo;
    }
}

2.7, create RuleController

package com.itheima.drools.controller;

import com.itheima.drools.entity.CreditCardApplyInfo;
import com.itheima.drools.service.RuleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("rule")
public class RuleController
{
    @Autowired
    private RuleService ruleService;

    @RequestMapping("/creditCardApply")
    public CreditCardApplyInfo creditCardApply(@RequestBody  CreditCardApplyInfo creditCardApplyInfo)
    {
        creditCardApplyInfo = ruleService.creditCardApply(creditCardApplyInfo);
        return creditCardApplyInfo;
    }

}

2.8, create the startup class DroolsApplication

package com.itheima.drools;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DroolsApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(DroolsApplication.class);
    }
}

2.9. Import static resource files to the resources/static directory

Front-end test page:

<!DOCTYPE html>
<html>
<head>
    <!-- 页面meta -->
    <meta charset="utf-8">
    <title>XX银行信用卡申请</title>
    <meta name="description" content="个人所得税计算">
    <meta name="keywords" content="个人所得税计算">
    <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
</head>
<body class="mainBg">
<div id="app">
    <h3 align="center">XX银行信用卡申请-by/Gjs</h3>
    <table align="center" width="50%" border="0">
        <tr>
            <td>姓名</td>
            <td>
                <input type="text" v-model="creditCardApplyInfo.name">
            </td>
            <td>性别</td>
            <td>
                <input type="text" v-model="creditCardApplyInfo.sex">
            </td>
        </tr>
        <tr>
            <td>年龄</td>
            <td>
                <input type="text" v-model="creditCardApplyInfo.age">
            </td>
            <td>手机号</td>
            <td>
                <input type="text" v-model="creditCardApplyInfo.telephone">
            </td>
        </tr>
        <tr>
            <td>住址</td>
            <td>
                <input type="text" v-model="creditCardApplyInfo.address">
            </td>
            <td>学历</td>
            <td>
                <select v-model="creditCardApplyInfo.education">
                    <option value="专科以下">专科以下</option>
                    <option value="专科">专科</option>
                    <option value="本科">本科</option>
                    <option value="本科以上">本科以上</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>月收入</td>
            <td>
                <input type="text" v-model="creditCardApplyInfo.monthlyIncome">
            </td>
            <td>现持有信用卡数量</td>
            <td>
                <input type="text" v-model="creditCardApplyInfo.hasCreditCardCount">
            </td>
        </tr>
        <tr>
            <td>是否有房</td>
            <td>
                <select v-model="creditCardApplyInfo.hasHouse">
                    <option value="true">是</option>
                    <option value="false">否</option>
                </select>
            </td>
            <td>是否有车</td>
            <td>
                <select v-model="creditCardApplyInfo.hasCar">
                    <option value="true">是</option>
                    <option value="false">否</option>
                </select>
            </td>
        </tr>
        <tr>
            <td colspan="4" align="center">
                <br>
                <input type="button" value="   申请   " @click="creditCardApply()">
            </td>
        </tr>
        <tr>
            <td colspan="4" align="center">
                {
   
   {applyResultMessage}}
            </td>
        </tr>
    </table>
</div>
</body>
<!-- 引入组件库 -->
<script src="js/vue.js"></script>
<script src="js/axios.js"></script>
<script>
    new Vue({
        el: '#app',
        data:{
            creditCardApplyInfo:{
                education:"本科",
                hasHouse:true,
                hasCar:true
            },
            applyResultMessage:''
        },
        methods: {
            creditCardApply(){
                axios.post("/rule/creditCardApply",this.creditCardApplyInfo).then((res) => {
                    if(res.data.checkResult){
                        //审核通过
                        this.applyResultMessage = "恭喜你信用卡申请成功,信用卡额度为:" + res.data.quota;
                    }else{
                        //审核失败
                        this.applyResultMessage = "抱歉,您提交的信息审核未通过,您不能申请我行信用卡!";
                    }
                });
            }
        }
    });
</script>
</html>

Guess you like

Origin blog.csdn.net/gjs935219/article/details/107905379