Thanks to visit codestin.com
Credit goes to github.com

Skip to content

xlorne/tax

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

个人所得税计算系统

一个全栈的个人所得税最优分配方案计算系统,包含后端 Spring Boot API 服务和前端 React Web 界面。该系统可以帮助用户找到年度工资和一次性奖励的最佳分配比例,以实现税费最小化。

功能特性

  • 📊 年度工资税计算:根据中国个人所得税累进税率计算年度工资应纳税额
  • 🎁 一次性奖励税计算:根据一次性奖励金额(除以12后)的月度税率计算应纳税额
  • 🎯 最优分配方案:自动计算年度工资和一次性奖励的最优分配比例,使总税费最小
  • 💰 精确计算:使用分为单位进行计算,避免出现分以下的精度问题
  • 高性能算法:提供全遍历和优化两种算法,平衡计算精度与性能
  • 🎨 现代化前端界面:基于 React + Ant Design 的友好用户界面

技术栈

后端

  • Java 17
  • Spring Boot 3.5.7
  • Maven
  • Lombok

前端

  • React 18.3
  • TypeScript 5.9
  • Ant Design 5.29
  • Rsbuild 1.6
  • Axios 1.13

项目结构

tax/
├── src/                              # 后端源代码
│   ├── main/
│   │   ├── java/com/codingapi/tax/
│   │   │   ├── controller/          # REST API 控制器
│   │   │   ├── model/               # 核心业务模型
│   │   │   │   ├── TaxCalculateContext.java  # 税费计算上下文
│   │   │   │   ├── TaxLayer.java             # 税率层级
│   │   │   │   └── TaxValue.java             # 税费结果
│   │   │   ├── pojo/                # 请求对象
│   │   │   ├── utils/               # 工具类
│   │   │   └── exception/           # 异常处理
│   │   └── resources/
│   │       ├── application.properties
│   │       └── static/              # 前端构建产物(构建后生成,已加入.gitignore)
│   └── test/                        # 测试代码
├── web/                             # 前端源代码
│   ├── src/
│   │   ├── api/                     # API 接口封装
│   │   │   └── index.ts
│   │   ├── App.tsx                  # 主应用组件
│   │   └── index.tsx                # 入口文件
│   ├── public/                      # 静态资源
│   ├── dist/                        # 前端构建产物(构建后生成,已加入.gitignore)
│   ├── rsbuild.config.ts            # Rsbuild 配置
│   ├── tsconfig.json                # TypeScript 配置
│   └── package.json                 # 前端依赖
├── scripts/                         # 构建脚本
│   └── package.sh                   # 一体化打包脚本(将前端打包到后端)
└── pom.xml                          # Maven 配置

税率说明

年度工资税率(7级累进)

级数 税率 速算扣除数 应纳税所得额
1 3% 0 不超过36,000元
2 10% 2,520 超过36,000至144,000元
3 20% 16,920 超过144,000至300,000元
4 25% 31,920 超过300,000至420,000元
5 30% 52,920 超过420,000至660,000元
6 35% 85,920 超过660,000至960,000元
7 45% 181,920 超过960,000元

一次性奖励税率(按月分摊后计算)

将一次性奖励除以12,然后按照以下税率计算:

级数 税率 速算扣除数 月应纳税所得额
1 3% 0 不超过3,000元
2 10% 210 超过3,000至12,000元
3 20% 1,410 超过12,000至25,000元
4 25% 2,660 超过25,000至35,000元
5 30% 4,410 超过35,000至55,000元
6 35% 7,160 超过55,000至80,000元
7 45% 15,160 超过80,000元

快速开始

环境要求

后端:

  • JDK 17 或更高版本
  • Maven 3.6 或更高版本

前端:

  • Node.js 16 或更高版本
  • pnpm(推荐)或 npm

安装依赖

后端:

# Maven 会自动下载依赖,无需手动安装

前端:

cd web

# 使用 pnpm(推荐)
pnpm install

# 或使用 npm
npm install

运行项目

方式一:开发模式(推荐)

1. 启动后端服务:

# 在项目根目录
./mvnw spring-boot:run

# 或使用 IDE 直接运行 TaxApplication 类

后端服务默认运行在:http://localhost:8090

2. 启动前端开发服务器:

# 在 web 目录
cd web
pnpm dev

# 或使用 npm
npm run dev

前端开发服务器默认运行在:http://localhost:8000

