1. 项目背景与核心价值
记账这件事,我从大学时代就开始折腾了。最早用Excel手工记录,后来试过各种记账App,但总感觉差点意思——要么功能太简单,要么数据不透明,要么就是突然收费。去年终于下定决心,自己开发一套全栈记账系统,既能满足个性化需求,又能作为全栈技术的练手项目。
这套系统经过半年迭代,现在已经稳定运行了8个月,累计记录交易4000+笔。最大的价值在于:1) 完全掌控数据所有权 2) 可定制任何特殊记账场景 3) 打通了消费分析的全链路。比如我可以自定义"奶茶消费警戒线"这样的特色功能,这是商业软件永远做不到的。
2. 技术架构设计
2.1 整体技术栈选型
前端采用React+TypeScript组合,主要考虑:
- 组件化开发适合频繁交互的记账场景
- TypeScript的强类型能避免金额计算这类低级错误
- 生态丰富(用了MUI组件库加速开发)
后端选择NestJS框架,因为:
- 模块化架构适合业务逐渐复杂的情况
- 内置TypeScript支持与前端的完美配合
- 企业级应用常用的成熟框架
数据库选了PostgreSQL,看中其:
- JSONB类型完美存储动态的交易附加信息
- 强大的分析函数支持复杂报表统计
- 事务特性确保资金计算的绝对准确
2.2 关键架构决策
采用BFF(Backend For Frontend)模式,在前后端之间增加了GraphQL层。实测发现三个优势:
- 前端可以精确获取所需字段,减少接口请求量
- 一次查询即可获取关联数据(如交易+分类+账户)
- 类型系统自动生成,前后端协作效率提升30%
// 典型GraphQL查询示例 query GetTransactions { transactions(dateRange: "2023-07") { id amount category { name icon } account { name } memo } }3. 核心功能实现细节
3.1 交易记录引擎
开发中最复杂的部分,需要考虑:
- 多币种处理(自动汇率转换)
- 分期交易拆分(如年费按月分摊)
- 转账交易的借贷平衡校验
解决方案是采用"事务+事件溯源"模式:
- 每个交易作为独立事务记录
- 状态变更生成事件流
- 通过重放事件重建账户余额
(注:根据规范要求已移除mermaid图表,改为文字说明) 流程说明: 1. 用户提交交易表单 2. 服务端验证并生成交易记录 3. 同步生成AccountBalanceUpdated事件 4. 事件处理器更新账户余额 5. 异常时触发事务回滚3.2 自动化记账功能
实现了三类自动化规则:
- 模板记账:固定场景快速记录(如每日咖啡)
- 智能识别:通过备注关键字自动分类
- 银行同步:对接支付宝/微信账单API
重要经验:自动化规则一定要加人工确认环节!初期因为规则冲突导致过错误分类,后来改为"建议+确认"模式才稳定。
4. 数据分析模块
4.1 实时统计实现
利用PostgreSQL的窗口函数,实现了:
- 实时消费趋势图(按日/周/月)
- 预算执行进度监控
- 同类消费对比分析
-- 周消费统计SQL示例 SELECT date_trunc('week', date) AS week, SUM(CASE WHEN type='expense' THEN amount ELSE 0 END) AS spending FROM transactions GROUP BY week ORDER BY week DESC LIMIT 12;4.2 自定义报表系统
开发了类Excel的报表设计器,支持:
- 拖拽字段生成透视表
- 自定义计算公式
- 条件格式设置(如超支标红)
实测比商业软件更灵活,比如可以计算: "奶茶支出 / 总餐饮支出 × 100%" 这样的个性化指标
5. 部署与运维方案
5.1 基础设施配置
使用Docker Compose编排服务:
- 前端静态资源托管在Nginx
- 后端服务启用PM2集群模式
- 数据库配置定期备份任务
# docker-compose片段 services: db: image: postgres:14 volumes: - pg_data:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: ${DB_PASSWORD}5.2 监控与告警
实现了三级监控体系:
- 前端:Sentry收集异常
- 后端:Prometheus采集指标
- 数据库:慢查询日志分析
最实用的自定义指标是"记账延迟报警"——当超过24小时没有新记录时,推送提醒到手机。
6. 踩坑经验实录
6.1 金额计算的精度问题
初期直接使用JavaScript的Number类型,导致出现:
0.1 + 0.2 // 0.30000000000000004解决方案:
- 后端使用PostgreSQL的numeric类型
- 前端引入decimal.js库
- 全链路统一以"分"为单位存储整数
6.2 数据迁移的血泪史
从旧系统迁移时犯过的错:
- 直接INSERT导致ID冲突
- 忘记转换日期时区
- 分类映射表不完整
最终方案:
- 使用临时表过渡
- 编写校验脚本核对总数和总额
- 分批次迁移并人工抽检
7. 项目成果与迭代计划
目前系统日均使用3-5次,核心指标:
- 交易记录成功率:99.8%
- 报表生成速度:<2s(万级数据)
- 移动端适配完成度:90%
下一步重点:
- 增加多设备同步功能
- 开发消费预测AI模型
- 完善API开放平台
这套系统给我最大的启示是:工具应该适应人,而不是人适应工具。现在我的记账流程从原来的每周痛苦1小时,变成了每天顺手3分钟,这才是真正可持续的个人财务管理方式。