gwy-exam/docs/checks/task-08.md
2026-09-01 16:47:25 +08:00

9.5 KiB
Raw Permalink Blame History

任务 08 检查记录:刷题与结果闭环

日期2026-09-01

交付内容

后端Handler + Schema + Routes

  • server/src/handlers/practice.ts(重写核心闭环)
    • modules:返回五大模块与题量(保留)。
    • start:支持两种组卷——
      • 普通组卷:按模块 + duration5/10/15 分钟)经 DURATION_TO_COUNT 换算题量随机抽取;题库不足时返回全部并打乱(实测数量关系仅题 4total=4 而非 5
      • 自定义组卷body.custom 指定题目 ID 列表(去重、校验存在、上限 20 题、返回首题模块),mode='custom'
    • currentQuestion:按 session.recordIndex + 1 推进取当前题;已答完返回 { question: null }不返回答案与解析;新增返回 answered / durationMinutes
    • answer:写入作答记录 + 递增 recordIndex幂等防重复(同 sessionId+questionId 已存在返回 accepted:false, duplicate:true,不重复计入);防乱序(非当前题返回 409「题目与会话作答顺序不符」返回 correct / correctAnswer / analysis 供单题即时反馈。
    • finish:按已作答题计分(未作答不计入正确率),返回 total/answered/correctCount/accuracy/durationSeconds/wrongQuestionIds/questions[];标记会话 finished 并写 endedAt
    • wrongReasons(新增):最近 30 天错因聚合计数 + 占比,供刷题中心「错因分布」卡片。
  • server/src/schemas/entities.tsPracticeSessionSchema 新增 recordIndex(默认 -1
  • server/src/schemas/api.tsPracticeStartBodySchema 新增可选 customPracticeSessionViewSchema 新增 totalPracticeQuestionResponseSchemaquestion 改为 .nullable() 并新增 answered/durationMinutesPracticeAnswerResponseSchema 新增 correct/correctAnswer/analysisPracticeFinishResponseSchema 新增 answered;新增 PracticeWrongReasonsResponseSchema
  • server/src/routes.ts:新增 GET /api/practice/wrong-reasons(刷题 tag路由数 35→36。

前端View + API

  • client/src/api/index.ts:新增类型 PracticeSessionStart/PracticeQuestion/PracticeAnswer/PracticeFinish/PracticeWrongReasonspracticeApi 新增 wrongReasons()
  • client/src/views/practice/PracticeView.vue(重写,原为 ComingSoon刷题中心含「刷题 / 错题本 / 申论」三 tab按路由高亮
    • 刷题 tab对照原型选择模块5 卡 + 掌握度 + 选中勾、碎片组卷时长5/10/15、开始刷题大按钮含模块+时长文案)、错因分布(最近 30 天横向条)、待复习错题、推荐动作。
    • 错题本 tab:对接 reviewApi.list({status:'pending'}),无数据空态;完整间隔复习属任务 09。
    • 申论 tabComingSoon 占位。
  • client/src/views/practice/AnswerView.vue(新增):作答 + 单题反馈 + 整卷结果。
    • 作答态:顶部返回 + 第X题/共Y题 进度条 + 计时 + 关闭;模块/子模块/难度标签题干A-D 选项;提交答案。
    • 单题结果态:答对/答错横幅(含正确答案 + 「已自动收录到错题本」、解析卡、AI 讲解按钮、标记错因(可多选,本地选择)、下一题 / 查看本卷结果。
    • 整卷结果态:答对题数、正确率、用时、错题回顾(你的答案 → 正确答案 + 解析)、返回刷题中心。
    • secondsUsed 按单题计时(elapsed - questionStartElapsed)而非会话累计。
  • client/src/views/practice/CustomView.vue(新增):自定义组卷——从题库勾选题目(上限 20、已选计数、全选底部开始练习。
  • client/src/components/base/icons.ts:新增 plus/sparkles/refresh/book-open 图标。
  • client/src/components/base/AppButton.vue:新增 loading propspinner
  • client/src/layouts/MobileLayout.vue/practice 相关路径隐藏顶栏标题(页面自带 AppPageHeader避免标题重复
  • client/src/router/index.ts:新增 /practice/session/:id(作答)、/practice/custom(自定义组卷)。

与原型图对照

  • 「桌面-刷题中心-刷题态.png」选择模块、碎片组卷时长、开始刷题大按钮、错因分布最近30天、待复习错题、推荐动作 —— 结构一致。
  • 「移动-刷题-行测Tab.png」模块卡 + 时长 + 开始刷题按钮 + 底部 TabBar —— 一致(含选中勾选态)。
  • 「移动-刷题-作答页.png」进度条 + 计时 + 模块标签 + 题干 + 选项 + 提交答案 —— 一致。
  • 「移动-刷题-结果页.png」回答错误横幅正确答案 + 已收录错题本、解析、AI 讲一讲、标记错因(可多选)、下一题 —— 一致。

接口实测curl演示数据

接口 结果
GET /api/practice/modules 5 模块题量 {言语理解4, 数量关系4, 判断推理4, 资料分析4, 常识判断2}
POST /api/practice/start(数量关系 5 分钟) 返回 sessionId / questionIds / total=4题库不足 5 取全部)/ startedAt / status
POST /api/practice/startcustom 3 题) 「语用理解 demo-q-001/002/003」total=3mode=custom
POST /api/practice/startcustom 含不存在题) 409 CONFLICT「存在不存在的题目nope-1」
GET /api/practice/:id/question 返回当前题(无答案/解析)+ index/total/answered/durationMinutes
POST /api/practice/:id/answer(正确) {accepted:true, answeredCount:1, correct:true, correctAnswer, analysis}
POST /api/practice/:id/answer(重复提交同题) {accepted:false, duplicate:true},不重复计入
POST /api/practice/:id/answer(乱序提交非当前题) 409 CONFLICT:「题目与会话作答顺序不符」
GET /api/practice/:id/question(答完全部) {question:null, index, total, answered}
POST /api/practice/:id/finish {total, answered, correctCount, accuracy, durationSeconds, wrongQuestionIds, questions[]}(部分答错正确率 25%,错题列表正确)
GET /api/practice/wrong-reasons {reasons:[{reason,count,percent}]} 按错因聚合(演示数据各错因 1 条 14%
GET /api/practice/wrong-reasons(无数据) {reasons:[]}

浏览器检查agent-browser

场景 结果
桌面 1440 刷题中心 页头按钮 + 3 tab + 选择模块 + 时长 + 开始大按钮 + 错因分布 + 待复习 + 推荐动作,与原型结构对齐
桌面 1440 作答页 进度条 + 计时 + 模块/子模块/难度标签 + 题干 + 选项 + 提交答案,渲染正常
桌面 1440 单题结果态(答错) 正确答案绿勾 / 错误答案红显 / 红色「回答错误」横幅(正确答案 + 已收录错题本) / 解析 / AI 讲一讲 / 标记错因(可多选) / 下一题 —— 对齐原型结果页
桌面 1440 整卷结果页 答对 1/4、正确率 25%、用时、错题回顾(答案对比 + 解析)、返回刷题中心
桌面 1440 自定义组卷 已选计数 / 全选 / 题目列表(标签 + 题干)/ 开始练习,勾选交互正常
移动 390 刷题中心 标题单次显示(修 topbar 重复)、模块 2 列卡片、时长、开始大按钮、底部 TabBar无横向溢出
移动 390 作答页 顶部进度 + 计时、题干、选项、提交答案、底部 TabBar无遮挡对齐原型
计时修正 secondsUsed 改为单题耗时(修正前误用会话累计时间导致结果页「用时 7 分 24 秒」不合理)

截图:deliverables/checks/task-08-practice-desktop.pngtask-08-practice-desktop-bottom.pngtask-08-answer-desktop.pngtask-08-answer-result-desktop.pngtask-08-result-desktop.pngtask-08-custom-desktop.pngtask-08-practice-mobile.pngtask-08-answer-mobile.png

完成标准核对开发计划任务08

  • 模块选题5 模块卡片全选)。
  • 5/10/15 分钟组卷(时长→题量)。
  • 自定义组卷。
  • 会话 + 计时(作答页计时,secondsUsed 单题计)。
  • 作答 + 提交(单选、校验当前题)。
  • 结果 + 标准解析。
  • 可从刷题中心或首页开始一套题并完成提交;记录写入 JSONpractice-sessions / practice-records
  • 中途刷新恢复(recordIndex 进度推进,currentQuestion 按索引取题,刷新后 question:null 走 finish
  • 提交后不能重复计入同一题(duplicate:true 幂等)。
  • 答案、正确率、耗时、完成状态准确。

边界说明

  • 「答错自动沉淀错题(写 wrong-questions.json」属于任务 09。任务 08 的 answer 不写错题库,整卷结果与单题结果中的「已自动收录到错题本」为提示文案;错题本 tab 当前仅对接 reviewApi.list 展示既有错题,完整间隔复习闭环在任务 09 完成。
  • 「标记错因(可多选)」当前为前端本地交互,落库归属任务 09 的错题逻辑。

当前结论

任务 08 完成:刷题与结果闭环在前后端打通。普通组卷 + 自定义组卷、会话持久化(recordIndex 进度防重复/防乱序)、单题即时反馈(对错/正确答案/解析/AI 入口/标记错因)、整卷结果(正确率/用时/错题回顾全部实测通过新增「错因分布」接口供刷题中心展示修复移动端标题重复与单题耗时统计。类型检查vue-tsc / tsc与生产构建128 模块)全部通过。测试数据已清理,题库/会话/记录恢复演示基线。