前端会自动代理 API 请求到后端(配置在 web/rsbuild.config.ts

方式二:一体化打包(生产模式)

使用打包脚本(推荐):

# 赋予脚本执行权限(首次运行)
chmod +x scripts/package.sh

# 执行打包脚本(会自动构建前端并复制到后端资源目录)
./scripts/package.sh

# 构建后端 JAR 包
./mvnw clean package

# 运行 JAR 包
java -jar target/tax-0.0.1-SNAPSHOT.jar

运行后访问 http://localhost:8090 即可同时访问前端界面和 API。

方式三:前后端分别构建(生产模式)

1. 构建后端:

# 在项目根目录
./mvnw clean package

# 运行 JAR 包
java -jar target/tax-0.0.1-SNAPSHOT.jar

2. 构建前端:

# 在 web 目录
cd web
pnpm build

# 预览生产构建
pnpm preview

构建产物位于 web/dist/ 目录,需要配合 Nginx 等静态服务器使用(详见部署说明)

配置

后端配置 (src/main/resources/application.properties):

server.port=8090

前端配置 (web/rsbuild.config.ts):

  • 前端开发服务器端口:8000
  • API 代理目标:http://127.0.0.1:8090

如需修改后端端口,需要同步更新前端代理配置。

使用指南

Web 界面使用

  1. 启动前后端服务(见快速开始章节)
  2. 打开浏览器访问 http://localhost:8000
  3. 输入参数
    • 个人应纳税额:需要计算的总金额(单位:元)
    • 已发工资:已经发放的工资,默认为 0(单位:元)
  4. 点击"计算最优税率"按钮
  5. 查看结果
    • 个人应纳税额
    • 推荐的年度工资
    • 年度工资税费
    • 一次性奖励金额
    • 一次性奖励税费
    • 最优总税金

API 接口使用

接口地址: POST /api/tax/calculate

请求示例:

curl -X POST http://localhost:8090/api/tax/calculate \
  -H "Content-Type: application/json" \
  -d '{
    "payableMoney": "200575.94",
    "salary": "0"
  }'

请求参数:

参数 类型 必填 说明
payableMoney String 个人应纳税额(总金额,单位:元)
salary String 已发工资(单位:元)

响应示例:

{
  "payableMoney": 200575.94,
  "salary": 164576.00,
  "oneRewardTax": 1080.00,
  "yearSalaryTax": 15995.20,
  "totalTax": 17075.20
}

响应字段说明:

字段 类型 说明
payableMoney BigDecimal 个人应纳税额
salary BigDecimal 推荐的年度工资
oneRewardTax BigDecimal 一次性奖励的税费
yearSalaryTax BigDecimal 年度工资的税费
totalTax BigDecimal 总税费(最小税费)

核心算法

计算原理

系统通过遍历所有可能的工资和奖励分配方案,找到使总税费最小的最优解。

  1. 全遍历算法 (calculateMinTax):

    • 以1元(100分)为步长遍历所有可能的分配方案
    • 计算每种方案的总税费
    • 返回税费最小的方案
    • 优点:结果绝对精确
    • 缺点:计算量大,适合金额较小的场景
  2. 优化算法 (calculateMinTaxPlus):

    • 第一阶段:粗略搜索(步长10元或1元,根据金额大小动态调整)
    • 第二阶段:精确搜索(在粗略最优值附近以1分为步长进行精细搜索)
    • 优点:计算效率高,结果精确度高(误差通常小于0.05元)
    • 缺点:极少数情况下可能不是绝对最优解

精度保证

  • 所有金额计算均转换为(整数)进行计算,避免出现分以下的单位(如厘)
  • 计算结果四舍五入到(保留2位小数)
  • 使用 BigDecimal 确保浮点数计算精度

代码示例

使用核心计算类

import com.codingapi.tax.model.TaxCalculateContext;
import com.codingapi.tax.model.TaxValue;
import java.math.BigDecimal;

// 获取计算上下文实例
TaxCalculateContext context = TaxCalculateContext.getInstance();

// 计算最优税费分配(全遍历算法)
TaxValue result = context.calculateMinTax(
    new BigDecimal("200575.94"),  // 个人应纳税额
    new BigDecimal("0")            // 已发工资
);

// 打印结果
result.print();

// 使用优化算法(推荐)
TaxValue resultPlus = context.calculateMinTaxPlus(
    new BigDecimal("200575.94"),
    new BigDecimal("0")
);

单独计算税费

// 计算年度工资税
Arithmetic yearTax = context.calculateYearSalaryTax(
    new BigDecimal("164576.00")
);
System.out.println("年度工资税: " + yearTax.getValue());

// 计算一次性奖励税
Arithmetic rewardTax = context.calculateOneRewardTax(
    new BigDecimal("35999.94")
);
System.out.println("一次性奖励税: " + rewardTax.getValue());

测试

项目包含完整的单元测试,使用 JUnit 5 和 CSV 参数化测试:

# 运行所有测试
./mvnw test

# 运行特定测试类
./mvnw test -Dtest=TaxCalculateContextTest

测试数据位于 src/test/resources/com/codingapi/tax/model/salary.csv

注意事项

  1. 金额单位:所有金额以为单位输入,系统内部转换为进行计算
  2. 精度限制:计算结果精确到(2位小数),不会出现分以下的单位
  3. 已发工资salary 参数表示已经发放的工资,系统会在此基础上计算剩余金额的最优分配
  4. 税率更新:如果税率政策发生变化,需要修改 TaxCalculateContext 中的税率层级配置

开发说明

前端开发

技术栈说明:

  • React:用于构建用户界面
  • TypeScript:提供类型安全
  • Ant Design:UI 组件库
  • Rsbuild:高性能的前端构建工具
  • Axios:HTTP 客户端

