Drools实战-信用卡申请
通过Drools规则引擎来根据规则进行申请人的合法性检查,检查通过后再根据规则确定信用卡额度,最终页面效果如下:

1、计算规则
合法性检查规则如下:

信用卡额度确定规则:

2、实现步骤
2.1、创建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>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、创建/resources/application.yml文件
server: port: 8080 spring: application: name: creditCardApply
2.3、编写配置类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、编写实体类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、在resources/rules下创建规则文件creditCardApply.drl文件
//当前规则文件负责处理两类规则:用户信息合法性检查、确定信用卡额度 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、创建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、创建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、创建启动类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、导入静态资源文件到resources/static目录下

前端测试页面:
<!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>


浙公网安备 33010602011771号