# LoanRepaymentTool **Repository Path**: java2job/loan-repayment-tool ## Basic Information - **Project Name**: LoanRepaymentTool - **Description**: 贷款还款明细工具 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-09-22 - **Last Updated**: 2026-09-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 贷款还款明细工具(Loan Instrument) 一个本地运行、仅面向 PC 端的贷款还款明细计算与展示工具。支持商业贷、公积金贷、组合贷,支持等额本息与等额本金,可在任意一期添加额外还款并按「缩短年限 / 减少月供 / 结清」自动重算后续每期明细,同时提供汇总卡片、图表与导出能力。 核心数据统一写入项目 `data/loan-data.json` 单文件,不依赖浏览器本地存储。 > 本工具计算结果仅供参考,最终以银行实际账单为准。 --- ## 功能特性 - **多贷款类型**:商业贷、公积金贷、组合贷(两笔分别计算后按期合并展示,期限可不同)。 - **两种还款方式**:等额本息、等额本金。 - **额外还款重算**:在某一期正常月供之后额外还本金,支持: - 缩短年限(月供 / 每期本金不变,减少剩余期数); - 减少月供(期数不变,降低每月还款额); - 结清(额外还款覆盖剩余本金,后续不再计息)。 - **还款对象**:可指定商贷、公积金、按比例分摊或直接结清。 - **每期备注**:备注不参与计算,随数据文件一并保存与导出。 - **汇总卡片**:贷款总额、原计划 / 提前还款后总利息与总还款额、节省利息、还清日期、剩余本金与利息、额外还款及违约金手续费合计等。 - **图表**:剩余本金曲线、每月还款构成(本金 vs 利息)、利息占比、提前还款前后对比、商贷与公积金占比。 - **导出**:导出 JSON / Excel / CSV。 - **从已还状态开始**:可设置已还期数、当前剩余本金、下一期还款日期。 - **尾差处理**:最后一期自动调整,保证剩余本金归零。 --- ## 技术栈 | 分类 | 选型 | |---|---| | 前端框架 | Vue 3 + TypeScript | | 构建工具 | Vite 6 | | UI 组件 | Element Plus(含 @element-plus/icons-vue) | | 状态管理 | Pinia | | 图表 | ECharts 5 | | 日期处理 | dayjs | | 导出 | xlsx(Excel / CSV),JSON | | 本地服务 | Node + Express 4 | | 数据存储 | 项目根目录 `data/loan-data.json` 单文件 | | 测试 | Vitest | 金额内部统一以「分」为整数单位计算,展示时转换为两位小数,避免浮点误差。 --- ## 环境要求 - Node.js 18+(代码使用 ES2022 语法) - npm(作为包管理器,依赖锁定于 `package-lock.json`) - 现代浏览器(Chrome / Edge 最新版) --- ## 快速开始 ```bash # 1. 安装依赖 npm install # 2. 启动开发环境(并行启动 Node 服务与 Vite 前端) npm run dev ``` 启动后: - 前端开发服务器: - 后端 API 服务: - Vite 已通过代理将 `/api` 请求转发到后端服务(见 `vite.config.ts`)。 在浏览器打开前端地址即可使用。首次运行时若 `data/loan-data.json` 不存在,服务端会自动创建 `data` 目录与默认空结构文件。 --- ## 常用脚本 | 命令 | 说明 | |---|---| | `npm run dev` | 并行启动后端服务(`server`)与前端(`client`),开发模式 | | `npm run client` | 仅启动 Vite 前端开发服务器 | | `npm run server` | 仅启动 Node 后端服务 | | `npm run build` | 使用 Vite 打包生产版本到 `dist/` | | `npm run start` | 启动生产服务(托管 `dist/` 静态文件并提供 API) | | `npm run test` | 运行单元测试(Vitest) | | `npm run typecheck` | TypeScript 类型检查(vue-tsc) | ### 生产运行 ```bash npm run build # 打包前端到 dist/ npm run start # Node 服务托管静态文件 + 提供 API ``` 生产模式下访问 ,数据仍写入项目 `data/loan-data.json`。 --- ## 项目结构 ```text LoanInstrument/ ├── data/ # 核心数据文件目录 │ └── loan-data.json # 单文件存储所有核心数据 ├── server/ │ └── index.js # Node + Express 本地服务(读写数据 / 托管静态文件) ├── src/ │ ├── api/ │ │ └── client.ts # 前端 API 客户端(fetchData / saveData) │ ├── components/ # Vue 组件 │ │ ├── TopBar.vue # 顶部栏:标题、保存状态、导出按钮 │ │ ├── LoanForm.vue # 贷款信息录入表单 │ │ ├── PartForm.vue # 单笔贷款(商贷/公积金)字段子表单 │ │ ├── SummaryCards.vue # 汇总卡片 │ │ ├── ChartsPanel.vue # 图表面板 │ │ ├── Echart.vue # ECharts 封装组件 │ │ ├── ScheduleTable.vue # 每期明细表 │ │ ├── ExtraPaymentDialog.vue # 额外还款弹窗 │ │ └── RemarkDialog.vue # 备注弹窗 │ ├── engine/ # 计算引擎(纯函数,可单元测试) │ │ ├── money.ts # 金额单位换算(元/分)与格式化 │ │ ├── rate.ts # 月利率、年金月供、剩余期数反推 │ │ ├── dates.ts # 还款日期推算与校验 │ │ ├── loanRuntime.ts # 单笔贷款运行时状态与额外还款处理 │ │ ├── schedule.ts # 生成每期还款明细(组合贷合并、重算) │ │ ├── summary.ts # 汇总统计(基准 vs 当前计划) │ │ └── validate.ts # 贷款方案与额外还款校验 │ ├── export/ │ │ └── exporters.ts # 导出 JSON / Excel / CSV │ ├── stores/ │ │ └── loanStore.ts # Pinia 状态:数据、计划、额外还款、备注、保存状态 │ ├── types/ │ │ └── loan.ts # 全局类型定义 │ ├── App.vue # 根组件 │ ├── main.ts # 应用入口 │ └── style.css # 全局样式 ├── tests/ │ └── engine.test.ts # 计算引擎单元测试 ├── index.html ├── vite.config.ts ├── tsconfig.json ├── package.json └── 需求.md # 需求规格说明书 ``` --- ## 架构与数据流 计算引擎为前端独立模块,采用纯函数实现,与数据读写、UI 解耦;Node 服务仅负责文件读写与静态托管,不参与贷款计算。 ```text 1. 前端启动 → GET /api/data 读取 data/loan-data.json 2. 用户录入贷款信息 / 额外还款 / 备注 3. 计算引擎(engine)生成每期明细,Pinia store 派生 schedule / summary 4. 用户保存 → PUT /api/data 写入单文件 5. 导出 → 前端直接生成 JSON / Excel / CSV 文件 ``` - `loanStore` 通过 `computed` 派生: - `schedule`:当前含额外还款的计划; - `baseline`:无额外还款的基准计划(用于前后对比); - `summary`:基于二者构建的汇总数据。 - 每期计算结果不写入数据文件,均由前端按需重新生成。 --- ## 后端接口 Node 服务仅监听本机 `127.0.0.1:3001`,只读写项目 `data` 目录。 | 方法 | 路径 | 说明 | |---|---|---| | GET | `/api/data` | 返回 `data/loan-data.json` 内容;文件不存在时自动创建默认结构并返回 | | PUT | `/api/data` | 请求体为完整数据对象,写入 `data/loan-data.json`(先写临时文件再原子重命名) | | GET | `/*` | 生产模式下托管 `dist/` 打包后的静态文件(`/api/` 除外) | 安全约束:仅监听本机、仅读写 `data` 目录、不允许路径穿越、不允许写入 `data` 目录之外的文件。 --- ## 数据结构 `data/loan-data.json` 示例: ```json { "version": 1, "loanPlan": { "type": "combination", "firstRepayDate": "2026-10-20", "repayDay": 20, "currentPaidPeriods": 0, "currentRemainingPrincipal": null, "nextRepayDate": null, "commercial": { "amount": 700000, "annualRate": 4.9, "years": 30, "method": "equalInstallment" }, "fund": { "amount": 300000, "annualRate": 3.1, "years": 30, "method": "equalInstallment" } }, "extraPayments": [ { "id": "uuid", "period": 12, "target": "commercial", "amount": 100000, "strategy": "shortenTerm", "penalty": 0, "fee": 0, "remark": "第12期提前还商贷10万", "ratio": null } ], "periodRemarks": { "1": "首期", "12": "提前还款" }, "createdAt": "2026-09-22T10:00:00.000Z", "updatedAt": "2026-09-22T10:00:00.000Z" } ``` 关键字段: | 字段 | 类型 | 说明 | |---|---|---| | `version` | number | 数据版本 | | `loanPlan.type` | string | `commercial` / `fund` / `combination` | | `loanPlan.repayDay` | number | 每月还款日 1-31,遇月末取月末 | | `loanPlan.commercial` / `fund` | object \| null | 单笔贷款信息(金额、年利率、年限、还款方式) | | `method` | string | `equalInstallment`(等额本息)/ `equalPrincipal`(等额本金) | | `extraPayments[].target` | string | `commercial` / `fund` / `ratio` / `settle` | | `extraPayments[].strategy` | string | `shortenTerm` / `reducePayment` / `settle` | | `periodRemarks` | object | 每期备注,key 为期数字符串 | > 保存内容仅包含贷款信息、额外还款记录、每期备注及时间戳;每期计算结果、图表数据、导出文件内容均不落盘。 完整类型定义见 [`src/types/loan.ts`](src/types/loan.ts)。 --- ## 计算规则要点 - **等额本息月供**:`M = P × r × (1+r)^n / ((1+r)^n - 1)`;`r = 0` 时 `M = P / n`。 - **等额本金每期本金**:`principal = P / n`,利息逐月递减。 - **月利率**:`r = 年利率 / 12`,固定利率、按整月计息,首期同样按整月计息。 - **缩短年限**:等额本息保持月供 `M` 不变反推剩余期数;等额本金保持每期本金不变减少期数。 - **减少月供**:剩余期数不变,重新计算月供 / 每期本金。 - **结清**:额外还款本金 ≥ 剩余本金时按剩余本金处理,后续期利息为 0,剩余本金与剩余利息归零。 - **剩余利息**:按当前计划继续还款,从下一期到最后一期的利息总和。 - **尾差**:最后一期本金 = 当前剩余本金,还款后剩余本金归零。 详细规则见 [`需求.md`](需求.md) 第 7 章「计算规则详述」。 --- ## 测试 ```bash npm run test # 运行计算引擎单元测试 npm run typecheck # TypeScript 类型检查 ``` --- ## 说明与边界 - 仅支持 PC 端,不做移动端适配。 - 本期只维护一个贷款方案,不做多方案对比(提前还款前后对比基于同一页面的基准计划生成)。 - 不支持账号登录、多设备同步、云端数据库。 - 不支持 LPR 浮动利率、每年调息、首期按实际天数计息。 - 浏览器无法直接写项目文件夹,所有数据读写均通过 Node 服务完成。