# 考试工作流-最终版 **版本:** v2.0 **状态:** ✅ 已完成并验证 **最后更新:** 2025-10-12 --- ## 一、功能概述 ### 考试页面 - **URL**:`http://localhost:3001/trainee/exam?courseId=1` - **流程**:三轮考试(正式考试 + 两次错题重考) - **试题生成**:动态调用Dify工作流,预计1-3分钟 ### 支持的题型 1. 单选题 - 点击立即判断 2. 多选题 - 点击提交判断 3. 判断题 - 点击立即判断 4. 填空题 - AI语义判断 5. 问答题 - AI语义判断 --- ## 二、Dify工作流配置 ### 工作流1:试题生成器 **API配置:** ``` URL: http://dify.ireborn.com.cn/v1/workflows/run Token: app-tDlrmXyS9NtWCShsOx5FH49L User: kaopeilian Mode: streaming ``` **输入参数:** ```json { "course_id": 1, "position_id": 3, "single_choice_count": 4, "multiple_choice_count": 2, "true_false_count": 1, "fill_blank_count": 2, "essay_count": 1, "difficulty_level": 3 } ``` **第二、三轮增加:** ```json { "mistake_records": "[{\"question_id\":null,\"knowledge_point_id\":456,...}]" } ``` ⚠️ **重要**:第一轮不传`mistake_records`参数,第二三轮传入JSON字符串格式 ### 工作流2:答案判断器 **API配置:** ``` URL: http://dify.ireborn.com.cn/v1/workflows/run Token: app-FvMdrvbRBz547DVZEorgO1WT User: kaopeilian Mode: streaming ``` **输入参数:** ```json { "question": "题目内容", "correct_answer": "正确答案", "user_answer": "用户答案", "analysis": "答案解析" } ``` **返回字段:** `result` 或 `is_correct`(值为"正确"/"错误"或true/false) --- ## 三、后端API接口 ### 接口列表 | 接口 | 方法 | 功能 | |------|------|------| | `/api/v1/exams/generate` | POST | 生成试题 | | `/api/v1/exams/judge-answer` | POST | 判断主观题答案 | | `/api/v1/exams/record-mistake` | POST | 记录错题 | | `/api/v1/exams/mistakes` | GET | 获取错题记录 | **文件位置:** `kaopeilian-backend/app/api/v1/exam.py` ### 关键实现 **获取岗位ID:** ```python # 从用户岗位分配信息中自动获取 position_member = await db.execute( select(PositionMember).where( PositionMember.user_id == current_user.id, PositionMember.is_deleted == False ) ) position_id = position_member.position_id if position_member else 1 ``` **创建Exam记录:** ```python exam = Exam( user_id=current_user.id, course_id=request.course_id, exam_name=f"课程{request.course_id}考试", status="started" ) await db.commit() return exam.id # 使用真实自增ID ``` --- ## 四、前端实现要点 ### 数据格式转换 **Dify格式 → 前端格式:** ```typescript { type: "single_choice" → "single", topic.title → title, topic.options → options[], correct → correctAnswer, analysis → explanation, knowledge_point_id → parseInt() } ``` ### 三轮考试流程 ```typescript // 第一轮:不传mistake_records await generateExam({ course_id: 1, // 不包含 mistake_records }) // 第二、三轮:传入上一轮错题 const mistakes = await getMistakes(lastExamId) await generateExam({ course_id: 1, mistake_records: JSON.stringify(mistakes.data.data.mistakes) }) ``` --- ## 五、关键配置 ### HTTP超时设置 ```typescript // 前端 generateExam: timeout 300000 // 5分钟 judgeAnswer: timeout 60000 // 1分钟 // 后端 httpx.AsyncClient(timeout=300.0) // 试题生成 httpx.AsyncClient(timeout=60.0) // 答案判断 ``` ### 数据库表 **exam_mistakes表:** - user_id, exam_id(必填) - question_id, knowledge_point_id(可空) - question_content, correct_answer, user_answer --- ## 六、重要经验 ### FastAPI路由顺序 ```python # ✅ 正确顺序 @router.get("/mistakes") # 具体路由在前 @router.get("/{exam_id}") # 动态路由在后 ``` ### ResponseModel使用 ```python # ✅ 统一使用ResponseModel @router.get("/mistakes", response_model=ResponseModel[GetMistakesResponse]) async def get_mistakes(...): return ResponseModel(code=200, data=GetMistakesResponse(...)) ``` ### 数据库ID生成 - ❌ 不使用时间戳(13位数字超出INT范围) - ✅ 使用数据库自增ID ### Axios响应访问 ```typescript // ✅ 正确路径 response.data.code response.data.data.result response.data.data.exam_id ``` --- ## 七、测试账号 - **用户名:** admin - **密码:** admin123 - **测试课程:** courseId=1 --- **文档维护:** AI助手 **最后验证:** 2025-10-12(三轮考试流程验证成功)