5.9 KiB
5.9 KiB
任务 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(新增):成绩录入/修改共用表单。- 字段:模考名称、日期、五个模块分数(0–100)、备注;总分由五模块自动汇总展示。
- 校验:名称必填、日期必填、模块合计 ≤ 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=67;targetGap=5(目标 72);changeVsPrevious=+3;trend 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 = 模块和,保持一致);后端仅做 0–100 范围校验,不强制模块和等于 total。
- CORS 方法白名单修复属于本任务联调发现的前置缺陷(浏览器端 DELETE/PATCH 预检被拒),一并修复并回归题库删除、计划切换。
当前结论
任务 10 完成:行测模考录入、列表、趋势、模块分数、目标分差、较上次变化、空状态与删除/修改联动全部实测通过;桌面与移动双端可操作;测试数据已恢复演示基线。