Drools实战-个人所得税计算器
1、个人所得税计算器
1.1、名词解释
税前月收入:即税前工资,指交纳个人所得税之前的总工资
应纳税所得额:指按照税法规定确定纳税人在一定期间所获得的所有应税收入减除在该纳税期间依法允许减除的各种支出后的余额
税率:是对征税对象的征收比例或征收额度
速算扣除数:指为解决超额累进税率分级计算税额的复杂技术问题,而预先计算出的一个数据,可以简化计算过程
扣税额:是指实际缴纳的税额
税后工资:是指扣完税后实际到手的工资收入
1.2、计算规则
要实现个人所得税计算器,需要了解如下计算规则:
例子:
税前工资:10000
应缴纳所得额:10000-3500 = 6500
税率:0.2
速算扣除数:555
扣税额:6500 * 0.2 - 555 = 745
税后工资:10000 - 745 = 9255
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>org.example</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 @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(); } }
第四步:编写实体类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; } @Override public String toString() { return "Calculation{" + "wage=" + wage + ", actualwage=" + actualwage + ", wagemore=" + wagemore + ", cess=" + cess + ", preminus=" + preminus + ", wageminus=" + wageminus + '}'; } }
第五步:在resources/rules下创建规则文件calculation.drl文件
//当前规则文件用于计算个人所得税 package calculation import com.itheima.drools.entity.Calculation /** 当前规则文件中的规划主要分为三类 1、计算应纳税所得额 2、设置税率、速算扣除数 3、计算税后工资 */ //计算应缴税所得额 rule "计算应缴纳所得额" salience 100 date-effective "2011-09-01" no-loop true when $cal:Calculation(wage > 0) then double wagemore = $cal.getWage() - 3500; $cal.setWagemore(wagemore); update($cal) end //设置税率、速算扣除数 rule "设置税率,应纳税所得额<=1500" salience 3 no-loop true when $cal:Calculation(wagemore <= 1500) then $cal.setCess(0.03); //税率 $cal.setPreminus(0); //速算扣除数 update($cal) end //设置税率、速算扣除数 rule "设置税率,应纳税所得额在1500至4500之间" salience 2 no-loop true activation-group "SETCess_Group" when $cal:Calculation(wagemore > 1500 && wagemore <= 4500 ) then $cal.setCess(0.1); //税率 $cal.setPreminus(105); //速算扣除数 update($cal) end rule "个人所得税:设置税率-->>应纳税所得额在4500志9000之间" salience 2 no-loop true activation-group "SETCess_Group" when $cal : Calculation(wagemore > 4500 && wagemore <= 9000) then $cal.setCess(0.2); $cal.setPreminus(555); update($cal); end rule "个人所得税:设置税率-->>应纳税所得额在9000志35000之间" salience 2 no-loop true activation-group "SETCess_Group" when $cal : Calculation(wagemore > 9000 && wagemore <= 35000) then $cal.setCess(0.25); $cal.setPreminus(1005); update($cal); end rule "个人所得税:设置税率-->>应纳税所得额在35000至55000之间" salience 2 no-loop true activation-group "SETCess_Group" when $cal : Calculation(wagemore > 35000 && wagemore <= 55000) then $cal.setCess(0.3); $cal.setPreminus(2755); update($cal); end rule "个人所得税:设置税率-->>应纳税所得额在55000至80000之间" salience 2 no-loop true activation-group "SETCess_Group" when $cal : Calculation(wagemore > 55000 && wagemore <= 80000) then $cal.setCess(0.35); $cal.setPreminus(5505); update($cal); end rule "个人所得税:设置税率-->>应纳税所得额在80000以上" salience 2 no-loop true activation-group "SETCess_Group" when $cal : Calculation(wagemore > 80000) then $cal.setCess(0.45); $cal.setPreminus(13505); update($cal); end rule "个人所得税:计算税后工资" salience 1 when $cal : Calculation(wage > 0 && wagemore > 0 && wagemore > 0 && cess > 0) then $cal.setWageminus($cal.getWagemore()*$cal.getCess()-$cal.getPreminus()); $cal.setActualwage($cal.getWage()-$cal.getWageminus()); System.out.println("-----税前工资:"+$cal.getWage()); System.out.println("-----应纳税所得额:"+$cal.getWagemore()); System.out.println("-----税率:" + $cal.getCess()); System.out.println("-----速算扣除数:" + $cal.getPreminus()); System.out.println("-----扣税额:" + $cal.getWageminus()); System.out.println("-----税后工资:" + $cal.getActualwage()); end
第六步:创建RuleService
package com.itheima.drools.service; import com.itheima.drools.entity.Calculation; 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 Calculation calculation(Calculation calculation) { KieSession session = kieBase.newKieSession(); //获得session session.insert(calculation); //加入到规则内存 session.fireAllRules(); //启动所有规则 session.dispose(); //销毁session return calculation; //返回经历过规则的calculation } }
第七步:创建RuleController
package com.itheima.drools.controller; import com.itheima.drools.entity.Calculation; import com.itheima.drools.service.RuleService; import org.springframework.beans.factory.annotation.Autowired; 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("/calculate") public Calculation calculation(double wage) { Calculation calculation = new Calculation(); calculation.setWage(wage); calculation = ruleService.calculate(calculation); System.out.println(calculation); return calculation; } }
第八步:创建启动类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目录下
calculation.html
<!DOCTYPE html> <html> <head> <!-- 页面meta --> <meta charset="utf-8"> <title>个人所得税计算</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">个人所得税计算器(2011版)</h3> <table align="center" width="25%" border="0"> <tr> <td>税前月收入</td> <td> <input type="text" v-model="cal.wage"> </td> </tr> <tr> <td colspan="2"> <input type="button" value="计 算" @click="calculate()"> </td> </tr> <tr> <td colspan="2" align="center"> </td> </tr> <tr> <td>应纳税所得额</td> <td> <input type="text" v-model="cal.wagemore"> </td> </tr> <tr> <td>税率</td> <td> <input type="text" v-model="cal.cess"> </td> </tr> <tr> <td>速算扣除数</td> <td> <input type="text" v-model="cal.preminus"> </td> </tr> <tr> <td>扣税额</td> <td> <input type="text" v-model="cal.wageminus"> </td> </tr> <tr> <td>税后工资</td> <td> <input type="text" v-model="cal.actualwage"> </td> </tr> </table> </div> </body> <!-- 引入组件库 --> <script src="js/vue.js"></script> <script src="js/axios.js"></script> <script> new Vue({ el: '#app', data:{ cal:{} }, methods: { calculate(){ if(this.cal.wage <= 3500){ alert("税前月收入需要大于3500!"); return; } axios.get("/rule/calculate?wage=" + this.cal.wage).then((res) => { console.log(res); this.cal = res.data; }); } } }); </script> </html>
第十步:测试:http://127.0.0.1:8080/calculation.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