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>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY