# 批阅接口测试文档 ## 一、接口说明 | 接口 | 地址 | 功能 | | -------- | ------------------------------------------------------------- | --------------------- | | 后端通用接口 | POST | 批阅答案(日常练习/模拟考/正式考试通用) | | 后端正式考试接口 | POST | 正式考试专用批阅接口 | | AI端接口 | POST | AI端批阅答案 | **answerType 参数说明**:后端接口支持 `answerType` 字段区分答题类型,前端传入什么值后端就使用什么值。 | answerType 值 | 说明 | 重复答题 | | ------------- | ---- | ----------- | | `practice` | 日常练习 | 允许(更新记录) | | `mock_exam` | 模拟考 | 允许(更新记录) | | `formal_exam` | 正式考试 | 不允许(唯一索引保护) | *** ## 二、接口路径规范 **注意**:所有接口路径都在 `/api` 前缀下,实际完整路径为: - `http://localhost:8080/api/exam/grade` - `http://localhost:8080/api/exam/record/{recordId}/grade` *** ## 三、获取 Token 在测试前,需要先获取有效的访问令牌: ```bash curl -X POST http://localhost:8080/api/auth/login -H "Content-Type: application/json" -d '{"username":"admin","password":"123456"}' ``` **新 Token**(有效期2小时): ``` eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew ``` *** ## 四、后端接口测试 ### 4.1 单选题测试(日常练习) ```bash curl -X POST http://localhost:8080/api/exam/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answerType":"practice","requestId":"test_001","answers":[{"questionId":"ea6a7f44-9077-4f19-b10e-8239a5198f4d","questionType":"single_choice","content":{"stem":"根据文档内容,当发现人证不符、证件伪造或冒用证件时,应采取的措施是?","data":{"options":[{"key":"A","content":"允许入住并记录信息"},{"key":"B","content":"一律不予入住并立即上报属地公安机关"},{"key":"C","content":"暂时允许入住并后续核查"},{"key":"D","content":"要求重新提供证件"}]},"answer":"B"},"studentAnswer":"B","maxScore":2.0}]}' ``` ### 4.2 单选题测试2(日常练习) ```bash curl -X POST http://localhost:8080/api/exam/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answerType":"practice","requestId":"test_002","answers":[{"questionId":"9d59e7c5-edfc-4517-9fb5-780b389b66fb","questionType":"single_choice","content":{"stem":"根据文档内容,谁是住宿登记的第一责任人?","data":{"options":[{"key":"A","content":"安保人员"},{"key":"B","content":"前台工作人员"},{"key":"C","content":"经理"},{"key":"D","content":"客户"}]},"answer":"B"},"studentAnswer":"B","maxScore":2.0}]}' ``` ### 4.3 判断题测试(日常练习) ```bash curl -X POST http://localhost:8080/api/exam/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answerType":"practice","requestId":"test_003","answers":[{"questionId":"7699dfb0-e03e-4e9a-8653-450d101a85d3","questionType":"true_false","content":{"stem":"一级指标合计权重不低于70%。","data":{},"answer":"对"},"studentAnswer":"对","maxScore":1.0}]}' ``` ### 4.4 填空题测试(日常练习) ```bash curl -X POST http://localhost:8080/api/exam/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answerType":"practice","requestId":"test_004","answers":[{"questionId":"88eaf2d7-4adb-4daf-9978-3113e754b7d5","questionType":"fill_blank","content":{"stem":"零售价格指数的计算公式为:___。","data":{"blank_count":1},"answer":[["实际零售价格/零售指导价格*100%"]]},"studentAnswer":[["实际零售价格/零售指导价格*100%"]],"maxScore":2.0}]}' ``` ### 4.5 主观题测试(日常练习)无题目 ```bash curl -X POST http://localhost:8080/api/exam/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answerType":"practice","requestId":"test_005","answers":[{"questionId":"806754e9-3951-4562-8641-553c42564ab8","questionType":"subjective","content":{"stem":"请简述加强吸烟场所维护的主要目的及意义。","data":{"scoring_points":[{"point":"要点1:确保设施设备良好状态","weight":0.5},{"point":"要点2:保障文明吸烟环境功能发挥","weight":0.3},{"point":"要点3:提高消费者满意度","weight":0.2}]},"answer":"加强吸烟场所维护的主要目的是确保设施设备处于良好状态,保障文明吸烟环境功能作用的最大发挥,进一步提高消费者满意度。"},"studentAnswer":"加强吸烟场所维护可以确保设施良好,提升吸烟环境,让消费者更满意。","maxScore":10.0}]}' ``` ```bash curl -X POST http://localhost:8080/api/exam/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answerType":"practice","requestId":"test_subjective_001","answers":[{"questionId":"4c1907fa-81c8-4244-9d87-f7affe38b621","questionType":"subjective","content":{"stem":"请简述第一章总则中提到的核心原则,并结合实际应用场景说明其重要性。","data":{},"answer":"核心原则包括:1. 以用户需求为导向;2. 保证信息的准确性与可靠性;3. 遵循法律法规和行业规范。在实际应用中,这些原则确保了系统的有效性和合规性,避免因错误信息或违规操作导致的风险。"},"studentAnswer":"第一章总则的核心原则是以用户需求为导向,保证信息准确可靠,同时遵循法律法规和行业规范。这些原则在实际应用中非常重要,能够确保系统有效运行并符合合规要求。","maxScore":10.0}]}' ``` ### 4.6 批量测试(所有题型,包含错题,日常练习) ```bash curl -X POST http://localhost:8080/api/exam/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answerType":"practice","requestId":"batch_test_001","answers":[{"questionId":"ea6a7f44-9077-4f19-b10e-8239a5198f4d","questionType":"single_choice","content":{"stem":"根据文档内容,当发现人证不符、证件伪造或冒用证件时,应采取的措施是?","data":{"options":[{"key":"A","content":"允许入住并记录信息"},{"key":"B","content":"一律不予入住并立即上报属地公安机关"},{"key":"C","content":"暂时允许入住并后续核查"},{"key":"D","content":"要求重新提供证件"}]},"answer":"B"},"studentAnswer":"A","maxScore":2.0},{"questionId":"9d59e7c5-edfc-4517-9fb5-780b389b66fb","questionType":"single_choice","content":{"stem":"根据文档内容,谁是住宿登记的第一责任人?","data":{"options":[{"key":"A","content":"安保人员"},{"key":"B","content":"前台工作人员"},{"key":"C","content":"经理"},{"key":"D","content":"客户"}]},"answer":"B"},"studentAnswer":"C","maxScore":2.0},{"questionId":"7699dfb0-e03e-4e9a-8653-450d101a85d3","questionType":"true_false","content":{"stem":"一级指标合计权重不低于70%。","data":{},"answer":"对"},"studentAnswer":"错","maxScore":1.0}]}' ``` **错题说明**: - 单选题1:学生选A(正确答案是B) - 单选题2:学生选C(正确答案是B) - 判断题:学生选错(正确答案是对) ### 4.7 模拟考测试(answerType = mock_exam) ```bash curl -X POST http://localhost:8080/api/exam/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answerType":"mock_exam","requestId":"mock_test_001","answers":[{"questionId":"ea6a7f44-9077-4f19-b10e-8239a5198f4d","questionType":"single_choice","content":{"stem":"根据文档内容,当发现人证不符、证件伪造或冒用证件时,应采取的措施是?","data":{"options":[{"key":"A","content":"允许入住并记录信息"},{"key":"B","content":"一律不予入住并立即上报属地公安机关"},{"key":"C","content":"暂时允许入住并后续核查"},{"key":"D","content":"要求重新提供证件"}]},"answer":"B"},"studentAnswer":"B","maxScore":2.0},{"questionId":"9d59e7c5-edfc-4517-9fb5-780b389b66fb","questionType":"single_choice","content":{"stem":"根据文档内容,谁是住宿登记的第一责任人?","data":{"options":[{"key":"A","content":"安保人员"},{"key":"B","content":"前台工作人员"},{"key":"C","content":"经理"},{"key":"D","content":"客户"}]},"answer":"B"},"studentAnswer":"B","maxScore":2.0}]}' ``` ### 4.8 正式考测试(通过 recordId 接口,推荐方式) > **注意**:正式考试推荐使用 `/api/exam/record/{recordId}/grade` 接口提交。这种方式会关联已存在的考试记录。 ```bash curl -X POST http://localhost:8080/api/exam/record/17f5be59-3d81-480a-98bb-1e1a2a4556e6/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answers":[{"questionId":"ea6a7f44-9077-4f19-b10e-8239a5198f4d","questionType":"single_choice","answer":"B"},{"questionId":"9d59e7c5-edfc-4517-9fb5-780b389b66fb","questionType":"single_choice","answer":"B"}]}' ``` ### 4.9 正式考测试(通过通用接口 + recordId 参数) ```bash curl -X POST http://localhost:8080/api/exam/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answerType":"formal_exam","recordId":"17f5be59-3d81-480a-98bb-1e1a2a4556e6","requestId":"formal_test_001","paperId":"4e1c48d5-2019-48b6-a31b-2fea3ebf1b6f","answers":[{"questionId":"ea6a7f44-9077-4f19-b10e-8239a5198f4d","questionType":"single_choice","content":{"stem":"根据文档内容,当发现人证不符、证件伪造或冒用证件时,应采取的措施是?","data":{"options":[{"key":"A","content":"允许入住并记录信息"},{"key":"B","content":"一律不予入住并立即上报属地公安机关"},{"key":"C","content":"暂时允许入住并后续核查"},{"key":"D","content":"要求重新提供证件"}]},"answer":"B"},"studentAnswer":"B","maxScore":2.0}]}' ``` ### 4.10 空白试卷测试 - 日常练习(answers 为空数组) ```bash curl -X POST http://localhost:8080/api/exam/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answerType":"practice","requestId":"blank_test_001","answers":[]}' ``` ### 4.11 空白试卷测试 - 模拟考(answers 为空数组) ```bash curl -X POST http://localhost:8080/api/exam/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answerType":"mock_exam","requestId":"blank_test_002","answers":[]}' ``` ### 4.12 空白试卷测试 - 正式考试(通过 recordId 接口) ```bash curl -X POST http://localhost:8080/api/exam/record/ff860338-99ed-4211-bf85-fce6605c8fcc/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answers":[]}' ``` ### 4.13 空白试卷测试 - 正式考试(通过通用接口 + recordId) ```bash curl -X POST http://localhost:8080/api/exam/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answerType":"formal_exam","recordId":"ff860338-99ed-4211-bf85-fce6605c8fcc","requestId":"blank_test_003","answers":[]}' ``` ### 4.14 正式考试 - 只提交一道题(通过 recordId 接口) ```bash curl -X POST http://localhost:8080/api/exam/record/26b9fac0-3f92-4d71-a5dc-3e8b432bd580/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answers":[{"questionId":"ea6a7f44-9077-4f19-b10e-8239a5198f4d","questionType":"single_choice","answer":"B"}]}' ``` ### 4.15 正式考试 - 一道题没选(通过 recordId 接口) ```bash curl -X POST http://localhost:8080/api/exam/record/17f5be59-3d81-480a-98bb-1e1a2a4556e6/grade -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc4MTA5NTA5MCwiZXhwIjoxNzgxMTAyMjkwfQ.BXB2Zmv68coIsQcynBPFprCT-xfBNKhs_G_xSVsLnrr7eXbhfU8NUT7v_MZYRxfNarIqnUC-wWe1Xi3mnv4oew" -d '{"answers":[{"questionId":"ea6a7f44-9077-4f19-b10e-8239a5198f4d","questionType":"single_choice","answer":""},{"questionId":"9d59e7c5-edfc-4517-9fb5-780b389b66fb","questionType":"single_choice","answer":"B"}]}' ``` **answerType 测试总结**: | answerType 值 | 场景 | 重复提交同一题目 | 数据库行为 | | ------------- | ---- | -------- | ------------ | | `practice` | 日常练习 | 允许 | UPDATE 已有记录 | | `mock_exam` | 模拟考 | 允许 | UPDATE 已有记录 | | `formal_exam` | 正式考试 | 不允许 | 抛出异常(唯一索引保护) | *** ## 五、AI端接口测试 AI端接口**支持** **`explanation`** **字段**,可以直接使用包含完整题目信息的JSON。 ### 5.1 单选题测试 ```bash curl -X POST http://localhost:5001/exam/grade -H "Content-Type: application/json" -d '{"answers":[{"questionId":"ea6a7f44-9077-4f19-b10e-8239a5198f4d","questionType":"single_choice","content":{"stem":"根据文档内容,当发现人证不符、证件伪造或冒用证件时,应采取的措施是?","data":{"options":[{"key":"A","content":"允许入住并记录信息"},{"key":"B","content":"一律不予入住并立即上报属地公安机关"},{"key":"C","content":"暂时允许入住并后续核查"},{"key":"D","content":"要求重新提供证件"}]},"answer":"B","explanation":"根据文档第八条明确规定,发现人证不符、证件伪造、冒用证件的,一律不予入住,并立即上报属地公安机关。"},{"questionId":"9d59e7c5-edfc-4517-9fb5-780b389b66fb","questionType":"single_choice","content":{"stem":"根据文档内容,谁是住宿登记的第一责任人?","data":{"options":[{"key":"A","content":"安保人员"},{"key":"B","content":"前台工作人员"},{"key":"C","content":"经理"},{"key":"D","content":"客户"}]},"answer":"B","explanation":"根据文档第四条,前台工作人员被明确为住宿登记的第一责任人。"},"studentAnswer":"B","maxScore":2}]}' ``` ### 5.2 多选题测试 ```bash curl -X POST http://localhost:5001/exam/grade -H "Content-Type: application/json" -d '{"answers":[{"questionId":"q2","questionType":"multiple_choice","content":{"stem":"依据务求实效原则,以下哪些做法符合其核心要求?(可多选)","data":{"options":[{"key":"A","content":"科学设定终端投入标准"},{"key":"B","content":"严格执行终端投入标准"},{"key":"C","content":"优先采购高配置但非必需的智能设备"},{"key":"D","content":"坚决杜绝不必要的支出和浪费"}]},"answer":["A","B","D"],"explanation":"A、B、D均符合务求实效原则"},"studentAnswer":["A","B","D"],"maxScore":4}]}' ``` ### 5.3 空白试卷测试(answers 为空数组) ```bash curl -X POST http://localhost:5001/exam/grade -H "Content-Type: application/json" -d '{"answers":[]}' ``` **预期响应**: - **正常情况**(Python AI 已做空值防御): ```json { "data": { "requestId": null, "results": [], "scoreRate": 0.0, "success": true, "totalMaxScore": 0, "totalScore": 0 }, "message": "批阅完成", "status": "success", "statusCode": 2012, "success": true } ``` - **异常情况**(Python AI 未做空值防御): ```json { "error_code": "GRADE_ERROR", "message": "'NoneType' object has no attribute 'get'", "status": "failed", "status_code": 5021, "success": false } ``` ### 5.4 填空题空答案测试 ```bash curl -X POST http://localhost:5001/exam/grade -H "Content-Type: application/json" -d '{"answers":[{"questionId":"q3","questionType":"fill_blank","content":{"stem":"务求实效原则强调以___为出发点,通过科学设定和严格执行终端投入标准,实现___与___的双重提升。","data":{"blank_count":3},"answer":["终端功能发挥和服务水平提升","终端功能发挥","服务水平提升"]},"studentAnswer":null,"maxScore":3}]}' ``` ### 5.5 主观题空答案测试 ```bash curl -X POST http://localhost:5001/exam/grade -H "Content-Type: application/json" -d '{"answers":[{"questionId":"q4","questionType":"subjective","content":{"stem":"请简述\"务求实效原则\"的核心要求。","data":{"scoring_points":[{"point":"功能发挥","weight":0.5},{"point":"服务水平","weight":0.3},{"point":"杜绝浪费","weight":0.2}]},"answer":"以终端功能发挥和服务水平提升为唯一导向"},"studentAnswer":"","maxScore":5}]}' ``` ### 5.6 判断题空答案测试(studentAnswer 为空字符串) ```bash curl -X POST http://localhost:5001/exam/grade -H "Content-Type: application/json" -d '{"answers":[{"questionId":"q5","questionType":"true_false","content":{"stem":"务求实效原则允许在终端建设中适度预留冗余预算,以应对未来可能的功能升级需求。","answer":"false"},"studentAnswer":"","maxScore":2}]}' ``` ### 5.7 判断题空答案测试(studentAnswer 为 null) ```bash curl -X POST http://localhost:5001/exam/grade -H "Content-Type: application/json" -d '{"answers":[{"questionId":"q6","questionType":"true_false","content":{"stem":"务求实效原则强调以终端功能发挥和服务水平提升为唯一导向。","answer":"true"},"studentAnswer":null,"maxScore":2}]}' ``` ### 5.8 单选题空答案测试 ```bash curl -X POST http://localhost:5001/exam/grade -H "Content-Type: application/json" -d '{"answers":[{"questionId":"q7","questionType":"single_choice","content":{"stem":"根据文档内容,务求实效原则的核心要求聚焦于哪一根本目标?","data":{"options":[{"key":"A","content":"扩大终端数量规模"},{"key":"B","content":"提升终端信息化系统覆盖率"},{"key":"C","content":"着眼于终端功能发挥和服务水平提升"},{"key":"D","content":"统一各类终端建设外观标准"}]},"answer":"C"},"studentAnswer":null,"maxScore":2}]}' ``` ### 5.9 多选题空答案测试 ```bash curl -X POST http://localhost:5001/exam/grade -H "Content-Type: application/json" -d '{"answers":[{"questionId":"q8","questionType":"multiple_choice","content":{"stem":"依据务求实效原则,以下哪些做法符合其核心要求?(可多选)","data":{"options":[{"key":"A","content":"科学设定终端投入标准"},{"key":"B","content":"严格执行终端投入标准"},{"key":"C","content":"优先采购高配置但非必需的智能设备"},{"key":"D","content":"坚决杜绝不必要的支出和浪费"}]},"answer":["A","B","D"]},"studentAnswer":[],"maxScore":4}]}' ``` *** ## 六、接口对比总结 | 特性 | 后端通用接口 (/api/exam/grade) | 后端正式考试接口 (/api/exam/record/{recordId}/grade) | AI端接口 (/exam/grade) | | --------------- | -------------------------------------- | -------------------------------------------------------- | ---------------------------------- | | 地址 | | | | | 认证 | 需要 Bearer Token | 需要 Bearer Token | 不需要认证 | | requestId | 必需 | 不需要 | 不需要 | | recordId | 可选(正式考试时使用) | 路径参数(必需) | 不支持 | | answerType | 前端传入,后端原样使用 | 固定为 "formal_exam" | 不支持 | | questionId | 使用数据库UUID | 使用数据库UUID | 可自定义ID | | maxScore | 小数 (2.0) | 不需要(从数据库获取) | 整数 (2) | | explanation字段 | **不支持** | **不支持** | 支持 | | questionContent | 日常练习/模拟考时必需 | 不需要 | 支持 | **recordId 参数说明**: - 当在通用接口中传入 `recordId` 时,系统会尝试查找并更新对应的考试记录 - 这种方式主要用于正式考试场景,配合 `answerType: "formal_exam"` 使用 - 对于日常练习或模拟考,可以不传入 `recordId` - 推荐使用专门的 `/api/exam/record/{recordId}/grade` 接口进行正式考试 *** ## 七、预期响应格式 ### 7.1 后端通用接口响应示例(日常练习/模拟考) ```json { "code": 200, "message": "批阅成功", "data": { "requestId": "test_001", "results": [ { "questionId": "ea6a7f44-9077-4f19-b10e-8239a5198f4d", "correct": true, "feedback": "回答正确!", "score": 2.0, "maxScore": 2.0 } ], "totalScore": 2.0, "totalMaxScore": 2.0, "scoreRate": 100.0 } } ``` ### 7.2 后端正式考试接口响应示例 ```json { "code": 200, "message": "提交成功", "data": { "recordId": "17f5be59-3d81-480a-98bb-1e1a2a4556e6", "paperId": "4e1c48d5-2019-48b6-a31b-2fea3ebf1b6f", "userId": 1, "answerType": "formal_exam", "status": "graded", "totalScore": 4.0, "paperTitle": "自动生成的试卷", "answers": [ { "questionId": "ea6a7f44-9077-4f19-b10e-8239a5198f4d", "score": 2.0, "isCorrect": true, "feedback": "回答正确!" }, { "questionId": "9d59e7c5-edfc-4517-9fb5-780b389b66fb", "score": 2.0, "isCorrect": true, "feedback": "回答正确!" } ], "startTime": "2026-06-10T11:11:19", "submitTime": "2026-06-10T11:11:49", "gradedTime": "2026-06-10T11:11:49" } } ``` ### 7.3 AI端接口响应示例 ```json { "data": { "requestId": null, "results": [ { "correct": true, "feedback": "正确!", "maxScore": 2, "questionId": "ea6a7f44-9077-4f19-b10e-8239a5198f4d", "score": 2 } ], "scoreRate": 100.0, "success": true, "totalMaxScore": 2, "totalScore": 2 }, "message": "批阅完成", "status": "success", "statusCode": 2021, "success": true } ``` ### 7.4 空白试卷响应示例(日常练习/模拟考) ```json { "code": 200, "message": "批阅成功", "data": { "requestId": "blank_test_001", "results": [], "totalScore": 0.0, "totalMaxScore": 0.0, "scoreRate": 0.0 } } ``` ### 7.5 空白试卷响应示例(正式考试) ```json { "code": 200, "message": "提交成功", "data": { "recordId": "17f5be59-3d81-480a-98bb-1e1a2a4556e6", "paperId": "4e1c48d5-2019-48b6-a31b-2fea3ebf1b6f", "userId": 1, "answerType": "formal_exam", "status": "graded", "totalScore": 0.0, "paperTitle": "自动生成的试卷", "answers": [], "startTime": "2026-06-10T11:11:19", "submitTime": "2026-06-10T11:11:49", "gradedTime": "2026-06-10T11:11:49" } } ``` *** ## 八、测试数据来源说明 本测试文档中的题目数据均来源于数据库表 `question`,具体来源如下: | questionId | 题目类型 | 文档来源 | | -------------------------------------- | ---------------- | ------------------- | | `ea6a7f44-9077-4f19-b10e-8239a5198f4d` | single_choice | test.docx - 住宿登记规定 | | `9d59e7c5-edfc-4517-9fb5-780b389b66fb` | single_choice | test.docx - 住宿登记规定 | | `7699dfb0-e03e-4e9a-8653-450d101a85d3` | true_false | 1.docx - 指标权重规定 | | `88eaf2d7-4adb-4daf-9978-3113e754b7d5` | fill_blank | 1.docx - 零售价格指数公式 | | `806754e9-3951-4562-8641-553c42564ab8` | subjective | 3.docx - 吸烟场所维护 | **试卷信息**: - 试卷ID:`4e1c48d5-2019-48b6-a31b-2fea3ebf1b6f` - 试卷名称:自动生成的试卷 - 总分:4.00 - 题目数量:2 数据库文件路径:[knowledge_management_system.sql](file:///d:/Users/19211/Desktop/222/demo/docs/sql/knowledge_management_system.sql) ### 8.1 数据库题目查询 SQL 如需从数据库获取更多测试题目,可使用以下 SQL 查询: ```sql -- 查询所有已审核通过的题目 SELECT question_id, question_type, difficulty, score, content FROM question WHERE status = 'approved' ORDER BY question_type, id; -- 查询指定类型的题目 SELECT question_id, question_type, content FROM question WHERE status = 'approved' AND question_type = 'single_choice' LIMIT 10; -- 查询指定难度的题目 SELECT question_id, question_type, difficulty, content FROM question WHERE status = 'approved' AND difficulty = 3; ``` *** ## 九、重要提示 **后端接口 QuestionContent 字段定义**: ```java private String stem; private Map data; private Object answer; ``` **注意**:后端接口**不支持** **`explanation`** **字段**,如果传入会导致JSON解析错误。 **字段命名规范**: - 所有字段使用驼峰命名(camelCase),而不是下划线命名(snake_case) - 例如:`answerType`、`recordId`、`questionId`、`studentAnswer`、`maxScore` **使用建议**: 1. **所有curl命令已改为单行格式**,可以直接复制使用 2. **Token有效期2小时**,过期后需要重新获取 3. **测试时请确保后端服务和AI服务都已启动** 4. **日常练习和模拟考可以重复提交**,会自动更新记录 5. **正式考试只能提交一次**,重复提交会报错 **空白试卷测试说明**: - 空白试卷(`answers` 为空数组)测试用于验证系统在无答案情况下的处理能力 - 正常情况下,空白试卷应返回总分 0.0,不触发错误 - 若 Python AI 批改服务未做空值防御,可能会出现 `'NoneType' object has no attribute 'get'` 错误(500 状态码) - 相关修复方案可参考:`后端问题诊断报告_考试提交AI批改服务崩溃.md` **AI端空白试卷测试要点**: - AI端接口(`http://localhost:5001/exam/grade`)**支持完整的题目信息**,包含 `explanation` 字段 - AI端采用**小写驼峰命名**(如 `questionId`、`questionType`、`questionContent`、`studentAnswer`、`maxScore`) - 空白试卷测试重点验证 Python AI 服务的空值防御能力 - 填空题空答案(`studentAnswer: null`)和主观题空答案(`studentAnswer: ""`)也是常见的边界测试场景 *** **文档结束**