主要文件:

  • web/src/App.tsx:主应用组件,包含表单和结果显示
  • web/src/api/index.ts:API 接口封装
  • web/rsbuild.config.ts:构建配置,包含代理设置

开发命令:

cd web

# 启动开发服务器(自动打开浏览器)
pnpm dev

# 构建生产版本
pnpm build

# 预览生产构建
pnpm preview

修改 API 地址: 如需修改后端 API 地址,编辑 web/rsbuild.config.ts 中的代理配置:

server: {
  proxy: {
    '/api': 'http://127.0.0.1:8090',  // 修改这里的地址
  }
}

后端开发

修改税率: 如需修改税率,请编辑 src/main/java/com/codingapi/tax/model/TaxCalculateContext.java 中的以下方法:

  • initYearSalaryLayers():年度工资税率层级
  • initOneRewardTaxLayers():一次性奖励税率层级

算法优化: 如需调整优化算法的搜索策略,可修改 calculateMinTaxPlus() 方法中的:

  • roughStepInFen:粗略搜索步长
  • searchRangeInFen:精确搜索范围

开发命令:

# 编译项目
./mvnw clean compile

# 运行测试
./mvnw test

# 打包项目
./mvnw package

# 运行应用
./mvnw spring-boot:run

贡献

欢迎提交 Issue 和 Pull Request!

许可证

本项目采用 MIT 许可证。

部署说明

方式一:一体化打包部署(推荐)

将前端构建产物打包到后端 JAR 中,前后端一起运行,部署更简单。

使用打包脚本(推荐)

项目提供了自动化打包脚本 scripts/package.sh

# 赋予脚本执行权限(首次运行)
chmod +x scripts/package.sh

# 执行打包脚本
./scripts/package.sh

脚本执行流程:

  1. 进入 web 目录
  2. 安装前端依赖(pnpm i
  3. 构建前端(pnpm run build
  4. 删除后端 src/main/resources/static 目录(如果存在)
  5. 将前端构建产物 web/dist 复制到 src/main/resources/static

手动打包步骤

如果脚本无法执行,可以手动执行以下步骤:

# 1. 构建前端
cd web
pnpm install
pnpm run build

# 2. 返回项目根目录,将前端构建产物复制到后端资源目录
cd ..
rm -rf ./src/main/resources/static
cp -r ./web/dist/ ./src/main/resources/static

构建并运行

打包完成后,构建后端 JAR:

# 构建 JAR 包
./mvnw clean package

# 运行 JAR 包
java -jar target/tax-0.0.1-SNAPSHOT.jar

访问应用:

  • 前端界面:http://localhost:8090
  • API 接口:http://localhost:8090/api/tax/calculate

优势:

  • ✅ 前后端一体化部署,只需一个 JAR 文件
  • ✅ 无需配置 Nginx 等反向代理
  • ✅ 部署简单,适合容器化部署
  • ✅ Spring Boot 自动提供静态资源服务

方式二:前后端分离部署

前后端分别部署,适合需要独立扩展的场景。

后端部署

  1. 构建 JAR 包:
./mvnw clean package
  1. 运行 JAR 包:
java -jar target/tax-0.0.1-SNAPSHOT.jar
  1. 使用环境变量配置(可选):
SERVER_PORT=8090 java -jar target/tax-0.0.1-SNAPSHOT.jar

前端部署

  1. 构建前端:
cd web
pnpm install
pnpm build
  1. 部署 web/dist/ 目录到静态文件服务器(如 Nginx、Apache 等)

  2. 配置 Nginx 反向代理(示例):

server {
    listen 80;
    server_name your-domain.com;
    
    # 前端静态文件
    location / {
        root /path/to/web/dist;
        try_files $uri $uri/ /index.html;
    }
    
    # API 代理到后端
    location /api {
        proxy_pass http://localhost:8090;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

注意: 如果使用前后端分离部署,需要修改前端的 API 基础地址配置(web/src/api/index.ts),将 baseURL 改为后端服务器的实际地址。

项目亮点

  • 🎯 全栈解决方案:前后端分离架构,职责清晰
  • 💰 精确计算:基于分(整数)进行计算,避免浮点精度问题
  • 性能优化:智能搜索算法,平衡精度与性能
  • 🎨 用户友好:现代化 Web 界面,操作简单直观
  • 🧪 质量保证:完整的单元测试覆盖

更新日志

v0.0.1-SNAPSHOT

  • ✨ 初始版本发布
  • ✅ 实现年度工资税和一次性奖励税计算
  • ✅ 实现最优分配算法(全遍历和优化两种方式)
  • ✅ 使用分为单位进行计算,避免精度问题
  • ✅ 提供 RESTful API 接口
  • ✅ 完整的单元测试覆盖
  • ✅ React + Ant Design 前端界面
  • ✅ 前后端分离架构
  • ✅ 提供一体化打包脚本(scripts/package.sh),支持前后端一体化部署

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published