Files
my-springboot-project/docs/批阅接口测试.md

488 lines
29 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 批阅接口测试文档
## 一、接口说明
| 接口 | 地址 | 功能 |
| -------- | ------------------------------------------------------------- | --------------------- |
| 后端通用接口 | POST <http://localhost:8080/api/exam/grade> | 批阅答案(日常练习/模拟考/正式考试通用) |
| 后端正式考试接口 | POST <http://localhost:8080/api/exam/record/{recordId}/grade> | 正式考试专用批阅接口 |
| AI端接口 | POST <http://localhost:5001/exam/grade> | 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) |
| --------------- | -------------------------------------- | -------------------------------------------------------- | ---------------------------------- |
| 地址 | <http://localhost:8080/api/exam/grade> | <http://localhost:8080/api/exam/record/{recordId}/grade> | <http://localhost:5001/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<String, Object> 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: ""`)也是常见的边界测试场景
***
**文档结束**