💬 首页(HomePage)
用户登录后看到的首页,通过 DataContext 和 AuthContext 消费数据。账单切换、预算预警、流水日历、趋势图都集中在此页面。
页面结构
- 侧边栏:Logo / 账单切换下拉 / 导航菜单 / 用户信息
- 账单切换:下拉选择当前账单(触发 GET /api/bills + GET /api/bills/:id)
- 统计概览:今日收支 / 本月收支 / 预算剩余(来自 DataContext)
- 趋势图:收支趋势折线图(ECharts)
- 日历热力图:每日交易量热力图(来自 DataContext)
- 最近交易:最近5条交易列表
- 预算预警:超预算分类红色高亮
数据流(Context 架构)
DataContext:bills, transactions, categories, budgets, selectedBillId, selectedBill
AuthContext:currentUser(来自 GET /api/auth/me)
路由:首次加载 redirect to="/login",已登录则 redirect to="/home"
AuthContext:currentUser(来自 GET /api/auth/me)
路由:首次加载 redirect to="/login",已登录则 redirect to="/home"
触发时机详解
1. App 初始化 → 重定向判断
触发条件:App 首次加载 → 检查 localStorage 中的 token → 有 token → redirect to="/home",无 token → redirect to="/login"
2. 首页加载 → AuthContext + DataContext 并发初始化
触发条件:路由匹配到 /home 时,AuthContext 和 DataContext 同时初始化,并发请求:
GET
/api/auth/me
✅ AuthContext 初始化时触发,获取当前用户信息(无需手动传 token)
响应: {"id": "string", "phone": "string", "nickname": "string", "email": "string", "avatar_url": "string|null", ...}
GET
/api/bills
✅ DataContext 初始化时触发,获取用户所有账单列表
响应: [{"id": "string", "name": "string", "created_at": "ISO8601", ...}]
3. 账单下拉切换 → GET /api/bills/:id + GET /api/transactions/:billId
触发条件:用户从侧边栏下拉选择不同账单 → setSelectedBillId(bill.id) → DataContext 重新请求
GET
/api/bills/:id
✅ 切换账单时触发,获取新账单的详细信息
响应: {"id": "string", "name": "string", "members": [...], ...}
GET
/api/transactions/:billId
✅ 切换账单时触发,获取该账单所有交易流水
响应: [{"id": "string", "amount": 100, "type": "income|expense", ...}]
4. DataContext 自动刷新规则
触发条件:当 bills / transactions / categories / budgets 中任意一个被 mutate 变更后 → DataContext 自动重新获取该资源数据
// 例:当 BillPage 新增交易 → transactions 被 mutate → DataContext 重新 GET /api/transactions/:billId
// 例:当 BillPage 新增分类 → categories 被 mutate → DataContext 重新 GET /api/categories/:billId
5. 页面卸载时
触发条件:路由离开 /home → 页面组件卸载,但 DataContext 和 AuthContext 保持挂载(因为在 App 层级)
6. 点击「添加账单」→ Modal → POST /api/bills
触发条件:点击侧边栏"添加账单"按钮 → 弹出创建账单 Modal → 填写名称 → 点击确认
POST
/api/bills
✅ 点击确认创建按钮触发
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 必填 | 账单名称 |
响应: {"id": "string", "name": "...", ...}
副作用:新增后 mutate("bills") → DataContext 重新 GET /api/bills
7. 点击「设置」菜单 → 路由跳转 /settings
触发条件:点击侧边栏"设置"菜单项 → Navigate to /settings
8. 点击「开发者」菜单 → 路由跳转 /developer
触发条件:点击侧边栏"开发者"菜单项 → Navigate to /developer
9. 点击「登出」→ 清除 token → 重定向 /login
触发条件:点击用户信息区的"登出"按钮 → localStorage.removeItem("token") → Navigate to /login → AuthContext 重置