Files
xiaocai/docs/prd-alignment.md
wangxiaogang 31f6487d61 feat: 前后端功能对齐 - 实现8个对齐差距
P0-1: 分类拖拽排序 - category-manage 添加拖拽 UI
P1-1: 反馈回复展示 - 新增 GET /feedback/mine + 前端我的反馈Tab
P1-2: 备份管理页面 - 新增下载端点 + backup-manage 页面
P2-1: 统计年度/周视图 - stats 支持 period 参数 + 前端维度切换器
P2-2: 数据导入 - 新增 POST /import 端点 + data-import 页面
P2-3: 数据导出服务端化 - 新增 GET /export 流式端点
P3-1: 健康检查展示 - health 移到 auth 前 + admin 状态卡片
P3-2~4: 交易标签系统 - tags CRUD + 交易关联 + 按标签筛选统计

后端: 新增 tag.ts/export.ts 路由, 改造 feedback/backup/transaction/stats
前端: 新增 DragSortList 组件, 3个新页面, 改造 7 个现有页面
QA 修复: 5个严重Bug + 4个潜在问题
2026-06-10 17:30:36 +08:00

255 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 小菜记账 — 前后端对齐增量 PRD
> 版本: v1.0 | 日期: 2026-07-11
> 类型: 增量 PRD仅包含变更部分
> 基线: 前后端对齐分析发现的 8 项差距
---
## 一、产品目标
| # | 目标 | 说明 |
|---|------|------|
| G1 | 消灭前后端差距,实现已开发后端能力的前端落地 | 后端已有排序、备份、健康检查等端点,但前端缺失对应 UI |
| G2 | 补齐用户反馈闭环,提升产品可信度 | 用户提交反馈后无法查看回复,体验断裂 |
| G3 | 扩展数据维度与吞吐能力 | 支持年度/周度统计、服务端导出、数据导入,为数据量增长做准备 |
---
## 二、用户故事
### P0 — 分类拖拽排序
> As a 用户, I want 在分类管理页面拖拽调整分类顺序, so that 常用分类排在前面,记账时选得更快。
### P1 — 反馈回复展示
> As a 用户, I want 查看自己提交的反馈列表及管理员回复, so that 我知道反馈是否被处理以及处理结果。
### P1 — 备份管理页面
> As a 管理员, I want 在前端触发备份、查看备份列表并下载备份文件, so that 我可以在出现问题时快速恢复数据。
### P2 — 统计年度/周视图
> As a 用户, I want 在统计页面切换年/周/月维度, so that 我可以从不同时间粒度分析收支趋势。
### P2 — 数据导入与服务端导出
> As a 用户, I want 导入 JSON 格式的交易数据, so that 我可以从其他记账工具迁移历史数据。
>
> As a 用户, I want 大数据量导出走服务端生成, so that 导出速度快、不卡顿。
### P3 — 健康检查
> As a 管理员, I want 在管理页面看到后端服务运行状态, so that 我能第一时间发现服务异常。
### P3 — 交易标签系统
> As a 用户, I want 给交易添加标签(如"出差""聚餐", so that 我可以按标签筛选和统计关联交易。
>
> As a 用户, I want 按标签筛选交易列表和查看标签维度的统计, so that 我可以追踪特定场景的收支。
---
## 三、需求池
### P0 — Must Have
| ID | 需求 | 前端 | 后端 | 验收标准 |
|----|------|------|------|----------|
| P0-1 | 分类拖拽排序 | 分类管理页面添加拖拽排序 UI拖拽结束后调用 `sortCategories(ids)` | 无新增(`PUT /categories/sort` 已实现) | 拖拽后顺序持久化;刷新页面顺序保持;支出/收入分类各自排序 |
### P1 — Should Have
| ID | 需求 | 前端 | 后端 | 验收标准 |
|----|------|------|------|----------|
| P1-1 | 用户反馈列表 | 反馈页面新增"我的反馈"Tab展示反馈列表及管理员回复 | 新增 `GET /feedback/mine` 端点(用户维度,返回当前用户的反馈+`admin_reply` | 用户只能看自己的反馈;未回复显示"待处理"状态;已回复显示回复内容和时间 |
| P1-2 | 备份管理页面 | 新增备份管理页面:触发备份按钮、备份列表、下载按钮 | 新增 `GET /backup/:id/download` 端点 | 管理员可触发备份并看到进度;列表显示备份时间和大小;点击下载获取备份文件 |
### P2 — Nice to Have
| ID | 需求 | 前端 | 后端 | 验收标准 |
|----|------|------|------|----------|
| P2-1 | 统计年度/周视图 | 统计页面添加维度切换器(周/月/年),切换后图表和排行联动更新 | `GET /stats/category``GET /stats/trend` 支持 `period=week|month|year` 参数,按对应维度聚合数据 | 周视图显示本周每日数据;年视图显示每月汇总;切换时图表平滑过渡 |
| P2-2 | 数据导入 | 我的页面新增"数据导入"入口;支持 JSON 文件上传;导入前预览数据条数,确认后提交 | 新增 `POST /api/transactions/import` 端点,接收 JSON 文件,校验格式,批量写入 | 支持 JSON 格式;导入前展示条数预览;重复数据(同日期/金额/分类)跳过并提示;导入完成显示成功/跳过计数 |
| P2-3 | 数据导出服务端化 | 数据导出页面新增"服务端导出"选项;大数据量(>1000条自动走服务端 | 新增 `GET /api/export` 端点,支持 CSV/JSON 格式,流式响应 | 客户端导出保留作为轻量选项;服务端导出无条数限制;下载进度可感知 |
### P3 — Nice to Have远期
| ID | 需求 | 前端 | 后端 | 验收标准 |
|----|------|------|------|----------|
| P3-1 | 健康检查展示 | 管理页面新增服务状态卡片,显示后端健康信息 | 将 `/api/health` 端点移到 authMiddleware 之前 | 管理页面实时显示服务状态(正常/异常);无需登录即可调用健康检查 |
| P3-2 | 交易标签 — 标签管理 | 新增标签管理页面:创建/编辑/删除标签(名称+颜色) | 新增 `tags` 表及 CRUD 端点(`GET/POST/PUT/DELETE /api/tags` | 每个用户独立标签;标签不可重名;删除标签时解绑关联交易 |
| P3-3 | 交易标签 — 交易关联 | 记账页面新增"添加标签"入口;交易详情/编辑页可修改标签 | `transactions` 表新增关联;`POST/PUT /transactions` 支持 `tagIds` 字段 | 一笔交易可关联多个标签;标签选择器展示用户已有标签 |
| P3-4 | 交易标签 — 标签筛选统计 | 账单页支持按标签筛选;统计页新增标签维度视图 | `GET /transactions` 支持 `tagId` 筛选参数;`GET /stats/by-tag` 新端点 | 筛选结果仅显示含指定标签的交易;标签统计展示各标签下收支总额 |
---
## 四、UI 交互说明
### P0-1 分类拖拽排序
```
分类管理页面category-manage/index.vue变更
1. 页面顶部新增提示栏:"长按拖拽可调整分类顺序"
2. 每个分类项左侧显示拖拽手柄图标Lucide GripVertical, #BFB3B3
3. 长按分类项300ms进入拖拽模式
- 被拖拽项 elevation 提升shadow-clay-float
- 背景色变为 #FFF0E6
- 其余项轻微缩进让出空间
4. 拖拽过程中实时交换位置(带 150ms 过渡动画)
5. 松手后:
- 调用 sortCategories(ids) 提交新顺序
- 成功:轻量 toast "排序已保存"
- 失败:回滚到原位置 + 错误提示
6. 支出/收入 Tab 各自独立排序,互不影响
```
### P1-1 用户反馈列表
```
反馈页面feedback/index.vue变更
1. 页面顶部新增 Tab 切换:"提交反馈" | "我的反馈"
2. "我的反馈" Tab 内容:
├── 列表按提交时间倒序排列
├── 每项显示:
│ ├── 反馈内容截断2行点击展开
│ ├── 提交时间(相对时间:"3天前"
│ ├── 状态标签:
│ │ ├── 待处理 → 灰色 #BFB3B3
│ │ ├── 已回复 → 绿色 #7BC67E
│ │ └── 已关闭 → 橙色 #FF8C69
│ └── 管理员回复区域(仅已回复时显示):
│ ├── 分割线 + "管理员回复" 标签
│ ├── 回复内容
│ └── 回复时间
└── 空状态:插画 + "还没有提交过反馈"
3. 下拉刷新更新列表
4. 上拉加载更多(分页)
```
### P1-2 备份管理页面
```
新增页面backup-manage/index.vue
1. 顶部操作区:
├── [立即备份] 主按钮Clay 风格)
├── 点击后按钮变为 loading 态
└── 成功后列表顶部新增一条记录 + toast "备份成功"
2. 备份列表:
├── 按时间倒序
├── 每项显示:
│ ├── 备份时间2026-07-11 14:30
│ ├── 文件大小12.3 MB
│ └── [下载] 按钮Lucide Download 图标)
├── 点击下载:
│ ├── 按钮变为进度条
│ └── 完成后 toast "下载完成"
└── 空状态:"暂无备份记录"
3. 仅管理员角色可见此页面入口
```
### P2-1 统计年度/周视图
```
统计页面stats/index.vue变更
1. 月份选择器升级为维度切换器:
├── 新增三个 Tab周 | 月 | 年
├── 样式同现有支出/收入切换器
└── 切换后日期选择器联动:
├── 周:显示 "2026年7月 第2周",左右切换周
├── 月:保持现有行为
└── 年:显示 "2026年",左右切换年
2. 图表联动更新:
├── 周维度:趋势图 X 轴为周一~周日
├── 年维度:趋势图 X 轴为1月~12月
└── 环形图和排行同步更新为对应维度数据
3. 概览卡片数值联动
```
### P2-2 & P2-3 数据导入与导出
```
我的页面变更 + 新增页面:
1. "数据导出"入口变更:
├── 点击后进入导出页面
├── 导出方式选择:
│ ├── 客户端导出(< 1000 条推荐)— 现有逻辑
│ └── 服务端导出(≥ 1000 条推荐)— 新增
├── 格式选择CSV | JSON
├── 日期范围选择器
└── [开始导出] 按钮
2. 新增"数据导入"入口(我的页面功能列表):
├── 点击后进入导入页面
├── 步骤流程:
│ ├── Step 1选择文件仅 .json
│ ├── Step 2预览 — 显示识别条数、日期范围、分类映射
│ ├── Step 3确认导入
│ └── 结果:成功 N 条 / 跳过 M 条
└── 导入模板下载链接
```
### P3-1 健康检查展示
```
管理页面变更:
1. 页面顶部新增服务状态卡片:
├── 正常:绿色圆点 + "服务运行正常" + 响应时间 "23ms"
├── 异常:红色圆点 + "服务异常" + 错误信息
└── 检测中:灰色圆点 + 旋转图标
2. 每 30 秒自动刷新一次
3. 点击卡片可手动刷新
```
### P3-2~4 交易标签系统
```
全局变更:
1. 记账页面add/index.vue
├── 附加信息区新增"添加标签"行
├── 点击弹出标签选择器(底部弹窗):
│ ├── 已有标签列表(可多选)
│ ├── 搜索框
│ └── [新建标签] 快捷入口
└── 已选标签以药丸标签形式展示在输入区
2. 账单页面bills/index.vue
├── 筛选栏新增标签筛选
└── 筛选弹窗中增加标签选择
3. 统计页面stats/index.vue
└── 新增"标签统计"卡片(环形图 + 排行)
4. 我的页面:
└── 功能列表新增"标签管理"入口
5. 标签管理页面tag-manage/index.vue— 新增:
├── 标签列表(名称 + 颜色色块 + 关联交易数)
├── [新建标签] 按钮
├── 编辑弹窗:名称输入 + 颜色选择器8色预设
└── 删除确认:关联 N 笔交易时提示"将解除关联"
```
---
## 五、待确认问题
| # | 问题 | 影响范围 | 建议 |
|---|------|----------|------|
| Q1 | 分类拖拽排序是否需要动画反馈?拖拽手柄位置(左侧还是右侧)? | P0-1 | 建议左侧手柄 + 长按触发,符合主流交互习惯 |
| Q2 | 用户反馈列表是否需要通知推送?当管理员回复后用户是否收到微信服务通知? | P1-1 | 后端已有通知逻辑,但微信订阅消息需用户主动订阅,建议先做页面内展示,通知作为后续增强 |
| Q3 | 备份文件的下载鉴权方式URL 是否需要时效性签名? | P1-2 | 建议使用临时签名 URL有效期 1 小时),避免备份文件被猜测 URL 直接访问 |
| Q4 | 统计年度视图的趋势图粒度:按月汇总还是按季汇总? | P2-1 | 建议按月汇总12 个点),季度可通过后续分组实现 |
| Q5 | 数据导入的 JSON 格式规范?是否需要支持其他记账 App 的导出格式? | P2-2 | 建议先定义小菜记账自有 JSON 格式,提供模板下载;其他 App 格式兼容作为远期需求 |
| Q6 | 服务端导出的文件存储方式:内存生成直接流式返回 vs 先写文件再下载? | P2-3 | 建议 < 1 万条内存流式返回,≥ 1 万条先写临时文件再下载,避免内存溢出 |
| Q7 | 交易标签上限:每笔交易最多关联几个标签?每个用户最多创建多少个标签? | P3-2~4 | 建议每笔交易最多 5 个标签,每用户最多 20 个标签,后续可调整 |
| Q8 | 标签与分类的关系:标签是否可以跨分类?同一标签能否同时用于支出和收入? | P3-2~4 | 建议标签不区分收支类型,跨分类使用,这是标签区别于分类的核心价值 |
---
*文档版本: v1.0 | 最后更新: 2026-07-11*