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

5.9 KiB
Raw Blame History

任务 11 检查记录AI 讲解与申论占位

日期2026-09-01

交付内容

后端

  • server/src/ai.ts(新增):
    • readAiConfig():从环境变量读取 AI_BASE_URL / AI_API_KEY / AI_MODEL(默认 gpt-4o-mini/ AI_TIMEOUT_MS(默认 20000未配置返回 null。
    • buildMessages():组装模块/题干/选项/标准答案/题库解析/标签/用户作答,要求模型输出严格 JSONsummary / steps / knowledgePoints / commonMistakes / answer
    • parseExplainJson():兼容 markdown 代码块等杂文的稳健 JSON 提取与字段校验。
    • explainWithAi()OpenAI 兼容 Chat Completions 调用(${baseUrl}/chat/completions + BearerAbortController 超时;未配置/超时/网络/HTTP/解析失败分别抛可识别错误;任何错误信息不含 API Key。
  • server/src/handlers/ai.ts(重写):配置有效 → 调用 AI 并返回 source:'ai';未配置 → source:'fallback'「AI 尚未配置」);超时 → source:'fallback'「AI 请求超时」);其余失败 → source:'fallback'「AI 讲解暂时不可用」)。回退内容为题库解析 + 标签 + 答案,前端可识别。
  • server/src/schemas/api.tsAiExplainBodySchema.userAnswer 改为可选(从错题详情进入且无作答历史时省略)。
  • server/.env.example(新增):记录 PORT / DATA_DIR / AI 配置项说明。

前端

  • client/src/views/practice/AiExplainView.vue(新增):
    • 路由 /practice/explain?questionId=&userAnswer=&requestType=,加载/错误/重试三态,缺少题目参数给出明确提示。
    • 展示来源徽章AI 生成 / 题库解析回退、讲解结论、分步解析编号步骤、考点chip、常见错误、正确答案绿色高亮回退时显示说明提示条。
    • requestType=deep 时标题为「AI 深度讲解」。
  • client/src/views/practice/AnswerView.vue
    • 单题结果「没看懂?让 AI 讲一讲」接入跳转(携带题目 ID + 用户答案)。
    • 整卷结果页错题回顾每项新增「AI 讲解」入口。
  • client/src/views/practice/WrongDetailView.vueAI 讲解按钮由占位禁用改为可用,携带题目 ID 与最近一次作答(无历史则省略)。
  • client/src/views/practice/EssayView.vue(新增):申论占位页——功能说明(五大题型)、后续能力(在线写作/AI 批改/范文库)、不保存写作内容的提示。
  • client/src/views/practice/PracticeView.vue:申论 tab 由通用 ComingSoon 替换为 EssayView
  • client/src/router/index.ts:新增 /practice/explainclient/src/api/index.ts 导出 AiExplain 类型。

接口实测(本地 OpenAI 兼容 mock + curl

场景 结果
未配置 AI source:fallback「AI 尚未配置已回退到题库标准解析用户答案Asteps=题库解析、answer=C
配置有效 Tokenmock source:aisummary/steps/knowledgePoints/commonMistakes/answer 结构化解析正确
deep 模式且无 userAnswer 正常返回 source:aiprompt 中用户作答为「未作答」)
超时AI_TIMEOUT_MS=1200 + 8s 慢响应) 1.2s 内返回 source:fallback「AI 请求超时」
AI 返回不可解析内容 source:fallback「AI 讲解暂时不可用」
非法输入 缺 questionId → VALIDATION_ERROR不存在题目 → NOT_FOUND非法 requestType → VALIDATION_ERROR
Token 不泄漏 后端日志仅含请求方法/URL/状态码,无 API KeyOpenAPI 无 AI Token仅有的 apiKey 字段是要闻 API 导入占位请求结构任务06 既有);前端源码无密钥

浏览器检查Chrome headless + CDP

场景 结果
AI 讲解页(配置) AI 生成徽章、结论、分步解析、考点、常见错误、答案 C 全部渲染
deep 模式 标题「AI 深度讲解」
错题详情 AI 按钮 可用;点击跳转 /practice/explain?questionId=demo-q-004&userAnswer=A
AI 未配置回退 UI 「题库解析回退」徽章 + 回退说明 + 题库解析步骤 + 正确答案
申论占位页 功能说明 + 五大题型 + 后续能力 + 不保存写作内容提示
移动 390 AI 讲解页与申论页均无横向溢出390/390
类型检查与构建 vue-tsc / tsc 通过;生产构建 139 模块通过;api:generate 与 OpenAPI 一致

截图:deliverables/checks/task11-ai-desktop.pngtask11-ai-mobile.pngtask11-ai-fallback-desktop.pngtask11-essay-desktop.pngtask11-essay-mobile.png

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

  • OpenAI 兼容客户端Chat Completions + Bearer Token环境变量配置
  • Token 配置读取(AI_BASE_URL / AI_API_KEY / AI_MODEL / AI_TIMEOUT_MSserver/.env.example 示例)。
  • 结构化讲解summary / steps / knowledgePoints / commonMistakes / answer
  • 超时处理AbortController + AI_TIMEOUT_MS,超时回退题库解析)。
  • 题库解析回退(未配置/超时/解析失败均回退,source:fallback 可识别,不阻塞刷题)。
  • 前端结果展示AI 讲解页 + 刷题结果/错题详情入口 + 未配置与失败提示)。
  • 申论占位页面(功能说明与后续入口,不保存写作内容)。
  • Token 不出现在前端、OpenAPI 与日志。

边界说明

  • 测试使用本地 OpenAI 兼容 mock 服务127.0.0.1:3199/3198/3197验证「配置有效」「超时」「不可解析」三条链路未使用真实外部 Token。
  • 未配置 AI 时不影响刷题、错题复习、模考等任何流程;设置页 aiConfigured 同步反映配置状态。

当前结论

任务 11 完成AI 讲解接口与前端结果页、未配置/超时/失败回退、申论占位页全部实测通过桌面与移动双端可操作Token 仅存于后端环境变量且未进入日志/文档/前端。