gwy-exam/docs/checks/task-10.md

81 lines
5.9 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.

# 任务 10 检查记录:模考分析
日期2026-09-01
## 交付内容
### 后端Handler + Schema + Routes
- `server/src/handlers/mock.ts`(重写):
- `analysis`:返回记录列表(新→旧)、目标分、最近成绩 `latest`、目标分差 `targetGap`(目标分 最近成绩)、较上次变化 `changeVsPrevious`(最近 上一场)、总分趋势 `trend` 与五个行测模块均分 `moduleAverages`
- `record`:录入持久化到 `mock-exams.json``updateData` 原子写,生成 UUID + createdAt不再返回未落库的临时对象。
- `update`(新增):按 id 修改记录,保留 id/createdAt其余字段覆盖。
- `remove`(新增):按 id 删除记录,分析随数据文件同步更新。
- `server/src/schemas/api.ts`:新增 `MockExamIdParamsSchema``MockExamUpdateBodySchema``MockExamRecordResponseSchema``MockExamDeleteResponseSchema``MockExamAnalysisResponseSchema` 增加 `latest` / `targetGap` / `changeVsPrevious`
- `server/src/routes.ts`:新增 `POST /api/mock-exams/:id/update``DELETE /api/mock-exams/:id`(模考分析 tag
- `server/src/server.ts`:修复 CORS 预检方法白名单(原默认仅 GET/HEAD/POST导致浏览器端 DELETE/PATCH 被拦;现显式允许 GET/HEAD/POST/PATCH/DELETE同时修复题库删除与计划切换的浏览器调用
### 前端View + API
- `client/src/views/mock/MockView.vue`(替换 ComingSoon 占位):
- 顶部「录入成绩」入口;加载/错误/空数据三态。
- 空态:标题「还没有模考成绩」+ 描述 + 「录入第一场模考」CTA。
- 统计卡:最近成绩(名称 + 日期)、目标分差(达标显示「已达目标」)、较上次变化(±分)。
- 行测成绩趋势(`AppLineChart`,虚线为目标分)。
- 模块均分对比(五模块横向进度条)。
- 模考记录列表(名称、日期、总分徽章、五模块小分、备注)+ 编辑 / 删除(删除弹确认框,二次确认)。
- `client/src/views/mock/MockFormView.vue`(新增):成绩录入/修改共用表单。
- 字段模考名称、日期、五个模块分数0100、备注总分由五模块自动汇总展示。
- 校验:名称必填、日期必填、模块合计 ≤ 100超限给出中文提示
- 创建走 `POST /api/mock-exams/record`,编辑走 `POST /api/mock-exams/:id/update`,保存成功 toast 后返回分析页。
- `client/src/api/index.ts``mockApi.update` / `mockApi.remove`;导出 `MockExamRecord` / `MockExamAnalysis` / `MockExamListItem` 类型。
- `client/src/router/index.ts`:新增 `/mock/new`(录入)、`/mock/:id/edit`(修改)。
- `client/src/components/base/icons.ts`:新增 `line`(趋势线)图标。
## 接口实测curl演示数据
| 接口 | 结果 |
|---|---|
| `GET /api/mock-exams/analysis` | 5 条记录latest=67targetGap=5目标 72changeVsPrevious=+3trend 5 点;五模块均分正确 |
| `POST /api/mock-exams/record` | 新增记录持久化analysis 变为 6 条、latest=70、gap=2 |
| `POST /api/mock-exams/:id/update` | 名称/分数/备注覆盖,保留 id/createdAt |
| `DELETE /api/mock-exams/:id` | 删除后 analysis 回到 5 条、latest 回 67 |
| 空数据 analysis | `records:[]`、latest/targetGap/changeVsPrevious 为 null、trend 空 |
| 非法输入 | 缺 name / 分数 120 → 统一 `VALIDATION_ERROR`;不存在记录 update/delete → `NOT_FOUND` |
| 重启持久化 | 新增记录重启后仍存在分析正确6 条 / latest=69 / gap=3 / +2 |
## 浏览器检查Chrome headless + CDP
| 场景 | 结果 |
|---|---|
| 桌面 1440 模考分析 | 统计卡(最近 67 / 还差 5 分 / +3 分、趋势图、模块对比、5 条记录、录入成绩按钮 |
| 录入流程 | 填名称/日期/五模块 → 总分自动汇总 70 → 保存 → 回分析页显示 6 条、最近 70 分 |
| 编辑流程 | 点击「编辑」→ 表单回填 → 改名称/分数 → 保存 → 列表同步更新 |
| 删除流程 | 点击「删除」→ 确认弹窗 → 「确认删除」→ 列表回 5 条、最近成绩回 67 |
| 空态 | 「还没有模考成绩」+「录入第一场模考」CTA 正常展示与跳转 |
| 表单校验 | 空名称提示「请填写模考名称」;五模块合计超 100 提示不能超过 100 分 |
| 移动 390 | 模考分析页与录入页均无横向溢出390/390 |
| 首页回归 | 数据中枢「最近模考」卡与趋势联动正常67 分 / +3 / 还差 5 分) |
截图:`deliverables/checks/task10-mock-desktop.png``task10-entry-desktop.png``task10-mock-mobile.png``task10-entry-mobile.png``task10-mock-empty-mobile.png`
## 完成标准核对开发计划任务10
- ✅ 行测模考录入record 持久化 + 录入页)。
- ✅ 列表(模考记录,含编辑/删除)。
- ✅ 趋势≥2 条记录生成折线趋势,含目标参考线)。
- ✅ 模块分数(五模块录入与均分对比,仅行测字段)。
- ✅ 目标分差targetGap与较上次变化changeVsPrevious
- ✅ 无数据空状态(后端 null 字段 + 前端空态 CTA
- ✅ 删除或修改记录后分析同步更新实测录入→6 条、删除→5 条、编辑同步)。
- ✅ 类型检查vue-tsc / tsc与生产构建135 模块)通过;`api:generate` 与 OpenAPI 一致。
## 边界说明
- 总分由前端按五模块自动汇总(演示数据 total = 模块和,保持一致);后端仅做 0100 范围校验,不强制模块和等于 total。
- CORS 方法白名单修复属于本任务联调发现的前置缺陷(浏览器端 DELETE/PATCH 预检被拒),一并修复并回归题库删除、计划切换。
## 当前结论
任务 10 完成:行测模考录入、列表、趋势、模块分数、目标分差、较上次变化、空状态与删除/修改联动全部实测通过;桌面与移动双端可操作;测试数据已恢复演示基线。