524 lines
13 KiB
Markdown
524 lines
13 KiB
Markdown
# 考试信息API使用文档
|
||
|
||
## 接口概述
|
||
|
||
`/aiol/aiolExam/getExamInfo` 接口用于获取教师名下的考试信息列表。
|
||
|
||
## 接口定义
|
||
|
||
### 请求方式
|
||
- **方法**: GET
|
||
- **路径**: `/aiol/aiolExam/getExamInfo`
|
||
- **参数**: `userId` (查询参数)
|
||
|
||
### 请求参数
|
||
|
||
| 参数名 | 类型 | 必选 | 说明 |
|
||
|--------|------|------|------|
|
||
| userId | string | 是 | 教师用户ID |
|
||
|
||
### 响应格式
|
||
|
||
```typescript
|
||
{
|
||
"success": boolean,
|
||
"message": string,
|
||
"code": number,
|
||
"result": ExamInfo[],
|
||
"timestamp": number
|
||
}
|
||
```
|
||
|
||
### ExamInfo 数据结构
|
||
|
||
```typescript
|
||
interface ExamInfo {
|
||
id: string // 考试ID
|
||
name: string // 考试名称
|
||
paperId: string // 试卷ID
|
||
startTime: string // 开始时间
|
||
endTime: string // 结束时间
|
||
totalTime: number // 考试时长(分钟)
|
||
type: number // 考试类型:0=练习,1=考试
|
||
status: number // 状态:0=未发布,1=发布中,2=已结束
|
||
createBy: string // 创建人
|
||
createTime: string // 创建时间
|
||
updateBy: string // 更新人
|
||
updateTime: string // 更新时间
|
||
}
|
||
```
|
||
|
||
## 使用示例
|
||
|
||
### 1. 在API模块中调用
|
||
|
||
```typescript
|
||
import { ExamApi } from '@/api/modules/exam'
|
||
|
||
// 获取教师考试信息
|
||
const response = await ExamApi.getExamInfo('teacher_user_id')
|
||
console.log('考试信息:', response.data)
|
||
```
|
||
|
||
### 2. 在Vue组件中使用
|
||
|
||
```typescript
|
||
import { ExamApi } from '@/api/modules/exam'
|
||
import { useUserStore } from '@/stores/user'
|
||
|
||
export default {
|
||
setup() {
|
||
const userStore = useUserStore()
|
||
|
||
const loadExamInfo = async () => {
|
||
if (!userStore.user?.id) {
|
||
console.error('请先登录')
|
||
return
|
||
}
|
||
|
||
try {
|
||
const response = await ExamApi.getExamInfo(userStore.user.id.toString())
|
||
return response.data || []
|
||
} catch (error) {
|
||
console.error('加载考试信息失败:', error)
|
||
return []
|
||
}
|
||
}
|
||
|
||
return {
|
||
loadExamInfo
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. 在试卷管理页面中使用
|
||
|
||
```typescript
|
||
// 在 ExamLibrary.vue 中
|
||
import { ExamApi } from '@/api/modules/exam'
|
||
import { useUserStore } from '@/stores/user'
|
||
import type { ExamInfo } from '@/api/types'
|
||
|
||
const userStore = useUserStore()
|
||
|
||
const loadExamInfo = async () => {
|
||
loading.value = true
|
||
try {
|
||
const currentUser = userStore.user
|
||
if (!currentUser?.id) {
|
||
message.error('请先登录')
|
||
return
|
||
}
|
||
|
||
const response = await ExamApi.getExamInfo(currentUser.id.toString())
|
||
|
||
if (response.data && Array.isArray(response.data)) {
|
||
// 数据映射和显示逻辑
|
||
const mappedList = response.data.map((item: ExamInfo) => {
|
||
// 映射逻辑...
|
||
return {
|
||
id: item.id,
|
||
name: item.name,
|
||
// ... 其他字段映射
|
||
}
|
||
})
|
||
|
||
examData.value = mappedList
|
||
}
|
||
} catch (error) {
|
||
console.error('加载考试信息失败:', error)
|
||
message.error('加载考试信息失败')
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
```
|
||
|
||
## 数据映射说明
|
||
|
||
### 状态映射
|
||
```typescript
|
||
const statusMap: { [key: number]: string } = {
|
||
0: '未发布',
|
||
1: '发布中',
|
||
2: '已结束'
|
||
}
|
||
```
|
||
|
||
### 类型映射
|
||
```typescript
|
||
const categoryMap: { [key: number]: string } = {
|
||
0: '练习',
|
||
1: '考试'
|
||
}
|
||
```
|
||
|
||
### 难度映射
|
||
```typescript
|
||
const difficultyMap: { [key: number]: string } = {
|
||
0: '易',
|
||
1: '中',
|
||
2: '难'
|
||
}
|
||
```
|
||
|
||
## 错误处理
|
||
|
||
接口可能返回以下错误:
|
||
|
||
1. **401 Unauthorized**: 用户未登录或token过期
|
||
2. **403 Forbidden**: 没有权限访问
|
||
3. **500 Internal Server Error**: 服务器内部错误
|
||
|
||
建议在调用时添加适当的错误处理:
|
||
|
||
```typescript
|
||
try {
|
||
const response = await ExamApi.getExamInfo(userId)
|
||
// 处理成功响应
|
||
} catch (error) {
|
||
if (error.response?.status === 401) {
|
||
// 处理认证错误
|
||
console.error('登录已过期,请重新登录')
|
||
} else {
|
||
// 处理其他错误
|
||
console.error('获取考试信息失败:', error.message)
|
||
}
|
||
}
|
||
```
|
||
|
||
## 注意事项
|
||
|
||
1. 调用此接口前需要确保用户已登录
|
||
2. 只有教师用户才能调用此接口
|
||
3. 返回的考试信息按创建时间倒序排列
|
||
4. 建议在组件挂载时调用此接口加载数据
|
||
5. 可以根据需要添加分页、搜索等参数(需要后端支持)
|
||
|
||
## 相关文件
|
||
|
||
- API实现: `src/api/modules/exam.ts`
|
||
- 类型定义: `src/api/types.ts`
|
||
- 使用示例: `src/api/examples/getExamInfo-example.ts`
|
||
- 页面实现: `src/views/teacher/ExamPages/ExamLibrary.vue`
|
||
|
||
---
|
||
|
||
# 创建试卷API使用文档
|
||
|
||
## 接口概述
|
||
|
||
`POST /aiol/aiolPaper/add` 接口用于创建新的试卷。
|
||
|
||
## 接口定义
|
||
|
||
### 请求方式
|
||
- **方法**: POST
|
||
- **路径**: `/aiol/aiolPaper/add`
|
||
- **Content-Type**: `application/json`
|
||
|
||
### 请求参数
|
||
|
||
| 参数名 | 类型 | 必选 | 说明 |
|
||
|--------|------|------|------|
|
||
| title | string | 是 | 试卷标题 |
|
||
| generateMode | number | 否 | 组卷模式:0=固定试卷组,1=随机抽题组卷 |
|
||
| rules | string | 否 | 组卷规则(随机抽题时使用) |
|
||
| repoId | string | 否 | 题库ID(随机抽题时使用) |
|
||
| totalScore | number | 是 | 试卷总分 |
|
||
| passScore | number | 否 | 及格分数(默认总分的60%) |
|
||
| requireReview | number | 否 | 是否需要批阅:0=不需要,1=需要 |
|
||
|
||
### 响应格式
|
||
|
||
```typescript
|
||
{
|
||
"success": boolean,
|
||
"message": string,
|
||
"code": number,
|
||
"result": string, // 试卷ID
|
||
"timestamp": number
|
||
}
|
||
```
|
||
|
||
## 使用示例
|
||
|
||
### 1. 在API模块中调用
|
||
|
||
```typescript
|
||
import { ExamApi } from '@/api/modules/exam'
|
||
|
||
// 创建固定试卷组
|
||
const response = await ExamApi.createExamPaper({
|
||
title: '数学期末考试试卷',
|
||
generateMode: 0,
|
||
totalScore: 100,
|
||
passScore: 60,
|
||
requireReview: 0
|
||
})
|
||
console.log('试卷ID:', response.data)
|
||
```
|
||
|
||
### 2. 在Vue组件中使用
|
||
|
||
```typescript
|
||
// 在 AddExam.vue 中
|
||
const saveExam = async () => {
|
||
try {
|
||
const apiData = {
|
||
title: examForm.title,
|
||
generateMode: examForm.type === 1 ? 0 : 1,
|
||
rules: '',
|
||
repoId: '',
|
||
totalScore: examForm.totalScore,
|
||
passScore: examForm.passScore || Math.floor(examForm.totalScore * 0.6),
|
||
requireReview: examForm.useAIGrading ? 1 : 0
|
||
}
|
||
|
||
const response = await ExamApi.createExamPaper(apiData)
|
||
console.log('创建试卷成功:', response.data)
|
||
} catch (error) {
|
||
console.error('创建试卷失败:', error)
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. 不同组卷模式示例
|
||
|
||
```typescript
|
||
// 固定试卷组
|
||
const fixedPaper = {
|
||
title: '固定试卷组示例',
|
||
generateMode: 0,
|
||
rules: '',
|
||
repoId: '',
|
||
totalScore: 100,
|
||
passScore: 60,
|
||
requireReview: 0
|
||
}
|
||
|
||
// 随机抽题组卷
|
||
const randomPaper = {
|
||
title: '随机抽题组卷示例',
|
||
generateMode: 1,
|
||
rules: '{"difficulty": [1, 2, 3], "types": [0, 1, 2], "count": 20}',
|
||
repoId: 'repo_123',
|
||
totalScore: 100,
|
||
passScore: 60,
|
||
requireReview: 1
|
||
}
|
||
```
|
||
|
||
## 相关文件
|
||
|
||
- API实现: `src/api/modules/exam.ts`
|
||
- 页面实现: `src/views/teacher/ExamPages/AddExam.vue`
|
||
- 使用示例: `src/api/examples/createPaper-example.ts`
|
||
|
||
---
|
||
|
||
# 删除试卷API使用文档
|
||
|
||
## 接口概述
|
||
|
||
删除试卷相关的API接口包括单个删除和批量删除功能。
|
||
|
||
## 接口定义
|
||
|
||
### 1. 删除单个试卷
|
||
|
||
- **方法**: DELETE
|
||
- **路径**: `/aiol/aiolPaper/delete?id={paperId}`
|
||
- **参数**: `id` (查询参数) - 试卷ID
|
||
|
||
### 2. 批量删除试卷
|
||
|
||
- **实现方式**: 循环调用单个删除接口(因为后端可能不支持批量删除接口)
|
||
- **方法**: 内部调用多个 `DELETE /aiol/aiolPaper/delete?id={paperId}`
|
||
- **参数**: `ids: string[]` - 试卷ID数组
|
||
|
||
### 响应格式
|
||
|
||
**单个删除响应**:
|
||
```typescript
|
||
{
|
||
"success": boolean,
|
||
"message": string,
|
||
"code": number,
|
||
"result": string,
|
||
"timestamp": number
|
||
}
|
||
```
|
||
|
||
**批量删除响应**:
|
||
```typescript
|
||
{
|
||
"success": boolean,
|
||
"message": string,
|
||
"code": number,
|
||
"result": {
|
||
"success": number, // 成功删除的数量
|
||
"failed": number, // 失败删除的数量
|
||
"total": number, // 总数量
|
||
"errors": string[] // 错误信息数组
|
||
},
|
||
"timestamp": number
|
||
}
|
||
```
|
||
|
||
## 使用示例
|
||
|
||
### 1. 删除单个试卷
|
||
|
||
```typescript
|
||
import { ExamApi } from '@/api/modules/exam'
|
||
|
||
// 删除单个试卷
|
||
const response = await ExamApi.deleteExamPaper('1962379646322384897')
|
||
console.log('删除结果:', response.data)
|
||
```
|
||
|
||
### 2. 批量删除试卷
|
||
|
||
```typescript
|
||
// 批量删除试卷
|
||
const paperIds = ['1962379646322384897', '1966450638717292545']
|
||
const response = await ExamApi.batchDeleteExamPapers(paperIds)
|
||
console.log('批量删除结果:', response.data)
|
||
```
|
||
|
||
### 3. 在Vue组件中使用(使用 Naive UI 对话框组件)
|
||
|
||
```typescript
|
||
// 在 ExamLibrary.vue 中
|
||
import { useDialog, useMessage } from 'naive-ui'
|
||
|
||
const dialog = useDialog()
|
||
const message = useMessage()
|
||
|
||
const handleDeletePaper = async (row: any) => {
|
||
try {
|
||
// 使用 Naive UI 对话框组件
|
||
dialog.warning({
|
||
title: '确认删除',
|
||
content: `确定要删除试卷"${row.name}"吗?此操作不可撤销。`,
|
||
positiveText: '确定删除',
|
||
negativeText: '取消',
|
||
onPositiveClick: async () => {
|
||
try {
|
||
// 调用删除API
|
||
const response = await ExamApi.deleteExamPaper(row.id)
|
||
|
||
// 显示成功消息
|
||
message.success('试卷删除成功!')
|
||
|
||
// 重新加载试卷列表
|
||
await loadExamPaperList()
|
||
} catch (error) {
|
||
console.error('删除试卷失败:', error)
|
||
message.error('删除试卷失败,请重试')
|
||
}
|
||
}
|
||
})
|
||
} catch (error) {
|
||
console.error('删除试卷失败:', error)
|
||
message.error('删除试卷失败,请重试')
|
||
}
|
||
}
|
||
|
||
// 批量删除示例
|
||
const handleBatchDelete = async () => {
|
||
if (checkedRowKeys.value.length === 0) {
|
||
message.warning('请先选择要删除的试卷')
|
||
return
|
||
}
|
||
|
||
try {
|
||
// 使用 Naive UI 对话框组件
|
||
dialog.error({
|
||
title: '确认批量删除',
|
||
content: `确定要删除选中的 ${checkedRowKeys.value.length} 个试卷吗?此操作不可撤销。`,
|
||
positiveText: '确定删除',
|
||
negativeText: '取消',
|
||
onPositiveClick: async () => {
|
||
try {
|
||
// 调用批量删除API
|
||
const response = await ExamApi.batchDeleteExamPapers(checkedRowKeys.value as string[])
|
||
|
||
// 显示成功消息
|
||
message.success(`成功删除 ${checkedRowKeys.value.length} 个试卷!`)
|
||
|
||
// 清空选中状态
|
||
checkedRowKeys.value = []
|
||
|
||
// 重新加载试卷列表
|
||
await loadExamPaperList()
|
||
} catch (error) {
|
||
console.error('批量删除试卷失败:', error)
|
||
message.error('批量删除试卷失败,请重试')
|
||
}
|
||
}
|
||
})
|
||
} catch (error) {
|
||
console.error('批量删除试卷失败:', error)
|
||
message.error('批量删除试卷失败,请重试')
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4. 错误处理
|
||
|
||
```typescript
|
||
const deletePaperWithErrorHandling = async (paperId: string) => {
|
||
try {
|
||
const response = await ExamApi.deleteExamPaper(paperId)
|
||
|
||
if (response.data === 'success') {
|
||
return { success: true, message: '删除成功' }
|
||
} else {
|
||
return { success: false, message: '删除失败,请重试' }
|
||
}
|
||
|
||
} catch (error: any) {
|
||
if (error.response?.status === 404) {
|
||
return { success: false, message: '试卷不存在' }
|
||
} else if (error.response?.status === 403) {
|
||
return { success: false, message: '没有权限删除此试卷' }
|
||
}
|
||
|
||
return { success: false, message: '删除失败,请检查网络连接' }
|
||
}
|
||
}
|
||
```
|
||
|
||
## 功能特性
|
||
|
||
### 单个删除
|
||
- 支持删除单个试卷
|
||
- 使用 Naive UI 警告对话框组件
|
||
- 删除成功后自动刷新列表
|
||
- 完整的错误处理
|
||
|
||
### 批量删除
|
||
- 支持同时删除多个试卷
|
||
- 循环调用单个删除接口(避免后端接口不存在的问题)
|
||
- 逐个删除,避免对服务器造成过大压力
|
||
- 详细的删除结果反馈(成功/失败数量)
|
||
- 使用 Naive UI 错误对话框组件(更醒目的警告)
|
||
- 删除后清空选中状态
|
||
|
||
### 用户体验
|
||
- **美观的确认对话框**: 使用 Naive UI 组件,样式统一美观
|
||
- **不同类型的对话框**: 单个删除使用 warning,批量删除使用 error
|
||
- **成功/失败消息提示**: 使用 Naive UI 的 message 组件
|
||
- **按钮状态管理**: 批量删除按钮在未选中时禁用
|
||
- **实时更新选中数量显示**: 动态显示选中的试卷数量
|
||
- **异步操作处理**: 在对话框确认后才执行删除操作
|
||
|
||
## 相关文件
|
||
|
||
- API实现: `src/api/modules/exam.ts`
|
||
- 页面实现: `src/views/teacher/ExamPages/ExamLibrary.vue`
|
||
- 使用示例: `src/api/examples/deletePaper-example.ts`
|