# Beancount Mobile 前端 UI 全面重设计 Spec

- 日期：2026-07-21
- 状态：已确认（经逐节评审）
- 范围：`src/app`、`src/components`、`src/theme`、`design-system/`；**不动** `src/domain`、`src/storage`、`src/services`、`plugins/`

## 1. 背景与问题

对现有 UI 的摸底发现以下问题（按严重度）：

1. **品牌色混乱**：代码主题 accent = 靛蓝 `#4F46E5`，`design-system/beancount-mobile/MASTER.md` 规定 CTA = 绿 `#059669`、背景深蓝 `#0F172A`（代码暗色实为 OLED 纯黑 `#040508`）。设计文档与实现脱节。
2. **图标体系三套并存**：Ionicons（主力）+ emoji 分类图标（CategoryPicker）+ MASTER.md 要求的 Lucide/Heroicons（未落地）。
3. **硬编码颜色绕过 token**：首页 Hero 卡片写死白字；`CATEGORY_COLORS`、标签默认色 `#2196F3`、渠道色 `#1677FF/#07C160/#E53935`。
4. **样式重复爆炸**：40+ 处 `StyleSheet.create`；`header` 样式在 ~15 个页面重复；8 个管理页（账户/分类/标签/预算/周期/规则/信用卡/备注模板）是同一"列表+FormModal"模式却各自实现。
5. **录入流程偏长**：方向 chip → 金额 → 账户 → 分类网格 → 折叠详情，不是金额优先；无 KeyboardAvoidingView；日期靠手输 `YYYY-MM-DD`。
6. **信息架构问题**：设置页 13 入口平铺；报表页周/月/年三套独立状态；年报内嵌月报与月 Tab 重复；AI/导出图标无文字标签。
7. **Header 策略不统一**：二级页手写返回栏，唯独 transaction/new 用原生 header。

## 2. 已确认的关键决策

| 决策点 | 结论 |
|---|---|
| 重设计深度 | **全面重做**（所有页面） |
| 视觉方向 | **明亮 Bento 现代风**：浅色为主 + 大圆角黑白对比，财务语义色点缀 |
| 暗色模式 | **完整保留**（OLED 纯黑，与浅色对等） |
| 记一笔交互 | **金额优先数字键盘面板**（NumpadSheet） |
| 底部导航 | **中央凸起 ＋**，4 个内容 Tab（首页/交易/报表/我的） |
| 实施策略 | **设计系统先行，逐页替换**（5 个阶段） |

## 3. 视觉语言（Design Tokens）

### 3.1 色板

**浅色（默认）**：

| Token | 值 | 用途 |
|---|---|---|
| bgPrimary | `#F6F7F9` | 页面背景 |
| bgSecondary | `#FFFFFF` | 卡片 |
| bgTertiary | `#EFF1F4` | 输入框/chip |
| fgPrimary | `#111318` | 主文字 |
| fgSecondary | `#6B7280` | 次要文字 |
| fgInverse | `#FFFFFF` | 反色文字 |
| accent | `#111318` | **近黑**，按钮/选中态 |
| accentLight / accentDark | 重定义为中性色阶：accentLight = accent 8% 透明度的底色（选中高亮），accentDark = accent 的按压加深态 | 高亮背景/按压态 |
| financial.income | `#10B981` | 收入 |
| financial.expense | `#EF4444` | 支出 |
| financial.transfer | `#3B82F6` | 转账 |

**暗色（OLED，完整对等）**：

| Token | 值 |
|---|---|
| bgPrimary | `#040508` |
| bgSecondary | `#101218` |
| bgTertiary | `#1A1D24` |
| fgPrimary / accent | `#F3F4F6`（accent 反转为白） |
| fgSecondary | `#9CA3AF` |
| financial.income | `#34D399`（提亮） |
| financial.expense | `#F87171`（提亮） |
| financial.transfer | `#60A5FA`（提亮） |

原则：**accent 从靛蓝改为近黑白单色**，品牌感靠排版与财务语义色表达；对比度 ≥ 4.5:1；暗色下用 1px 半透边框代替阴影。

### 3.2 字体 / 圆角 / 阴影 / 图标

