feat: 初始化考培练系统项目

- 从服务器拉取完整代码
- 按框架规范整理项目结构
- 配置 Drone CI 测试环境部署
- 包含后端(FastAPI)、前端(Vue3)、管理端

技术栈: Vue3 + TypeScript + FastAPI + MySQL
This commit is contained in:
111
2026-01-24 19:33:28 +08:00
commit 998211c483
1197 changed files with 228429 additions and 0 deletions

199
tests/test_exam_api.py Normal file
View File

@@ -0,0 +1,199 @@
#!/usr/bin/env python3
"""
测试考试API接口
"""
import requests
import json
import time
# API配置
BASE_URL = "http://localhost:8000/api/v1"
# 使用有效的token需要先登录获取
TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEsImV4cCI6MTc0MTQxOTQ5Mn0.0ZoiGJaIpV0WvVdH-M2tq03RMfRd9OKUJvDIgJtJoXk"
headers = {
"Authorization": f"Bearer {TOKEN}",
"Content-Type": "application/json"
}
def test_generate_exam():
"""测试生成考试试题"""
print("\n" + "="*50)
print("测试1: 生成考试试题")
print("="*50)
url = f"{BASE_URL}/exams/generate"
data = {
"course_id": 1,
"single_choice_count": 2,
"multiple_choice_count": 1,
"true_false_count": 1,
"fill_blank_count": 1,
"essay_count": 0,
"difficulty_level": 3,
"mistake_records": "[]"
}
print(f"请求URL: {url}")
print(f"请求数据: {json.dumps(data, indent=2, ensure_ascii=False)}")
print("\n正在调用Dify工作流生成试题请稍候...")
try:
response = requests.post(url, json=data, headers=headers, timeout=300)
print(f"\n响应状态码: {response.status_code}")
if response.status_code == 200:
result = response.json()
print(f"响应数据: {json.dumps(result, indent=2, ensure_ascii=False)[:500]}...")
# 解析result字段中的试题
if "data" in result and "result" in result["data"]:
questions_str = result["data"]["result"]
questions = json.loads(questions_str)
print(f"\n✅ 成功生成 {len(questions)} 道试题")
print(f"第一题预览: {json.dumps(questions[0], indent=2, ensure_ascii=False)[:300]}...")
return questions
else:
print("❌ 响应格式不正确")
else:
print(f"❌ 请求失败: {response.text}")
except requests.exceptions.Timeout:
print("❌ 请求超时可能Dify工作流执行时间较长")
except Exception as e:
print(f"❌ 请求异常: {str(e)}")
return None
def test_judge_answer():
"""测试判断主观题答案"""
print("\n" + "="*50)
print("测试2: 判断主观题答案")
print("="*50)
url = f"{BASE_URL}/exams/judge-answer"
data = {
"question": "肉毒素注射后____小时内不能平躺",
"correct_answer": "4",
"user_answer": "4"
}
print(f"请求URL: {url}")
print(f"请求数据: {json.dumps(data, indent=2, ensure_ascii=False)}")
print("\n正在调用Dify答案判断工作流...")
try:
response = requests.post(url, json=data, headers=headers, timeout=60)
print(f"\n响应状态码: {response.status_code}")
if response.status_code == 200:
result = response.json()
print(f"响应数据: {json.dumps(result, indent=2, ensure_ascii=False)}")
if "data" in result:
is_correct = result["data"].get("is_correct")
print(f"\n✅ 判断结果: {'正确' if is_correct else '错误'}")
return result
else:
print(f"❌ 请求失败: {response.text}")
except Exception as e:
print(f"❌ 请求异常: {str(e)}")
return None
def test_record_mistake():
"""测试记录错题"""
print("\n" + "="*50)
print("测试3: 记录错题")
print("="*50)
url = f"{BASE_URL}/exams/record-mistake"
data = {
"exam_id": 1,
"question_id": None,
"knowledge_point_id": 199,
"question_content": "以下哪一项最能准确描述艾维岚Avilan在医美注射材料中的独特作用机制",
"correct_answer": "B它是唯一可以做减法的注射材料实现收紧而不增容。",
"user_answer": "A它是一款主要用于增容塑形的支撑型材料。"
}
print(f"请求URL: {url}")
print(f"请求数据: {json.dumps(data, indent=2, ensure_ascii=False)}")
try:
response = requests.post(url, json=data, headers=headers, timeout=30)
print(f"\n响应状态码: {response.status_code}")
if response.status_code == 200:
result = response.json()
print(f"响应数据: {json.dumps(result, indent=2, ensure_ascii=False)}")
if "data" in result:
print(f"\n✅ 成功记录错题ID: {result['data'].get('id')}")
return result
else:
print(f"❌ 请求失败: {response.text}")
except Exception as e:
print(f"❌ 请求异常: {str(e)}")
return None
def test_get_mistakes():
"""测试获取错题记录"""
print("\n" + "="*50)
print("测试4: 获取错题记录")
print("="*50)
exam_id = 1
url = f"{BASE_URL}/exams/mistakes?exam_id={exam_id}"
print(f"请求URL: {url}")
try:
response = requests.get(url, headers=headers, timeout=30)
print(f"\n响应状态码: {response.status_code}")
if response.status_code == 200:
result = response.json()
print(f"响应数据: {json.dumps(result, indent=2, ensure_ascii=False)[:500]}...")
if "data" in result and "mistakes" in result["data"]:
mistakes = result["data"]["mistakes"]
print(f"\n✅ 成功获取 {len(mistakes)} 条错题记录")
return result
else:
print(f"❌ 请求失败: {response.text}")
except Exception as e:
print(f"❌ 请求异常: {str(e)}")
return None
def main():
"""主测试流程"""
print("\n" + "="*60)
print("开始测试考试API接口")
print("="*60)
# 测试1: 生成考试试题调用Dify工作流
# 注意这个测试可能需要较长时间因为要调用Dify工作流
# questions = test_generate_exam()
# 测试2: 判断答案调用Dify工作流
test_judge_answer()
# 测试3: 记录错题
test_record_mistake()
# 测试4: 获取错题记录
test_get_mistakes()
print("\n" + "="*60)
print("测试完成")
print("="*60)
print("\n注意: 试题生成测试已注释因为需要较长时间调用Dify工作流")
print("如需测试,请取消注释 test_generate_exam() 行")
if __name__ == "__main__":
main()