第2-4-9章 规则引擎Drools实战(2)-信用卡申请
9.2 信用卡申请
本小节我们需要通过Drools规则引擎来根据规则进行申请人的合法性检查,检查通过后再根据规则确定信用卡额度,最终页面效果如下:
9.2.1 计算规则
合法性检查规则如下:
规则编号 | 名称 | 描述 |
---|---|---|
1 | 检查学历与薪水1 | 如果申请人既没房也没车,同时学历为大专以下,并且月薪少于5000,那么不通过 |
2 | 检查学历与薪水2 | 如果申请人既没房也没车,同时学历为大专或本科,并且月薪少于3000,那么不通过 |
3 | 检查学历与薪水3 | 如果申请人既没房也没车,同时学历为本科以上,并且月薪少于2000,同时之前没有信用卡的,那么不通过 |
4 | 检查申请人已有的信用卡数量 | 如果申请人现有的信用卡数量大于10,那么不通过 |
信用卡额度确定规则:
规则编号 | 名称 | 描述 |
---|---|---|
1 | 规则1 | 如果申请人有房有车,或者月收入在20000以上,那么发放的信用卡额度为15000 |
2 | 规则2 | 如果申请人没房没车,但月收入在10000~20000之间,那么发放的信用卡额度为6000 |
3 | 规则3 | 如果申请人没房没车,月收入在10000以下,那么发放的信用卡额度为3000 |
4 | 规则4 | 如果申请人有房没车或者没房但有车,月收入在10000以下,那么发放的信用卡额度为5000 |
5 | 规则5 | 如果申请人有房没车或者是没房但有车,月收入在10000~20000之间,那么发放的信用卡额度为8000 |
9.2.2 实现步骤
第一步:创建maven工程creditCardApply并配置pom.xml文件
<?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>com.itheima</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>
第二步:创建/resources/application.yml文件
server:
port: 8080
spring:
application:
name: creditCardApply
第三步:编写配置类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.api.runtime.KieSession;
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.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.Resource;
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 {
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();
}
}
第四步:编写实体类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 "审核不通过";
}
}
}
第五步:在resources/rules下创建规则文件creditCardApply.drl文件
package com.itheima.creditCardApply
import com.itheima.drools.entity.CreditCardApplyInfo
//合法性检查
rule "如果申请人既没房也没车,同时学历为大专以下,并且月薪少于5000,那么不通过"
salience 10
no-loop true
when
$c:CreditCardApplyInfo(hasCar == false &&
hasHouse == 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
第六步:创建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;
}
}
第七步:创建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;
}
}
第八步:创建启动类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);
}
}
第九步:导入静态资源文件到resources/static目录下
全套代码及资料全部完整提供,点此处下载