# bill **Repository Path**: lucasey/bill ## Basic Information - **Project Name**: bill - **Description**: 个人记账系统:Kotlin+Spring Boot+SQLite 后端,Vue3+ECharts 前端,支持自定义收支分类、多维度统计、CSV 导出,docker compose 一键部署 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 6 - **Forks**: 0 - **Created**: 2026-08-29 - **Last Updated**: 2026-09-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 📒 记账本 · 个人记账系统 一个简单实用的个人记账 Web 应用,支持**家庭多账号**、**自定义收支分类**、**账单记录**和**多维度统计**。 前后端打包为单个 jar,数据存 SQLite(单文件),一条 `docker compose up -d` 即可部署(适配飞牛 fnOS 等 NAS)。 当前版本:**v1.5**(更新日志见文末) ![总览页](gui-test-screenshots/t1_dashboard_ro.png) ## ✨ 功能特性 - **账号与家庭**:注册/登录,一人创建家庭、家人凭邀请码加入;账单按家庭共享,记录人一目了然 - **记一笔**:支出/收入/转账三合一、大金额输入、图标分类宫格选择、资金账户选择、日期、「给谁花」、备注 - **账户体系(v1.3,随手记风格)**: - 账户分组:现金 / 储蓄 / 虚拟 / 负债 / 债权 / 信用 / 投资,信用卡等负债账户期初可填负数 - 余额自动计算:期初 + 收入 − 支出 − 转出 + 转入;总资产 / 总负债 / 净资产汇总 - **转账类型**:还信用卡、账户间挪钱不再计入收支统计,解决「上月刷卡本月还款被重复记为花销」的问题 - **日历(v1.5)**:月历展示每日收支与待还标记(信用卡还款日 / 贷款月供),点击某天弹窗查看当天账单与待还明细 - **还款自动核销(v1.5)**:记一笔转入信用卡/负债账户的转账,自动按还款日先后冲抵该账户的待还账单(含分期),修改/删除转账自动回退,杜绝「已还还提醒」的重复统计 - **分期时间轴(v1.5.2)**:点击已分期/已出账的消费查看详情,逐期展示还款计划(每期金额含手续费分摊、已还/待还、未来期次的还款日);此类消费锁定不可修改删除 - **自动出账(v1.5)**:信用卡等到账单日自动把周期消费合并成账单,无需(也不能)手动出账 - **账单明细**:按日分组展示 + 日小计、月份/类型/分类/账户/成员/关键词筛选、分页、一键导出 CSV(Excel 打开不乱码);电脑端可拖动账单条目调整当日顺序 - **多维度统计**: - 按月 / 按年 / 自定义时间范围 - 时间趋势(日粒度折线图 / 月粒度柱状图) - 分类排行(金额、笔数、占比进度条) - **成员对比**(各成员收支横条图)、**给谁花排行**、收支占比环形图、收支结余汇总卡片 - **排行/成员条目可点击**,直接跳转账单页查看对应明细 - **分类管理**:自定义收支分类,40+ emoji 图标 + 12 色主题,删除保护(有账单的分类不可删) - **响应式**:桌面侧边栏 / 手机底部导航自适应,手机上也好用 - **数据安全**:SQLite 单文件存储,金额以「分」为整数存储避免浮点误差;备份一个文件即备份全部数据 - **平滑升级**:内置 SchemaMigrator,旧版本数据库自动补列/重建,历史数据无损迁移 ## 🛠️ 技术选型 | 层 | 技术 | |----|------| | 后端 | Kotlin 1.9 + Spring Boot 3.3 + spring-jdbc(轻量 SQL,无 ORM) | | 数据库 | SQLite(WAL 模式,单文件免部署) | | 账号 | Servlet Session + BCrypt 密码哈希(spring-security-crypto) | | 前端 | Vue 3(全局构建,免编译)+ ECharts 5,静态资源由后端直接托管 | | 构建 | Maven(阿里云镜像加速) | | 部署 | Docker 多阶段构建 + docker compose | ## 📂 项目结构 ``` bill/ ├── backend/ │ ├── pom.xml │ └── src/main/ │ ├── kotlin/com/bill/ │ │ ├── BillApplication.kt # 入口 │ │ ├── common/ # 异常处理 / 参数校验 / 登录拦截 / 数据迁移 │ │ ├── model/ # 数据模型 │ │ ├── repo/ # 数据访问(JdbcTemplate) │ │ └── web/ # REST 控制器(含认证 AuthController) │ └── resources/ │ ├── application.yml │ ├── schema.sql # 建表脚本(幂等) │ └── static/ # 前端 SPA(Vue + ECharts) │ ├── index.html │ ├── css/app.css │ ├── vendor/ # vue / echarts 本地文件,内网可用 │ └── js/ # utils / api / ui / charts / views ├── Dockerfile # 多阶段构建 ├── docker-compose.yml └── README.md ``` ## 🚀 飞牛 fnOS 部署(docker compose) 1. 把整个 `bill` 文件夹上传到 NAS,例如 `/vol1/1000/docker/bill` 2. 打开 fnOS 的 **Docker** 应用 → **Compose** → **新增项目**,路径选择 `bill` 文件夹(内含 `docker-compose.yml`),点击构建并启动 - 或者 SSH 到 NAS 执行: ```bash cd /vol1/1000/docker/bill docker compose up -d --build ``` 3. 浏览器访问 `http://NAS的IP:8080` 即可使用 4. 端口被占用时,修改 `docker-compose.yml` 里 `"8080:8080"` 左侧的端口 > 💡 Dockerfile 默认从 `docker.m.daocloud.io` 拉取基础镜像(国内可直连);若它失效,把 `docker-compose.yml` 里 `REGISTRY` 换成 `docker.1ms.run` 等即可。 > 首次构建需下载 Maven 依赖(已配置阿里云镜像),之后重新构建会利用 Docker 层缓存,速度很快。 ### 数据备份 / 迁移 所有数据都在 `bill/data/bill.db` 一个文件里(SQLite)。 备份 = 停止容器后复制该文件;迁移 = 把整个文件夹拷到新机器再启动。 ## 💻 本地开发运行 环境要求:JDK 17 + Maven 3.9(国内建议配置阿里云镜像)。 ```bash cd backend mvn package -DskipTests java -jar target/bill.jar --server.port=8080 # 数据库默认落在 ./data/bill.db,可用环境变量 BILL_DB_PATH 覆盖 ``` 打开 http://localhost:8080 ,首次使用在注册页创建账号:第一个人选「创建新家庭」,家人选「加入家庭」填邀请码(登录后点左下角用户区可查看/复制邀请码)。 ### 👨‍👩‍👧 账号与家庭 - 数据按**家庭**隔离:分类、账单、统计都是全家共享;每笔账单记录记录人 - 侧边栏底部用户区:查看家庭信息(成员/邀请码)、修改密码、退出登录 - 老版本升级:启动时自动迁移旧数据(补家庭字段并归入「我的家庭」),无需手动处理 ## 🔌 API 一览 | 方法 | 路径 | 说明 | |------|------|------| | POST | `/api/auth/register` | 注册(创建家庭 / 邀请码加入),成功即登录 | | POST/GET | `/api/auth/login` · `/api/auth/logout` · `/api/auth/me` | 登录 / 登出 / 当前用户 | | GET | `/api/auth/family` | 家庭信息(名称、邀请码、成员列表) | | PUT | `/api/auth/password` | 修改密码 | | GET | `/api/categories?type=EXPENSE\|INCOME` | 分类列表(含账单数) | | POST/PUT/DELETE | `/api/categories[/{id}]` | 分类增改删(有账单时删除返回 409) | | GET | `/api/bills?page&size&type&categoryId&accountId&userId&payee&start&end&keyword` | 账单分页筛选(keyword 搜备注/给谁花/分类;v1.5 起按 `tx_date + sort_no` 排序) | | POST/PUT/DELETE | `/api/bills[/{id}]` | 账单增改删;已出账/已分期的消费改删返回 409(v1.5.2 锁定) | | POST | `/api/bills/reorder` | 同日内账单拖拽排序(body `{ids:[...]}`,v1.5) | | GET | `/api/bills/payees` | 家庭内用过的「给谁花的」名字(按使用次数排序,用于补全) | | GET | `/api/bills/export?...` | 按筛选导出 CSV(带 BOM,列:日期,类型,分类,账户,金额(元),记录人,给谁花,备注) | | GET | `/api/accounts` / POST/PUT/DELETE | 账户列表(含余额)/ 增改删(v1.3;信用账户支持 `billDay`/`dueDay`) | | GET | `/api/credit/summary` | 信用/负债账户统计:本周期消费、未结清、本月应还(v1.4) | | GET | `/api/credit/accounts/{id}/statements` | 某卡的周期账单列表(v1.4) | | POST | `/api/credit/statements/{id}/install` · `/pay` · `/unmerge` | 账单分期 / 还款(`all:true` 提前结清)/ 撤销合并(v1.4) | | POST | `/api/credit/bills/{billId}/install` | 单笔消费分期(v1.4.3) | | GET | `/api/credit/bills/{billId}/schedule` | 分期时间轴:每期还款日/金额/已还状态(v1.5.2) | | GET/POST | `/api/loans[/{id}]` | 贷款固定项增改删(v1.4) | | GET/PUT | `/api/budget` · GET `/api/budget/status` | 预算保存与执行状态(风险线/今日可用/还款提醒,v1.4) | | GET/PUT/DELETE | `/api/salary[/{userId}]` | 按成员工资固定发放配置(v1.4.3) | | GET | `/api/calendar?month=YYYY-MM` | 日历:每日收支汇总 + 每日待还(信用卡还款日、分期每期逐月投影、贷款月供,v1.5) | | GET | `/api/stats/summary?start&end` | 区间收支汇总 | | GET | `/api/stats/trend?start&end&granularity=day\|month` | 时间趋势 | | GET | `/api/stats/category?start&end&type=` | 分类统计排行 | | GET | `/api/stats/member?start&end` | 成员收支对比 | | GET | `/api/stats/payee?start&end&type=` | 给谁花排行(total 单位分,未填 payee 的账单不计入) | - 除 `/api/auth` 外的接口均需登录(Session Cookie),未登录返回 401 - 金额:请求用元(最多两位小数),存储/返回用分(整数),前端负责格式化 - 错误统一返回 `{"message": "..."}` + 对应 HTTP 状态码 ## ✅ 质量验证 - 单元测试 31 项全部通过(预算风险线、账单日自动出账与周期边界、分期金额/期数推进/回退、 还款自动核销与撤销、日历分期逐月投影、参数校验、旧库迁移) - 浏览器实测:登录/注册、总览(预算/提醒/图表)、账单(筛选/拖拽排序/详情时间轴)、日历(待还标记/单日弹窗)、 账户(信用周期/还款/分期)、家庭信息、修改密码 ## 📜 更新日志 - **v1.5(2026-09)** - 新增**日历模块**:月历展示每日收支与待还标记(信用卡还款日 / 分期每期逐月投影 / 贷款月供),点某天弹窗看当天账单与待还明细 - **还款自动核销**:记一笔转入信用/负债账户的转账,自动按还款日先后冲抵待还账单(含分期按期推进、支持部分还款),修改/删除转账自动回退;「还款/提前结清」按钮与普通转账走同一套核销 - **自动出账**:到账单日当天自动生成周期账单,移除手动出账接口与按钮 - **分期时间轴**:点击已分期/已出账的消费查看详情,逐期展示还款计划;此类消费锁定不可修改删除 - 转账支持选择日期;电脑端账单页可**拖拽调整当日顺序**(`sort_no` + reorder 接口) - 修复总览页工资弹窗模板嵌套损坏与重复的还款提醒 - **v1.4.x**:月度预算与风险线、贷款固定项、信用卡周期账单(分期/提前结清/持续提醒)、按成员工资固定发放、单笔消费分期 - **v1.3**:账户体系(随手记风格分组、余额自动计算、总资产/净资产)、转账类型(还款不计支出)、统计排行点击跳转 - **v1.2**:「给谁花」记录与统计、payees 自动补全接口 ## 📄 License MIT