从"记账坚持不下来"到自研记账软件:架构、数据建模与三大踩坑实录

举报
yd_294377644 发表于 2026/10/15 09:21:00 2026/10/15
【摘要】 市面上记账 App 很多,但我总在用两三个月后放弃——要么广告多,要么功能臃肿,要么担心我的收支数据被上传。于是我从零开发了一款**本地优先(Local-First)**的记账软件,从需求梳理、数据建模、快速记账交互到图表统计,走完了完整闭环。这篇文章记录我的技术选型思路、数据模型设计,以及三个印象深刻的踩坑。

目录

  1. 缘起:为什么自己做一款记账软件
  2. 技术选型:本地优先 + 一个浏览器可以是所有平台
  3. 核心难点一:记账的数据模型怎么设计
  4. 核心难点二:金额、日期与"精度"的博弈
  5. 交互设计:让记账"快"到不打断生活
  6. 统计图表:数据的作用是让人看清,而不是吓人
  7. 三个值得分享的实战经验
  8. 结尾:给同样想做工具型产品的你

1. 缘起:为什么自己做一款记账软件

我记过很多次账,有些坚持了三个月,有些坚持了三天。

放弃的原因很统一:记账的动作太"重"了。要打开 App、等启动页、点"记一笔"、选分类、输金额、确定……一套流程下来十几秒,而大多数消费场景只有几秒钟的心力。加上隐私顾虑——把全年收支交给一家商业公司,心里总不踏实。

于是我想:能不能做一款 「打开就想记、3 秒完成一笔、数据 100% 留在本地」 的记账软件?

我给自己定了三条硬约束:

  1. 本地优先:数据存本机,不强制注册不强制上传,支持一键导出;
  2. 3 秒记一笔:主界面就是记账入口,快捷键 + 键盘数字直接输入金额,回车即保存;
  3. 足够轻:单 Web 应用,桌面浏览器、手机浏览器都能开,功能克制,不做社交不做社区。

2. 技术选型:本地优先 + 一个浏览器可以是所有平台

技术栈我选得很"保守",核心就一句话:能用浏览器原生能力解决的不引库,能本地存的绝不上云。

模块 方案 理由
界面 原生 Web(HTML/CSS/JS) 无框架成本,启动快,双端同源
存储 IndexedDB 封装 本地结构化存储,容量以 GB 计
导出 Blob + a[download] 一键导出 CSV/备份 JSON,数据主动权在用户
图表 自绘 Canvas 记账图表场景简单,不必引入重型图表库
同步 可选 JSON 文件导入 官方不做云同步,天生无账号体系

"本地优先"有代价,但要想清楚。它最大的收益是隐私和稳定性,最大的代价是多端共享难。我的解决思路是:本地为主,Excel/CSV 导出兜底,有同步需求时手动手工导入导出即可。工具型产品,信任成本有时比便利更重要。

3. 核心难点一:记账的数据模型怎么设计

看起来记账就是"收入/支出 + 金额 + 分类",但深入之后会发现没那么简单。我最终的数据模型是这样设计的:

账本 (Ledger)                     账单 (Record)
 ├─ id                          ├─ id
 ├─ 名称、币种                    ├─ 类型: income / expense / transfer
 └─ 预算项列表                    ├─ 金额(整数分)、日期、备注
                                ├─ 分类 id、账户 id、账本 id
                                ├─ 标签 ids
                                └─ createdAt、updatedAt

关键设计决策有三个:

