Drools实战-信用卡申请
通过Drools规则引擎来根据规则进行申请人的合法性检查,检查通过后再根据规则确定信用卡额度,最终页面效果如下:
1、计算规则
合法性检查规则如下:
信用卡额度确定规则:
2、实现步骤
2.1、创建maven工程creditCardApply并配置pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>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"> 4.0.0 org.springframework.boot spring-boot-starters 2.0.6.RELEASE org.example creditCardApply 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-aop org.springframework.boot spring-boot-starter-test commons-lang commons-lang 2.6 org.drools drools-core 7.6.0.Final org.drools drools-compiler 7.6.0.Final org.drools drools-templates 7.6.0.Final org.kie kie-api 7.6.0.Final org.kie kie-spring org.springframework spring-tx org.springframework spring-beans org.springframework spring-core org.springframework spring-context 7.6.0.Final ${project.artifactId} src/main/java **/*.xml false src/main/resources **/*.* false org.apache.maven.plugins maven-compiler-plugin 2.3.2 1.8
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目录下
前端测试页面:
XX银行信用卡申请 class="mainBg">XX银行信用卡申请-by/Gjs
姓名 性别 年龄 手机号 住址 学历 月收入 现持有信用卡数量 是否有房 是否有车
{{applyResultMessage}}