- **移除 Caveat/Quicksand 自定义字体**，改系统字体（iOS SF / Android Roboto），消除字体加载失败风险；删除 `_layout.tsx` 字体加载代码。
- 金额数字统一 `fontVariant: ['tabular-nums']`。
- 字阶：display 34 / h1 28 / h2 22 / h3 17 / body 16 / bodySmall 14 / caption 12。
- 圆角：sm 8 / md 12 / lg 16 / **xl 24（卡片默认）** / full。
- 阴影减重：浅色 2–12px 弥散阴影；暗色以边框代替。
- **图标统一 Ionicons**；全部 emoji 图标替换为 `CategoryIcon`（Ionicon + 圆形彩色底）。
- 硬编码分类色收归 `theme.categoryPalette`（12 色循环）；渠道色、标签默认色等一并 token 化。
- `design-system/beancount-mobile/MASTER.md` 重写以匹配实现，结束"两份宪法"。

## 4. 核心交互：NumpadSheet 记一笔面板

### 4.1 结构（一屏完成 90% 记账）

自上而下：方向 chip（支出/收入/转账） → 大金额显示（等宽数字） → **账户 chip 行** → 分类快捷网格（4 列，常用分类 + "全部"） → 内嵌数字键盘（0-9、小数点、⌫、**＋/－ 连续计算**（如 20+15 直接出 35）、"今天"日期键、完成键）。下滑展开"更多"抽屉：备注、标签、日期、高级模式（PostingEditor）入口。原 SpeedDial 的 OCR/导入入口移入面板顶部工具行。

### 4.2 两个账户（复式记账的"两条腿"）

| 方向 | 腿 1 | 腿 2 |
|---|---|---|
| 支出 | 资金来源账户（Assets/Liabilities，账户 chip 行，"从"） | 分类账户（Expenses:*，分类网格） |
| 收入 | 分类账户（Income:*，分类网格） | 到账账户（Assets，账户 chip 行，"到"） |
| 转账 | 转出账户（chip 行） | 转入账户（第二 chip 行 + ⇅ 互换按钮），分类网格隐藏 |

配套规则：

- 账户 chip 行显示最常用的 3~4 个 Assets/Liabilities 账户（按使用频率排序），**默认选中上次使用的账户**（settingsStore 持久化），分类同理；"⋯"弹出全部账户树。
- 转账双方限定 Assets/Liabilities 账户（与 transferRecognizer 校验一致）；还信用卡 = 转账到 Liabilities 账户，天然支持。
- 落账走 `buildAndSaveTransaction()` → BillPipeline，与手动/自动渠道完全一致，不产生第二套写入逻辑。
- 无 Assets 账户时 chip 行显示"去创建账户"引导，不死锁。
- 完成键上方可选显示分录预览 `Assets:招行 → Expenses:餐饮 ¥35`（可在设置关闭）。
- 编辑模式按 posting 方向回填两条腿。
- P3 阶段先在设置加"新版录入"开关灰度，稳定后默认开启。

## 5. 导航

自定义 **AppTabBar**（替换 expo-router 默认 tabBar）：4 个内容 Tab（首页/交易/报表/我的）+ 中央凸起 ＋。＋ **不是路由**，在任何页面唤起全局 Modal（NumpadSheet），不丢失上下文。**SpeedDial 退役**。

## 6. 核心组件库（P2 交付物）

新增：

- **NumpadSheet** — 见第 4 节
- **AppTabBar** — 见第 5 节
- **ScreenHeader** — 统一二级页头（返回 + 标题 + 右操作位），替换十几份手写返回栏；transaction/new 的原生 header 一并撤掉
- **StatCard** — "标题 + 大数字 + caption"统计卡（首页/报表/年报共用）
- **ManagementScreen** — 管理页模板（ScreenHeader+＋ / 可选分组 Tab / FlatList / 删除确认 / FormModal），8 个管理页共用，各页只声明字段配置 + 数据读写 hooks
- **DatePickerField** — 日历选择器，终结手输 `YYYY-MM-DD`
- **FilterSheet** — 底部弹层高级筛选（账户/日期/金额区间）
- **CategoryIcon** — Ionicon + 彩色圆底，替换 emoji

改造/退役：Button/Card/Chip/SearchBar 按新 token 重刷；CategoryPicker 改底部弹层网格并 Ionicon 化；FormModal 的 "✕" 字符换 Ionicons；transaction/new 整页重写为 NumpadSheet 宿主（编辑模式复用同面板）。

## 7. 逐页重设计要点

### 7.1 首页：从"数据墙"到"今日视角"