1. 分类不是固定的树,而是"可配置的标签 + 默认模板"。 硬编码"餐饮/交通/购物"的分类树听起来合理,但每个人记账思维不同。我更推荐:内置一套高频默认分类,同时允许用户自定义标签。记账时分类负责快速归类,标签负责"查为什么"(比如 #给爸妈、#出差报销)。

2. 转账也是账单。 转账(transfer)很容易被忽略,但它会同时影响两个账户的余额。把它当作第三种账单类型而不是"特殊支出",统一进一套查询逻辑,账户余额计算才不出错。

3. 绝对不要把类型和分类互相耦合。 有不少失败的设计会把分类表拆成"支出分类表""收入分类表"两张表,导致日后想更改分类体系时改哪张都别扭。分类只挂账单类型这一个维度,永远分开存。

4. 核心难点二:金额、日期与"精度"的博弈

这是我踩坑最深的部分,具体有三个:

踩坑 A:金额千万别用浮点。 0.1 + 0.2 !== 0.3 在 JS 里是常识,但写业务代码时还是会顺手用 Number。正确做法是以「分」为最小单位存整数,展示时再除以 100。我用了一个 Money 工具函数统一处理输入输出,界面输入元,存储分,计算全走整数——配合统计一个季度才发现,之前累计误差能到"分"这个维度并不夸张。

// 示范:统一金额处理
const yuanToFen = (y) => Math.round(Number(y) * 100);
const fenToYuan = (f) => (f / 100).toFixed(2);

踩坑 B:时区会影响"今天"这个判断。 很多人记录"今天花钱",但哪天开始的"今天"?用本机时区判断没问题,但如果数据被导出、导入到另一个时区,日期可能错位。我的做法是:所有日期按本机时区转成 YYYY-MM-DD 字符串存,而不是存时间戳,这样报表以"自然日"为单位的统计永远稳定。

踩坑 C:导入数据要去重。 支持导入 CSV/备份后,最大的问题变成"重复导入"。我给每条账单生成一个基于(时间+金额+分类+备注)的唯一键,导入前先查重。否则用户手动导入两次,当月支出就翻倍——这对记账软件的信任是毁灭性的。

5. 交互设计:让记账"快"到不打断生活

功能做完了,我发现最重要的其实是交互。记账 App 留存率低的根因是每次记账的心智负担。

我的主界面长这样(布局示意):

┌──────────────────────────────────┐
│  [支出] [收入] [转账]       今日总额  │
│  ┌─────────────┐   ┌────────┐    │
│  │  金额输入框    │   │ 分类快捷│    │
│  │  (数字占用    │   │ 面板    │    │
│  │  外设键盘)    │   │         │    │
│  └─────────────┘   └────────┘    │
│  [备注(可选)]  [保存]             │
└──────────────────────────────────┘

设计原则只有一条:默认路径 0 次鼠标点击输入。

  • 页面加载即聚焦金额输入框,直接敲数字不用点任何东西;
  • 分类用"快捷面板"展示(最近使用优先),一次点击选中;
  • "保存"绑定回车键,全程键盘完成;
  • 记账成功后不弹提示、不跳转,就地清空并重新聚焦,方便连续记多笔;
  • 支持"最近一笔一键复记"(很多账单是重复的,比如每天咖啡)。

心得:记账工具竞品拼的不是功能,是"每秒能省多少操作"。每多一次点击,就多一个流失的理由。

6. 统计图表:数据的作用是让人看清,而不是吓人

统计功能我坚持"克制"。做了三个,不贪多:

  1. 月度收支概览:本月收入/支出/结余 + 环比;
  2. 分类占比(环形图):支出按分类占比,一眼看清钱花在哪;
  3. 支出趋势线:最近 6 个月月度支出曲线,看趋势不看细节。

没有做"记账风格分析"“花钱星座”"财富等级"之类花哨的东西——那些是运营增长的手段,不是用户决策需要的。数据产品的本分,是让人在 5 秒内看清自己财务状况,而不是生成一张需要解读的"艺术品"。

7. 三个值得分享的实战经验

经验一:先画好"数据是主人的"底线,再写代码。 免费试用、可导出、不留隐私后门——这些不是营销话术,而是要写进架构层的设计。我的导出按钮从第一天就有,而不是最后补的。

经验二:表格(数据)和界面(视图)要分层。 我一开始把统计逻辑直接写在组件里,后来发现"月报表"“年度报告”"分类占比"三个视图要的其实是同一批聚合函数的不同切片。后来把聚合逻辑抽成独立的 stats.js,视图只负责渲染。这个重构让后续加功能顺畅了很多。

经验三:给"空白状态"设计价值。 新用户看到"暂无数据"一片空白时最容易流失。我设计了引导流程:首次打开就引导"先记第一笔收入",记完给个小小的正反馈。第一笔的成功体验,比任何新人优惠都有效。

8. 结尾:给同样想做工具型产品的你

这款记账软件最后没有做云端社交功能,但它的留存反而比很多商业软件好。原因可能是:当产品没有商业压力的绑架,它的每一条设计决策都回到了"用户到底需要什么"。

做个人工具型产品,我给的建议是:

  1. 少即是多:功能每多一项,主流程就重一分;
  2. 数据主权优先:能本地存的本地上存,导出能力从第一天就在;
  3. 把"记账很快"当成和"记账很准"一样重要的需求。

如果你也在做类似的工具,欢迎和我讨论数据建模或交互设计。工具小而美,价值往往不在大,而在于"每个细节上都替用户多想了一步"。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。