- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
4.5 KiB
4.5 KiB
考试工作流-最终版
版本: v2.0
状态: ✅ 已完成并验证
最后更新: 2025-10-12
一、功能概述
考试页面
- URL:
http://localhost:3001/trainee/exam?courseId=1 - 流程:三轮考试(正式考试 + 两次错题重考)
- 试题生成:动态调用Dify工作流,预计1-3分钟
支持的题型
- 单选题 - 点击立即判断
- 多选题 - 点击提交判断
- 判断题 - 点击立即判断
- 填空题 - AI语义判断
- 问答题 - AI语义判断
二、Dify工作流配置
工作流1:试题生成器
API配置:
URL: http://dify.ireborn.com.cn/v1/workflows/run
Token: app-tDlrmXyS9NtWCShsOx5FH49L
User: kaopeilian
Mode: streaming
输入参数:
{
"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
}
第二、三轮增加:
{
"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
输入参数:
{
"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:
# 从用户岗位分配信息中自动获取
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记录:
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格式 → 前端格式:
{
type: "single_choice" → "single",
topic.title → title,
topic.options → options[],
correct → correctAnswer,
analysis → explanation,
knowledge_point_id → parseInt()
}
三轮考试流程
// 第一轮:不传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超时设置
// 前端
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路由顺序
# ✅ 正确顺序
@router.get("/mistakes") # 具体路由在前
@router.get("/{exam_id}") # 动态路由在后
ResponseModel使用
# ✅ 统一使用ResponseModel
@router.get("/mistakes", response_model=ResponseModel[GetMistakesResponse])
async def get_mistakes(...):
return ResponseModel(code=200, data=GetMistakesResponse(...))
数据库ID生成
- ❌ 不使用时间戳(13位数字超出INT范围)
- ✅ 使用数据库自增ID
Axios响应访问
// ✅ 正确路径
response.data.code
response.data.data.result
response.data.data.exam_id
七、测试账号
- 用户名: admin
- 密码: admin123
- 测试课程: courseId=1
文档维护: AI助手
最后验证: 2025-10-12(三轮考试流程验证成功)