- 顶部：日期 + 问候语（替代应用名标题）。
- 净资产卡：去 accent 底色改白卡 + tabular 大数字，下方一行小字：本月支出 / 收入 / 预算剩余。
- 新增**待办条**：周期记账到期、信用卡还款提醒、未确认自动账单——首页回答"今天我要做什么"。
- 最近 5 条交易 + "查看全部 →"。
- 月度趋势卡（TrendLine 重刷新色板）。
- 账户余额树下沉到「我的」页。

### 7.2 交易页：搜索优先 + 分组时间线

- 搜索框常驻；方向筛选 chip 保留；高级筛选收进 FilterSheet。
- 列表**按日期分组**（今天/昨天/具体日期），组头显示当日收支小计。
- TransactionCard 重刷：CategoryIcon 圆底图标 + 商户/备注 + 账户小字 + 右侧等宽金额（支出黑色、收入绿色带 + 号，降低色彩噪音）。
- 左滑卡片：快捷"再记一笔（复制）/ 删除"。
- 解析诊断从页面底部移入设置 → 数据组。

### 7.3 报表页：统一时间导航 + 去重

- 周/月/年 Tab 保留；三套独立状态（viewYear/viewMonth/viewWeekDate）合并为**单一 anchor 日期 + 周期类型**，左右箭头统一切换。
- 删除年报内嵌的 MonthlyReport（与月 Tab 重复）；年报只留：年度收支汇总、月度节奏迷你图、Top 分类。
- AI 总结/导出入口加文字标签，收进 "⋯" 菜单。
- CalendarView 保留在月 Tab，配色收归 token；热力图用 expense 色 5 级透明度。
- CategoryPie / StatCard / NetWorthChart 统一新 token。

### 7.4 设置 →「我的」：4 分组重构

- **账户与分类**：账户树（含余额，从首页移来）、分类、标签、信用卡、备注模板。
- **记账自动化**：规则、周期记账、自动记账通道（无障碍/通知/短信）、导入。
- **数据**：同步（WebDAV/Git/iCloud）、备份恢复、导出、解析诊断。
- **偏好**：主题、语言、应用锁、AI 设置、每日提醒、关于。
- 每组一张 Bento 卡，条目 = 图标 + 名称 + 右箭头；所有二级页用统一 ScreenHeader。

### 7.5 管理页模板化

账户/分类/标签/预算/周期/规则/信用卡/备注模板 8 页统一套 ManagementScreen，预计删除上千行重复代码。

## 8. 阶段计划

| 阶段 | 内容 | 验收 |
|---|---|---|
| P1 设计系统 | 新 tokens → 双主题 presets → 移除自定义字体 → categoryPalette → 重写 MASTER.md | typecheck 通过；token 名不变只改值，旧组件接口兼容 |
| P2 组件库 | ScreenHeader / StatCard / AppTabBar / CategoryIcon / DatePickerField / FilterSheet / ManagementScreen | 组件调试页可逐个查看；纯逻辑单测 |
| P3 录入闭环 | NumpadSheet + 双腿账户选择 + 全局＋ + transaction/new 重写 + SpeedDial 退役；"新版录入"开关灰度 | 手动记账/编辑/转账/还款全走面板；pipeline 集成测试不回归 |
| P4 四个 Tab | 首页（待办条）/ 交易（时间线+左滑）/ 报表（anchor 统一）/ 我的（4 分组） | 逐页替换，每页替换后全量测试 |
| P5 管理页+收尾 | 8 页套模板；图表重刷；emoji 清零；硬编码色清零（grep 审计）；无障碍标签补全 | `#[0-9A-Fa-f]{6}` 在 src/ 下只剩 presets.ts 与 categoryPalette |

## 9. 测试策略

- **不动 domain 层**：billPipeline/dedup/rules 等纯逻辑零改动，现有 30+ 单测是安全网，必须保持全绿。
- 新增纯逻辑单测：numpad 表达式求值（＋/－ 连续计算）、双腿账户解析（方向 → posting 映射）、anchor 日期导航（周/月/年加减）。
- 每阶段结束跑 `npm test` + `npm run typecheck`；UI 层靠深浅双主题手工走查清单。
- 硬编码色审计：grep 全量扫描。

## 10. 风险与 YAGNI

风险对策：

- 主题切换过渡期"半新半旧" → P1 保持 token 名不变只改值，组件接口向后兼容。
- NumpadSheet 全新交互 → 设置开关灰度后再默认开启。
- 移除字体无数据迁移，删加载代码即可。

明确不做：自定义主题编辑器（保留 light/dark/system 三档）；迁移图标库到 Lucide；改 domain/存储/同步层；平板/桌面布局适配。
