Drools项目实战
Drools实战
1 个人所得税计算器
本小节我们需要通过Drools规则引擎来根据规则计算个人所得税,最终页面效果如下:
1.1 名词解释
税前月收入:即税前工资,指交纳个人所得税之前的总工资
应纳税所得额:指按照税法规定确定纳税人在一定期间所获得的所有应税收入减除在该纳税期间依法允许减除的各种支出后的余额
税率:是对征税对象的征收比例或征收额度
速算扣除数:指为解决超额累进税率分级计算税额的复杂技术问题,而预先计算出的一个数据,可以简化计算过程
扣税额:是指实际缴纳的税额
税后工资:是指扣完税后实际到手的工资收入
1.2 计算规则
要实现个人所得税计算器,需要了解如下计算规则:
规则编号 | 名称 | 描述 |
---|---|---|
1 | 计算应纳税所得额 | 应纳税所得额为税前工资减去3500 |
2 | 设置税率,应纳税所得额<=1500 | 税率为0.03,速算扣除数为0 |
3 | 设置税率,应纳税所得额在1500至4500之间 | 税率为0.1,速算扣除数为105 |
4 | 设置税率,应纳税所得额在4500志9000之间 | 税率为0.2,速算扣除数为555 |
5 | 设置税率,应纳税所得额在9000志35000之间 | 税率为0.25,速算扣除数为1005 |
6 | 设置税率,应纳税所得额在35000至55000之间 | 税率为0.3,速算扣除数为2755 |
7 | 设置税率,应纳税所得额在55000至80000之间 | 税率为0.35,速算扣除数为5505 |
8 | 设置税率,应纳税所得额在80000以上 | 税率为0.45,速算扣除数为13505 |
9 | 计算税后工资 | 扣税额=应纳税所得额*税率-速算扣除数 税后工资=税前工资-扣税额 |
1.3 实现步骤
本实战案例我们基于Spring Boot整合Drools的方式来实现。
第一步:创建maven工程calculation并配置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>cn.itcast</groupId><artifactId>calculation</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: calculation
第三步:编写配置类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@ConditionalOnMissingBeanpublic 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@ConditionalOnMissingBeanpublic 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@ConditionalOnMissingBeanpublic KieBase kieBase() throws IOException {return kieContainer().getKieBase();}@Bean@ConditionalOnMissingBeanpublic KModuleBeanFactoryPostProcessor kiePostProcessor() {return new KModuleBeanFactoryPostProcessor();}
}
第四步:编写实体类Calculation
package com.itheima.drools.entity;public class Calculation {private double wage;//税前工资private double wagemore;//应纳税所得额private double cess;//税率private double preminus;//速算扣除数private double wageminus;//扣税额private double actualwage;//税后工资public double getWage() {return wage;}public void setWage(double wage) {this.wage = wage;}public double getActualwage() {return actualwage;}public void setActualwage(double actualwage) {this.actualwage = actualwage;}public double getWagemore() {return wagemore;}public void setWagemore(double wagemore) {this.wagemore = wagemore;}public double getCess() {return cess;}public void setCess(double cess) {this.cess = cess;}public double getPreminus() {return preminus;}public void setPreminus(double preminus) {this.preminus = preminus;}public double getWageminus() {return wageminus;}public void setWageminus(double wageminus) {this.wageminus = wageminus;}@Overridepublic String toString() {return "Calculation{" +"wage=" +