table of Contents
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.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>