本地优先(Local-First)的个人/家庭记账软件,采用 Vue 3 + 小米风格设计,支持未来扩展桌面端与多端同步。
Tally 是一款面向 20–35 岁用户的开源记账工具,以"你的数据,你的选择"为原则。数据全部存储在浏览器本地的 IndexedDB,无强制账号、不依赖云端,后续可按需接入 WebDAV / Git 仓库 / 自托管服务进行跨设备同步。
当前版本为 MVP(最小可用原型),已覆盖日常记账、预算追踪和收支分析等核心场景,视觉风格参考小米 / HyperOS 设计语言(克制、大圆角、橙色素系、卡片化)。
完整设计思路见 Tally-技术架构文档、记账需求调研报告 与 Tally-UI组件结构说明。
| 模块 | 功能 |
|---|---|
| 💰 概览 Dashboard | 本月收支、结余、储蓄率、预算进度、最近 5 笔流水 |
| 📒 账本 Ledger | 按日期分组的流水列表;支持按时间/类型/分类/账户筛选;新增、编辑、删除流水 |
| 📊 分析 Analysis | 收支趋势折线图、分类支出占比(环图)、预算偏差对比、任意日期区间 |
| 💸 预算 Budget | 总预算与分类预算;进度条实时跟踪(0–79% 橙、80–99% 黄、100%+ 红) |
| ➕ 记一笔 | 支持支出 / 收入 / 转账;金额自动处理为"分"避免浮点误差;校验必填字段 |
| 📚 多账本 | 支持个人/家庭/经营/旅行等多账本独立核算 |
| 🏦 多账户 | 现金、银行卡、电子钱包三类账户,余额随流水动态计算 |
| 🏷️ 分类体系 | 内置收入/支出分类,支持自定义颜色 |
| 💾 本地存储 | 浏览器 IndexedDB(Dexie 封装),支持离线首次使用即灌入示例数据 |
- Tauri 2.x 桌面端:零平台适配成本的桌面安装包(Windows / macOS / Linux)
- CRDT 同步引擎(Yjs):离线优先 + 自动冲突合并
- 同步通道:WebDAV、GitHub 私密仓库、自托管 Tally Cloud
- PWA 形态:一键安装、Service Worker 离线缓存
- 账单导入:微信 / 支付宝 / 银行 CSV 解析 + 智能去重
- AI 能力:智能分类、语音/图片记账、消费洞察
| 层级 | 选型 | 用途 |
|---|---|---|
| 框架 | Vue 3 + <script setup> + TypeScript |
前端主框架 |
| 构建 | Vite | 开发与生产构建 |
| 状态 | Pinia | 全局状态管理(账本、流水、预算等) |
| 路由 | Vue Router | 多视图 SPA 导航 |
| 存储 | IndexedDB + Dexie | 本地结构化数据持久化(大容量、异步、事务) |
| 图表 | ECharts | 趋势、占比、预算偏差图 |
| 样式 | 原生 CSS + 设计 Token | 小米风格视觉规范 |
| 测试 | Vitest | 领域逻辑单元测试 |
| 代码规范 | ESLint + typescript-eslint + eslint-plugin-vue | 静态检查 |
| 类型检查 | vue-tsc | 编译期类型校验 |
| 未来桌面壳 | Tauri 2.x | Rust + 系统 WebView,安装包 3–15MB |
Tally/
├── docs/superpowers/specs/ # 规格与设计文档
├── src/
│ ├── components/ # 通用组件(DateRangePicker、DateTimeField)
│ ├── router/ # Vue Router 路由定义
│ ├── stores/ # Pinia 状态(tally.ts:统一账本 store)
│ ├── styles/ # 全局样式与 Token
│ ├── views/ # 页面视图
│ │ ├── OverviewView.vue # 概览仪表盘
│ │ ├── LedgerView.vue # 账本流水
│ │ ├── AnalysisView.vue # 分析报表
│ │ └── BudgetView.vue # 预算管理
│ ├── App.vue # 根组件(导航外壳 + 视图挂载)
│ ├── db.ts # Dexie 数据库定义 + 种子数据
│ ├── domain.ts # 领域模型、金额/日期/过滤等纯函数
│ ├── domain.test.ts # 领域逻辑单元测试
│ ├── env.d.ts # 类型声明
│ └── main.ts # 应用入口
├── .gitignore
├── eslint.config.js
├── index.html # Vite 入口 HTML
├── package.json
├── tsconfig.json
├── vite.config.ts # Vite + Vitest 配置
└── 技术架构/调研报告/UI 说明文档
- Node.js ≥ 18
- 包管理器:项目使用 npm,可按需换成 pnpm / yarn
npm installnpm run dev打开后会自动初始化本地数据库并注入一套示例数据(示例账本、分类、账户与若干笔流水),便于直接浏览全部页面效果。
npm run typechecknpm run lintnpm run testnpm run build构建产物输出到 dist/ 目录,可直接部署到任意静态站点(Cloudflare Pages、Nginx、Vercel 等),或后续由 Tauri 壳打包为桌面安装包。
所有金额统一以 "分" 为单位存储为整数,避免 JavaScript 浮点精度问题;格式化展示时再换算为元。详见 domain.ts。
// 六大核心实体(简略)
interface Book { id; name; currency } // 账本
interface Account { id; bookId; name; type; balanceCents } // 账户
interface Category { id; bookId; name; kind; color } // 分类
interface Transaction {
id; bookId; type: 'expense'|'income'|'transfer'
amountCents; categoryId; accountId; targetAccountId?
note; occurredAt
}
interface Budget { id; bookId; name; amountCents; categoryId?; month }
interface FilterState { startDate; endDate; type; categoryId; accountId }全局状态与数据操作集中在 Pinia Store:tally.ts,包含增删改、校验、月度统计、分类花费聚合等能力。
- 克制(Less is More):减少装饰,强化信息层级。
- 大圆角:卡片 16px,按钮/输入框 12px。
- 大字号:标题 ≥ 18px,正文 15–16px,弱化信息 13px。
- 橙色素系:主色
#FF6700,辅以白、浅灰与强分隔卡片。 - 正负表达:除颜色外,金额前必须加
+/-号或文字标签,保证状态可感知。 - 响应式:≥1024px 左侧导航,<1024px 底部 Tab Bar,<640px 单列卡片。
完整规范:Tally-UI组件结构说明。
- 默认本地存储:数据仅存在当前浏览器的 IndexedDB,不上传任何服务器。
- 示例数据:首次使用自动注入的样例数据仅用于体验,可随时删除。
- 后续同步能力:计划接入端到端加密;服务器(若使用)仅存储密文,不可见明文财务数据。
本项目目前处于 MVP 阶段,欢迎以 Issue 或提交代码的方式参与贡献:
- Fork 本仓库并创建新分支。
- 执行
npm run lint && npm run typecheck && npm run test确保全部通过。 - 提交清晰的变更说明与对应的测试/文档更新。
Copyright © 2026 项目贡献者
本项目基于 GNU General Public License v3.0 开源。