# 知识库管理系统 - 完整接口文档

## 文档信息

| 项目         | 内容                 |
| ---------- | ------------------ |
| **文档名称**   | 知识库管理系统完整接口文档    |
| **版本号**   | V2.15.0            |
| **发布日期**   | 2026-05-29         |
| **文档状态**   | 正式发布               |
| **接口基础路径** | `/api`             |
| **认证方式**   | Bearer Token (JWT) |

---

## 一、认证说明

### 1.1 认证流程

所有接口（除登录接口外）均需要在请求头中携带有效的JWT Token：

```
Authorization: Bearer <token>
```

**Token获取方式**：
- 通过 `/api/auth/login` 接口登录获取
- Token有效期为24小时

### 1.2 通用请求头

| 请求头           | 类型     | 必填 | 说明                                     |
| ------------- | ------ | -- | -------------------------------------- |
| Content-Type  | string | 是  | application/json 或 multipart/form-data |
| Authorization | string | 是  | Bearer Token认证信息                       |

### 1.3 通用响应格式

```json
{
  "code": 200,
  "message": "成功",
  "data": {},
  "timestamp": "2026-05-17 10:00:00"
}
```

**响应状态码说明**：

| 状态码 | 说明          |
| --- | ----------- |
| 200 | 成功          |
| 400 | 请求参数错误      |
| 401 | 未授权/Token无效 |
| 403 | 权限不足        |
| 404 | 资源不存在       |
| 500 | 服务器内部错误     |

---

## 二、认证接口

### 2.1 登录

**接口路径**: `POST /api/auth/login`

**请求体**:
```json
{
  "username": "admin",
  "password": "123456"
}
```

**响应示例**:
```json
{
  "code": 200,
  "message": "登录成功",
  "data": {
    "token": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwidXNlcm5hbWUiOiJhZG1pbiIsImlhdCI6MTc3ODQzNDg1MCwiZXhwIjoxNzc4NDQyMDUwfQ.q38XpqBPFMrYTuupyTN-trR4p_e80yyNLw2reuybPov6A-EBvmFtXjh_l61hCrLax6Zx6KrdAVFHC9gtNQVLjg",
    "user": {
      "id": 1,
      "username": "admin",
      "role": 1
    }
  },
  "timestamp": "2026-05-17 10:00:00"
}
```

---

## 三、向量库管理接口

### 模块说明

向量库（也称知识库）是本系统的核心概念，所有向量库的管理操作都通过本模块完成。

**核心设计**：
- 创建/更新/删除向量库时，先调用AI端接口，再同步到 `knowledge_base_path` 表
- `knowledge_base_path` 表存储向量库的元信息（部门、公开/私密、属于公司或个人等）

**基础路径**：`/api/collection`

---

### 3.1 获取向量库列表

**接口路径**: `GET /api/collection`

**响应示例**:
```json
{
  "code": 200,
  "message": "成功",
  "data": [
    {
      "name": "public_kb",
      "displayName": "公开知识库",
      "documentCount": 150,
      "department": "公共部门",
      "description": "全员可访问",
      "ownerType": "department",
      "visibility": "public",
      "uploader": "1",
      "fileSize": 5242880,
      "createTime": "2026-01-01T10:00:00",
      "updateTime": "2026-01-01T10:00:00"
    }
  ],
  "timestamp": "2026-05-17 10:00:00"
}
```

---

### 3.2 创建向量库

**接口路径**: `POST /api/collection`

**请求参数**:
| 参数名         | 类型     | 必填 | 说明                           |
| ----------- | ------ | -- | ---------------------------- |
| name        | String | 是  | 向量库名称（唯一）                    |
| displayName | String | 否  | 显示名称，默认使用name                |
| department  | String | 否  | 所属部门，有值时ownerType为department |
| description | String | 否  | 描述信息                         |

**请求示例**:
```http
POST /api/collection?name=dept_hr&displayName=人力资源知识库&department=人事部门&description=人力资源部专用知识库
Authorization: Bearer <token>
```

---

### 3.3 修改向量库

**接口路径**: `PUT /api/collection/{name}`

**请求参数**:
| 参数名         | 类型     | 必填 | 说明   |
| ----------- | ------ | -- | ---- |
| displayName | String | 否  | 显示名称 |
| department  | String | 否  | 所属部门 |
| description | String | 否  | 描述信息 |

---

### 3.4 删除向量库

**接口路径**: `DELETE /api/collection/{name}`

---

### 3.5 文件向量化（单文件）

**接口路径**: `POST /api/collection/{name}/vectorize`

**请求参数**:
| 参数名    | 类型   | 必填 | 说明   |
| ------ | ---- | -- | ---- |
| fileId | Long | 是  | 文件ID |

**响应示例**:
```json
{
  "code": 200,
  "message": "成功",
  "data": {
    "success": true,
    "message": "文件已成功解析并存储到向量库",
    "fileId": 1,
    "fileName": "考勤制度.pdf",
    "collection": "public_kb",
    "fileSize": 1024000,
    "chunkCount": 15,
    "path": "public_kb/考勤制度.pdf"
  },
  "timestamp": "2026-05-17 10:00:00"
}
```

---

### 3.6 批量文件向量化

**接口路径**: `POST /api/collection/{name}/vectorize/batch`

**请求参数**:
| 参数名     | 类型         | 必填 | 说明     |
| ------- | ---------- | -- | ------ |
| fileIds | List<Long> | 是  | 文件ID列表 |

---

### 3.7 获取文档列表

**接口路径**: `GET /api/collection/{name}/documents`

---

### 3.8 删除文档

**接口路径**: `DELETE /api/collection/{name}/documents/{filename}`

**请求参数**:

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| name | String | 是 | 向量库名称 |
| filename | String | 是 | 文档文件名 |
| fileId | Long | 否 | 文件ID（优先使用，避免同名文件删除错误） |

**说明**: 删除文档时优先根据 `fileId` 查找记录，若未提供 `fileId` 则回退到 `collection+filename` 查找，避免同名文件删除错误。

---

### 3.9 废止文档

**接口路径**: `POST /api/collection/{name}/documents/{filename}/deprecate`

---

### 3.10 恢复已废止文档

**接口路径**: `POST /api/collection/{name}/documents/{filename}/restore`

---

### 3.11 获取文档版本历史

**接口路径**: `GET /api/collection/{name}/documents/{filename}/versions`

---

### 3.12 获取文档切片列表

**接口路径**: `GET /api/collection/{name}/documents/{filename}/chunks`

**请求参数**:
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
| ------ | ---- | ---- | ------ | ---- |
| page | Integer | 否 | 1 | 页码 |
| pageSize | Integer | 否 | 20 | 每页数量 |

**响应示例**:
```json
{
  "code": 200,
  "message": "成功",
  "data": {
    "chunks": [
      {
        "id": "chunk_001",
        "document": "文档内容摘要...",
        "metadata": {
          "chunk_id": "chunk_001",
          "chunk_type": "text",
          "collection": "public_kb",
          "page": 1,
          "source": "文档名.pdf",
          "status": "active"
        },
        "status": "active",
        "version": "v1"
      }
    ],
    "collection": "public_kb",
    "document_id": "public_kb/文档名.pdf",
    "total": 25
  },
  "timestamp": "2026-05-17 10:00:00"
}
```

---

### 3.13 新增切片

**接口路径**: `POST /api/collection/{name}/chunks`

**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
| ------ | ---- | ---- | ---- |
| content | String | 是 | 切片内容 |
| section | String | 否 | 章节信息 |

---

### 3.14 修改切片

**接口路径**: `PUT /api/collection/{name}/chunks/{chunkId}`

**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
| ------ | ---- | ---- | ---- |
| content | String | 否 | 新内容 |
| section | String | 否 | 章节信息 |

---

### 3.15 删除切片

**接口路径**: `DELETE /api/collection/{name}/chunks/{chunkId}`

---

## 四、文件管理接口

**基础路径**：`/api/file`

### 4.1 查询文件详情

**接口路径**: `GET /api/file/{id}`

**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
| ------ | ---- | ---- | ---- |
| id | Long | 是 | 文件ID |

**响应示例**:
```json
{
  "code": 200,
  "message": "成功",
  "data": {
    "id": 1,
    "fileName": "test.pdf",
    "filePath": "/uploads/test.pdf",
    "fileSize": 1024000,
    "fileType": "application/pdf",
    "extension": "pdf",
    "description": "测试文件",
    "isPublic": true,
    "status": 1,
    "auditStatus": 1,
    "processStatus": "INDEXED",
    "examStatus": "COMPLETED",
    "createTime": "2026-05-17T10:00:00"
  },
  "timestamp": "2026-05-17 10:00:00"
}
```

---

### 4.2 文件上传

**接口路径**: `POST /api/file/upload`

**请求参数**:
| 参数名     | 类型     | 必填 | 说明       |
| ------- | ------ | -- | -------- |
| file    | MultipartFile | 是  | 文件内容     |
| deptId | Long | 否  | 部门ID（管理员上传制度文件时指定） |
| description | String | 否  | 文件描述     |
| isPublic | Boolean | 否  | 是否公开，默认true |

**响应示例**:
```json
{
  "code": 200,
  "message": "上传成功",
  "data": {
    "id": 1,
    "fileName": "test.pdf",
    "filePath": "/uploads/test.pdf",
    "fileSize": 1024000,
    "fileType": "application/pdf",
    "status": 1
  },
  "timestamp": "2026-05-17 10:00:00"
}
```

---

### 4.3 文件列表分页查询

**接口路径**: `GET /api/file/page`

**请求参数**:
| 参数名     | 类型      | 必填 | 默认值 | 说明        |
| ------- | ------- | -- | --- | --------- |
| pageNum | Integer | 否  | 1   | 页码        |
| pageSize | Integer | 否  | 10  | 每页数量      |
| fileName | String  | 否  | -   | 文件名模糊查询   |
| status  | Integer | 否  | -   | 文件状态      |
| auditStatus | Integer | 否  | -   | 审核状态      |

---

### 4.4 获取文件信息

**接口路径**: `GET /api/file/info/{id}`

**响应示例**:
```json
{
  "code": 200,
  "message": "成功",
  "data": {
    "id": 1,
    "fileName": "test.pdf",
    "filePath": "/uploads/test.pdf",
    "fileSize": 1024000,
    "fileType": "application/pdf",
    "extension": "pdf",
    "description": "测试文件",
    "isPublic": true,
    "status": 1,
    "auditStatus": 1,
    "processStatus": "INDEXED",
    "examStatus": "COMPLETED",
    "createTime": "2026-05-17T10:00:00"
  },
  "timestamp": "2026-05-17 10:00:00"
}
```

---

### 4.5 文件下载

**接口路径**: `GET /api/file/download/{id}`

**返回类型**: 文件流

---

### 4.6 文件预览

**接口路径**: `GET /api/file/preview/{id}`

**返回类型**: 文件流（支持浏览器预览的格式）

---

### 4.7 获取文件文本内容

**接口路径**: `GET /api/file/text/{id}`

**响应示例**:
```json
{
  "code": 200,
  "message": "成功",
  "data": {
    "content": "文档文本内容...",
    "pageCount": 10
  },
  "timestamp": "2026-05-17 10:00:00"
}
```

---

### 4.8 获取文件内容（二进制）

**接口路径**: `GET /api/file/content/{id}`

**功能说明**: 获取文件的二进制内容，供后端服务使用

**返回类型**: `byte[]`

---

### 4.9 文件RAG流式问答

**接口路径**: `POST /api/file/rag/stream`

**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
| ------ | ---- | ---- | ---- |
| message | String | 是 | 用户提问内容 |

**请求示例**:
```http
POST /api/file/rag/stream?message=请总结这份文档的内容
Authorization: Bearer <token>
```

**返回类型**: Server-Sent Events (SSE)

---

### 4.10 文件审核通过

**接口路径**: `POST /api/file/audit/approve/{id}`

---

### 4.11 文件审核拒绝

**接口路径**: `POST /api/file/audit/reject/{id}`

**请求体**:
```json
{
  "rejectReason": "内容不符合要求"
}
```

---

### 4.12 获取待审核文件列表

**接口路径**: `GET /api/file/audit/pending`

**请求参数**:
| 参数名     | 类型      | 必填 | 默认值 | 说明   |
| ------- | ------- | -- | --- | ---- |
| pageNum | Integer | 否  | 1   | 页码   |
| pageSize | Integer | 否  | 10  | 每页数量 |

---

### 4.13 更新文件信息

**接口路径**: `PUT /api/file/{id}`

**请求体**:
```json
{
  "isPublic": true,
  "description": "更新后的描述"
}
```

---

### 4.14 删除文件

**接口路径**: `DELETE /api/file/{id}`

---

## 五、知识库访问控制接口

**基础路径**：`/api/collection-access`

**说明**：此模块负责查询用户可访问的知识库列表，实现基于部门权限的访问控制。

### 5.1 分页查询知识库列表

**接口路径**: `GET /api/collection-access/page`

**请求参数**:
| 参数名        | 类型      | 必填 | 默认值 | 说明                        |
| ---------- | ------- | -- | --- | ------------------------- |
| pageNum    | Integer | 否  | 1   | 页码，从1开始                   |
| pageSize   | Integer | 否  | 10  | 每页记录数                     |
| name       | String  | 否  | -   | 知识库名称（模糊查询）               |
| department | String  | 否  | -   | 部门                        |
| ownerType  | String  | 否  | -   | 所有者类型：department/personal |
| visibility | String  | 否  | -   | 可见性：public/private        |

---

### 5.2 获取知识库详情

**接口路径**: `GET /api/collection-access/{id}`

---

### 5.3 获取用户可访问的知识库列表

**接口路径**: `GET /api/collection-access/accessible`

**功能说明**：根据当前登录用户的部门信息，返回其可访问的所有知识库列表，包括：
- 用户所属部门的公开知识库
- 公共部门的知识库（所有用户都可访问）
- 用户个人的知识库

**响应示例**:
```json
{
  "code": 200,
  "message": "成功",
  "data": {
    "collections": [
      {
        "name": "public_kb",
        "displayName": "公开知识库",
        "department": "公共部门",
        "description": "全员可访问",
        "createTime": "2026-01-01T10:00:00"
      },
      {
        "name": "dept",
        "displayName": "部门知识库",
        "department": "人事部门",
        "description": "人事部门专用",
        "createTime": "2026-05-16T13:44:10"
      }
    ],
    "total": 2
  },
  "timestamp": "2026-05-17 10:00:00"
}
```

---

## 六、AI流式问答接口

### 6.1 基本信息

| 属性               | 说明                                 |
| ---------------- | ---------------------------------- |
| **接口名称**         | AI流式问答                             |
| **描述**           | 向AI服务发起流式问答请求，实时返回处理过程，完成后自动保存到数据库 |
| **请求方法**         | POST                               |
| **URL路径**        | /api/ai/chat/stream                |
| **Content-Type** | application/json                   |
| **返回格式**         | Server-Sent Events (SSE)           |

### 6.2 请求参数

| 参数名         | 类型     | 必填 | 说明                  |
| ----------- | ------ | -- | ------------------- |
| message     | String | 是  | 用户提问内容              |
| session_id | String | 否  | 会话ID，用于多轮对话，不传则自动生成 |
| id          | String | 否  | 自定义请求ID，用于跟踪请求      |

**请求示例**:
```json
{
  "message": "请介绍一下这个知识库管理系统",
  "session_id": "sess_1777600000000_abc123",
  "id": "custom_req_001"
}
```

### 6.3 流式事件类型

| 事件类型          | 说明        |
| ------------- | --------- |
| start         | 对话开始事件    |
| connected     | RAG服务连接成功 |
| thinking      | AI思考中     |
| searching     | 知识库检索中    |
| sources       | 检索到的来源信息  |
| chunk         | 流式内容片段    |
| result/finish | 最终结果      |
| error         | 错误信息      |

---

## 七、AI数据接口

**基础路径**：`/api/ai/data`

### 7.1 获取会话消息

**接口路径**: `GET /api/ai/data/session/{sessionId}/messages`

**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
| ------ | ---- | ---- | ---- |
| sessionId | String | 是 | 会话ID |

---

### 7.2 获取反馈列表

**接口路径**: `GET /api/ai/data/feedbacks`

**请求参数**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| page | Integer | 否 | 1 | 页码 |
| pageSize | Integer | 否 | 20 | 每页大小 |

---

### 7.3 获取差评案例

**接口路径**: `GET /api/ai/data/feedbacks/bad-cases`

---

## 八、反馈管理接口

**基础路径**：`/api/feedback`

### 8.1 提交反馈

**接口路径**: `POST /api/feedback`

**请求体**:
```json
{
  "session_id": "会话ID（可选）",
  "query": "用户问题",
  "answer": "AI回答",
  "rating": 1,
  "reason": "反馈原因（可选）",
  "sources": ["来源文档列表（可选）"]
}
```

---

### 8.2 获取反馈列表

**接口路径**: `GET /api/feedback/list`

**请求参数**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| page | Integer | 否 | 1 | 页码 |
| pageSize | Integer | 否 | 20 | 每页大小 |

---

### 8.3 获取反馈统计

**接口路径**: `GET /api/feedback/stats`

---

### 8.4 获取差评案例

**接口路径**: `GET /api/feedback/bad-cases`

---

## 九、FAQ管理接口

**基础路径**：`/api/faq`

### 9.1 创建FAQ

**接口路径**: `POST /api/faq`

**请求体**:
```json
{
  "question": "常见问题内容",
  "answer": "问题答案",
  "source_documents": ["来源文档列表（可选）"]
}
```

---

### 9.2 获取FAQ列表

**接口路径**: `GET /api/faq`

**请求参数**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| page | Integer | 否 | 1 | 页码 |
| pageSize | Integer | 否 | 20 | 每页大小 |

---

### 9.3 获取FAQ详情

**接口路径**: `GET /api/faq/{id}`

---

### 9.4 更新FAQ

**接口路径**: `PUT /api/faq/{id}`

**请求体**:
```json
{
  "question": "更新后的问题（可选）",
  "answer": "更新后的答案（可选）",
  "status": "approved/pending/rejected（可选）"
}
```

---

### 9.5 删除FAQ

**接口路径**: `DELETE /api/faq/{id}`

---

### 9.6 批量删除FAQ

**接口路径**: `DELETE /api/faq/batch?ids=1,2,3`

---

### 9.7 条件查询FAQ

**接口路径**: `GET /api/faq/list`

**请求参数**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| status | String | 否 | - | 状态筛选 |
| limit | Integer | 否 | 100 | 返回数量限制 |

---

### 9.8 获取FAQ建议列表

**接口路径**: `GET /api/faq/suggestions`

**请求参数**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| page | Integer | 否 | 1 | 页码 |
| pageSize | Integer | 否 | 20 | 每页大小 |

---

### 9.9 批准FAQ建议

**接口路径**: `POST /api/faq/suggestions/{id}/approve`

**请求体**:
```json
{
  "answer": "修改后的标准答案（可选）"
}
```

---

### 9.10 拒绝FAQ建议

**接口路径**: `POST /api/faq/suggestions/{id}/reject`

---

## 十、图片管理接口

**基础路径**：`/api/image`

### 10.0 图片完整处理流程

#### 10.0.1 整体流程说明

本系统实现了完整的AI图片处理流程，包括：

```
用户提问 → RAG服务返回 → 图片提取 → 下载保存 → 数据库存储 → API访问 → 前端展示
```

#### 10.0.2 详细处理步骤

**步骤1：用户提问**
```
POST /api/ai/chat/stream
{
  "message": "2003—2022 年，三峡电站累计发电量是多少？最好带图片说明"
}
```

**步骤2：RAG服务返回完整数据**
```json
{
  "type": "finish",
  "answer": "根据【参考资料】...",
  "images": [
    {
      "id": "ab77281e7913.jpg",
      "score": 7.8,
      "type": "chart",
      "source": "三峡公报_1-15页.pdf",
      "page": 12,
      "description": "这是一张柱状图...",
      "full_description": "这是一张柱状图，展示了...",
      "url": "/images/ab77281e7913.jpg"
    }
  ]
}
```

**步骤3：系统自动处理**
- ✅ 提取图片元数据（id, score, type, source, page, description, full_description）
- ✅ 从AI服务下载图片到本地目录
- ✅ 保存图片元数据到 `context_image` 表
- ✅ 保存图片到本地文件系统（`/tmp/img/` 或 `./img/`）

**步骤4：前端获取图片数据**
```bash
GET /api/image/ab77281e7913.jpg/data
```
返回：图片二进制流

#### 10.0.3 前端展示示例

**JavaScript (原生)**
```javascript
// 从 finish 事件获取图片数组
const images = finishEvent.images;

images.forEach(image => {
  // 创建图片元素
  const img = document.createElement('img');
  img.src = image.url;  // url = "/api/image/ab77281e7913.jpg/data"
  img.alt = image.description;
  img.style.maxWidth = '100%';
  
  // 创建描述容器
  const descDiv = document.createElement('div');
  descDiv.innerHTML = `
    <p><strong>来源：</strong>${image.source}</p>
    <p><strong>页码：</strong>第 ${image.page} 页</p>
    <p><strong>类型：</strong>${image.type}</p>
    <p><strong>描述：</strong>${image.description}</p>
  `;
  
  // 添加到页面
  document.getElementById('image-gallery').appendChild(img);
  document.getElementById('image-gallery').appendChild(descDiv);
});
```

**React 示例**
```jsx
{images && images.length > 0 && (
  <div className="image-gallery">
    {images.map((image, index) => (
      <div key={index} className="image-item">
        <img 
          src={image.url} 
          alt={image.description}
          style={{ maxWidth: '100%' }}
        />
        <div className="image-info">
          <p><strong>来源：</strong>{image.source}</p>
          <p><strong>页码：</strong>第 {image.page} 页</p>
          <p><strong>类型：</strong>{image.type}</p>
          <p><strong>描述：</strong>{image.description}</p>
          {image.full_description && (
            <details>
              <summary>查看完整描述</summary>
              <p>{image.full_description}</p>
            </details>
          )}
        </div>
      </div>
    ))}
  </div>
)}
```

**Vue 示例**
```vue
<template>
  <div v-if="images && images.length > 0" class="image-gallery">
    <div v-for="(image, index) in images" :key="index" class="image-item">
      <img :src="image.url" :alt="image.description" style="max-width: 100%" />
      <div class="image-info">
        <p><strong>来源：</strong>{{ image.source }}</p>
        <p><strong>页码：</strong>第 {{ image.page }} 页</p>
        <p><strong>类型：</strong>{{ image.type }}</p>
        <p><strong>描述：</strong>{{ image.description }}</p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: ['images']
}
</script>
```

### 10.1 创建图片记录

**接口路径**: `POST /api/image`

**请求体**:
```json
{
  "image_id": "图片唯一标识",
  "filename": "原始文件名（可选）",
  "path": "存储路径",
  "size_bytes": 1024000,
  "format": "图片格式（可选）",
  "source": "来源文档（可选）",
  "page": 1,
  "collection": "所属向量库（可选）"
}
```

---

### 10.2 获取图片列表

**接口路径**: `GET /api/image/list`

**请求参数**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| limit | Integer | 否 | 50 | 返回数量 |
| offset | Integer | 否 | 0 | 偏移量 |

---

### 10.3 获取图片详情

**接口路径**: `GET /api/image/{id}`

---

### 10.4 获取图片数据

**接口路径**: `GET /api/image/{id}/data`

**返回类型**: 图片二进制流

---

### 10.5 更新图片记录

**接口路径**: `PUT /api/image/{id}`

**请求体**:
```json
{
  "filename": "更新后的文件名（可选）",
  "path": "更新后的路径（可选）",
  "format": "更新后的格式（可选）"
}
```

---

### 10.6 删除图片

**接口路径**: `DELETE /api/image/{id}`

---

### 10.7 批量删除图片

**接口路径**: `DELETE /api/image/batch?ids=1,2,3`

---

### 10.8 获取图片统计

**接口路径**: `GET /api/image/stats`

---

## 十一、报告管理接口

**基础路径**：`/api/report`

### 11.1 获取周报

**接口路径**: `GET /api/report/weekly`

---

### 11.2 获取月报

**接口路径**: `GET /api/report/monthly`

---

## 十二、知识检索接口

### 12.1 混合检索

**接口路径**: `POST /api/search`

**请求体**:
```json
{
  "query": "检索关键词",
  "topK": 5,
  "collections": ["public_kb", "dept"]
}
```

---

## 十三、知识库路由接口

### 13.1 测试知识库路由

**接口路径**: `POST /api/kb-route`

**请求体**:
```json
{
  "query": "财务部的报销流程是什么"
}
```

---

## 十四、模拟考接口 🔵 模拟考

**基础路径**：`/api/exam`

**功能说明**：模拟考接口，通过 AI 生成模拟试卷、题目，支持批改答案。前端可传 `type` 参数指定本次试卷类型（日常练习/模拟考/正式考均可）。

**type 参数可选值**：

| 值 | 说明 |
|----|------|
| `practice` | 日常练习 |
| `mock_exam` | 模拟考 |
| `formal_exam` | 正式考试 |

### 14.1 生成试卷

**接口路径**: `POST /api/exam/paper/generate`

**功能说明**: 根据权限范围或指定文件从题库中动态生成试卷

**请求体**:
```json
{
  "single_choice_count": 5,
  "multiple_choice_count": 3,
  "true_false_count": 2,
  "fill_blank_count": 2,
  "subjective_count": 1,
  "difficulty": 3,
  "include_personal": false,
  "file_ids": [1, 2, 3]
}
```

**请求参数说明**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| single_choice_count | Integer | 否 | - | 单选题数量 |
| multiple_choice_count | Integer | 否 | - | 多选题数量 |
| true_false_count | Integer | 否 | - | 判断题数量 |
| fill_blank_count | Integer | 否 | - | 填空题数量 |
| subjective_count | Integer | 否 | - | 简答题数量 |
| difficulty | Integer | 否 | - | 难度等级（1-5） |
| include_personal | Boolean | 否 | false | 是否包含个人专属题目 |
| file_ids | List<Long> | 否 | - | 指定文件ID列表，仅从这些文件生成题目 |

**响应示例**:
```json
{
  "code": 200,
  "message": "试卷生成成功",
  "data": {
    "paper_id": "paper_xxx",
    "paper_title": "考试试卷 - 2026-05-17T15:41:56",
    "total_score": 100.00,
    "question_count": 13,
    "generated_at": "2026-05-17T15:41:56",
    "permission_scope": "本部门",
    "questions": [
      {
        "question_id": "q_xxx",
        "question_type": "single_choice",
        "question_type_name": "单选题",
        "difficulty": 3,
        "score": 5.00,
        "content": {...}
      }
    ]
  },
  "timestamp": "2026-05-17 15:41:56"
}
```

---

### 14.2 开始考试（获取题目）

**接口路径**: `POST /api/exam/paper/{paperId}/start`

**功能说明**: 通过试卷ID开始模拟考试，系统自动查找或创建考试记录，返回试卷题目内容

**路径参数**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| paperId | String | 是 | 试卷ID |

**响应示例**: 同14.1 生成试卷的响应格式

---

### 14.3 获取考试结果

**接口路径**: `GET /api/exam/record/{recordId}/result`

**功能说明**: 获取模拟考试的完整结果，包括题目、答案、分数等信息

**路径参数**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| recordId | String | 是 | 考试记录ID |

**响应示例**:
```json
{
  "code": 200,
  "message": "操作成功",
  "data": {
    "record_id": "59759c40-ee4e-4ff5-ab03-4819a0499beb",
    "paper_id": "0ef70443-67d3-48cd-9309-f5088c092fe1",
    "answer_type": "practice",
    "paper_title": "考试试卷 - 2026-05-17T15:41:56",
    "user_id": 1,
    "status": "submitted",
    "total_score": 85.0,
    "answers": [
      {
        "question_id": "q_001",
        "score": 5.0,
        "is_correct": true,
        "feedback": "回答正确"
      }
    ]
  },
  "timestamp": "2026-05-17 16:05:00"
}
```

---

### 14.4 生成题目

**接口路径**: `POST /api/exam/generate`

**功能说明**: 根据指定文件生成考试题目，支持两种生成模式：
1. **智能生成模式**（推荐）：不提供 `question_types` 参数，系统会调用 AI 智能出题接口 `/exam/generate-smart`，AI 会根据文档内容自动判断题型和数量
2. **指定题型模式**：提供 `question_types` 参数，系统会调用传统出题接口 `/exam/generate`，按照指定的题型和数量生成题目

**重要说明**：此接口为异步接口，请求后立即返回任务提交状态，实际生成在后台执行。需通过 `GET /api/file/{fileId}` 接口轮询查询生成进度和结果。

支持两种方式指定文件：
1. **通过 file_id 指定**（推荐）：系统自动从 `collection_file` 表查询向量库信息
2. **通过 file_path 指定**：需要同时指定 collection 参数

**请求体（智能生成模式）**:
```json
{
  "file_id": 1,
  "difficulty": 3,
  "request_id": "gen_req_smart_001"
}
```

**请求体（指定题型模式）**:
```json
{
  "file_id": 1,
  "question_types": {
    "single_choice": 3,
    "multiple_choice": 2,
    "true_false": 2,
    "fill_blank": 2,
    "subjective": 1
  },
  "question_scores": {
    "single_choice": 5.00,
    "multiple_choice": 8.00
  },
  "difficulty": 3,
  "request_id": "gen_req_001"
}
```

**请求参数说明**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| file_id | Long | 二选一 | 文件ID，系统自动查询向量库 |
| file_path | String | 二选一 | 文件路径 |
| collection | String | 当使用 file_path 时必填 | 向量库名称 |
| question_types | Object | 否 | 题型及数量配置（不提供则使用智能生成模式） |
| question_scores | Object | 否 | 自定义题型分数配置（仅在指定题型模式下有效） |
| difficulty | Integer | 否 | 难度等级（1-5），默认3 |
| request_id | String | 否 | 请求ID，用于幂等性 |

**响应示例（通过 file_id）**:
```json
{
  "code": 200,
  "message": "收到请求",
  "data": {
    "requestId": "gen_req_001",
    "fileId": 1,
    "fileMatchStatus": "success",
    "matchedCollection": "public_kb",
    "matchedFilePath": "薪酬制度.docx",
    "documentName": "薪酬制度.docx",
    "collectionFilled": true,
    "collectionFillSource": "collection_file 表查询",
    "asyncTaskStarted": true,
    "nextStep": "请通过文件状态接口查询生成进度",
    "status": "success"
  },
  "timestamp": "2026-05-28 10:00:00"
}
```

**响应示例（通过 file_path）**:
```json
{
  "code": 200,
  "message": "收到请求",
  "data": {
    "requestId": "gen_req_001",
    "fileMatchStatus": "skipped",
    "reason": "使用 file_path 直接指定文件",
    "collectionFilled": false,
    "asyncTaskStarted": true,
    "nextStep": "请通过文件状态接口查询生成进度",
    "status": "success"
  },
  "timestamp": "2026-05-28 10:00:00"
}
```

**响应字段说明**:
| 字段 | 类型 | 说明 |
|------|------|------|
| requestId | String | 请求ID，用于追踪 |
| fileId | Long | 文件ID |
| fileMatchStatus | String | 文件匹配状态：success/skipped/failed |
| matchedCollection | String | 匹配到的向量库名称 |
| matchedFilePath | String | 匹配到的文件路径 |
| documentName | String | 文档名称 |
| collectionFilled | Boolean | 向量库是否已填充 |
| collectionFillSource | String | 向量库填充来源 |
| asyncTaskStarted | Boolean | 异步任务是否已启动 |
| nextStep | String | 下一步操作提示 |
| status | String | 状态：success/error |

**生成状态查询**：
请求成功后，需通过 `GET /api/file/{fileId}` 接口轮询查询生成进度：

**AI生成题目状态**：
| 状态值 | 说明 | 前端处理建议 |
|--------|------|--------------|
| `UNGENERATED` | 未生成 | 显示"未生成"状态 |
| `GENERATING` | 正在生成 | 显示加载动画，轮询状态 |
| `GENERATED` | 已生成 | 显示成功状态，可查看题目 |
| `FAILED` | 生成失败 | 显示错误信息，支持重试 |

**文件状态查询响应示例**：
```json
{
  "code": 200,
  "message": "成功",
  "data": {
    "id": 1,
    "fileName": "薪酬制度.docx",
    "filePath": "public_kb/薪酬制度.docx",
    "processStatus": "INDEXED",
    "examStatus": "GENERATED",
    "processMessage": "生成成功，共5道题\n\n【AI分析结果】\n{\"summary\":\"文档摘要...\",\"questionDistribution\":{\"single_choice\":3,\"multiple_choice\":2}}",
    "createTime": "2026-05-28T10:00:00",
    "updateTime": "2026-05-28T10:00:03"
  }
}
```

**processMessage 字段说明**：
- 生成成功时：包含题目数量，智能模式还会包含 AI 分析结果（JSON格式）
- 生成失败时：包含错误原因
- AI 分析结果通过 `【AI分析结果】` 标记标识

**默认分值配置**:

| 题型 | question_type | 默认分值 |
|------|---------------|---------|
| 单选题 | single_choice | 2分 |
| 多选题 | multiple_choice | 4分 |
| 判断题 | true_false | 1分 |
| 填空题 | fill_blank | 2分 |
| 简答题 | subjective | 6分 |

**分数优先级**:
1. 题目级配置（AI返回的 score 字段）
2. 题型级配置（question_scores 参数）
3. 默认值（上表）

**轮询策略建议**：
- 初始轮询间隔：2-3秒
- 超时时间：建议设置为 5-10 分钟
- 停止条件：`examStatus` 变为 `GENERATED` 或 `FAILED`

---

### 14.5 提交考试并批改（正式考试专用）

**接口路径**: `POST /api/exam/record/{recordId}/grade`

**功能说明**: 通过考试记录ID提交正式考试答案并批改，自动将类型设置为 `formal_exam`。

**路径参数**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| recordId | String | 是 | 考试记录ID |

**请求体**:
```json
{
  "answers": [
    {"questionId": "q_001", "questionType": "single_choice", "answer": "B"},
    {"questionId": "q_002", "questionType": "multiple_choice", "answer": ["A", "C", "D"]},
    {"questionId": "q_003", "questionType": "true_false", "answer": true},
    {"questionId": "q_004", "questionType": "fill_blank", "answer": ["答案1", "答案2", "答案3"]},
    {"questionId": "q_005", "questionType": "subjective", "answer": "主观题答案内容"}
  ]
}
```

**响应示例**:
```json
{
  "code": 200,
  "message": "提交成功",
  "data": {
    "recordId": "record_xxx",
    "paperId": "paper_xxx",
    "paperTitle": "月度考核试卷",
    "status": "submitted",
    "totalScore": 85.0,
    "totalMaxScore": 100.0,
    "scoreRate": 85.0,
    "submitTime": "2026-05-17T14:30:00",
    "answers": [
      {
        "questionId": "q_001",
        "score": 5.0,
        "maxScore": 5.0,
        "isCorrect": true,
        "feedback": "回答正确"
      }
    ]
  },
  "timestamp": "2026-05-17T14:30:00"
}
```

---

### 14.6 批改答案（日常练习/模拟考/正式考试通用）

**接口路径**: `POST /api/exam/grade`

**功能说明**: 对学生提交的答案进行批改，支持两种模式：
1. **日常练习/模拟考模式**（无 record_id）：直接批改答案，可重复提交更新记录
2. **正式考试模式**（有 record_id）：通过考试记录ID提交正式考试答案并批改

`type` 字段由前端传入，后端原样使用（不限值）。

**请求体**:
```json
{
  "request_id": "grade_req_001",
  "type": "practice",
  "record_id": "59759c40-ee4e-4ff5-ab03-4819a0499beb",
  "answers": [
    {
      "question_id": "q_001",
      "question_type": "single_choice",
      "question_content": {
        "stem": "题目内容",
        "data": {"options": [...]},
        "answer": "B"
      },
      "student_answer": "A",
      "max_score": 5.0
    }
  ]
}
```

**响应示例**:
```json
{
  "code": 200,
  "message": "批阅成功",
  "data": {
    "success": true,
    "total_score": 5.0,
    "total_max_score": 5.0,
    "score_rate": 100.0,
    "results": [
      {
        "question_id": "q_001",
        "question_type": "single_choice",
        "score": 5.0,
        "max_score": 5.0,
        "is_correct": true,
        "correct": true,
        "student_answer": "B",
        "correct_answer": "B",
        "feedback": "回答正确"
      }
    ]
  },
  "timestamp": "2026-05-17 10:00:00"
}
```

**响应字段说明**:

| 字段 | 类型 | 说明 |
|------|------|------|
| code | Integer | 状态码，200表示成功 |
| message | String | 响应消息 |
| data.success | Boolean | 批改是否成功 |
| data.total_score | Double | 总得分 |
| data.total_max_score | Double | 总满分 |
| data.score_rate | Double | 得分率（0-100） |
| data.results | Array | 每题批改结果 |
| data.results[].question_id | String | 题目ID |
| data.results[].question_type | String | 题型 |
| data.results[].score | Double | 本题得分 |
| data.results[].max_score | Double | 本题满分 |
| data.results[].is_correct | Boolean | 是否正确（推荐使用） |
| data.results[].correct | Boolean | 是否正确（兼容字段） |
| data.results[].student_answer | String | 学生答案 |
| data.results[].correct_answer | String | 正确答案 |
| data.results[].feedback | String | 反馈信息 |

**字段兼容性说明**:

| 字段名 | 说明 | 兼容性 |
|--------|------|--------|
| `is_correct` | 布尔值，表示是否正确 | ✅ 主字段，推荐使用 |
| `correct` | 布尔值，表示是否正确 | ✅ 兼容字段，与is_correct值相同 |
| `feedback` | 反馈信息 | ✅ 后端自动生成，确保不为空 |
| `student_answer` | 学生答案 | ✅ 返回前端提交的答案 |
| `correct_answer` | 正确答案 | ✅ 从题目信息中获取 |

**各题型反馈生成规则**:

- **单选题、多选题、判断题**：优先使用AI返回的`feedback`字段，内容简单直接
- **填空题**：优先使用AI返回的`feedback`，否则从`details.blank_scores`和`details.correct_answers`自动生成
- **主观题**：优先使用`details.overall_feedback`，否则使用`feedback`，最后从`details.scoring_breakdown`生成

---

### 14.7 查询用户答题记录

**接口路径**: `POST /api/exam/answers/query`

**功能说明**: 根据试卷ID或会话ID查询用户答题记录，支持按试卷/练习维度分组展示

**请求体**:
```json
{
  "paper_id": "paper_xxx"
}
```

或

```json
{
  "session_id": "sess_xxx"
}
```

**请求参数说明**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| paper_id | String | 二选一 | 试卷ID |
| session_id | String | 二选一 | 会话ID（日常练习） |

---

### 14.8 获取考试记录列表（统一接口）

**接口路径**: `GET /api/exam/records?type={type}`

**功能说明**: 根据类型获取用户的考试/练习记录，统一查询接口

**请求参数**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| type | String | 否 | practice | 记录类型：practice(日常练习), mock_exam(模拟考), formal_exam(正式考) |

**响应示例**（日常练习）:
```json
{
  "code": 200,
  "message": "成功",
  "data": {
    "success": true,
    "totalCount": 10,
    "groups": [
      {
        "groupType": "practice",
        "groupId": "sess_xxx",
        "groupName": "2026-05-17",
        "createdAt": "2026-05-17T10:30:00"
      }
    ]
  }
}
```

**响应示例**（模拟考/正式考）:
```json
{
  "code": 200,
  "message": "成功",
  "data": [
    {
      "recordId": "rec_xxx",
      "paperId": "paper_xxx",
      "paperTitle": "月度考核试卷",
      "answerType": "formal_exam",
      "status": "completed",
      "totalScore": 85.0,
      "submitTime": "2026-05-17T11:30:00"
    }
  ]
}
```

---

## 十五、正式考试接口 🟢 正式考

**基础路径**：`/api/formal-exam`

**功能说明**：正式考试接口，仅供被分配了正式试卷的用户使用。提交答案时 `type` 自动设置为 `formal_exam`，同一用户对同一题目只能答题一次（唯一索引防重复）。

### 15.1 开始考试（获取题目）

**接口路径**: `POST /formal-exam/paper/{paperId}/start`

**功能说明**: 直接通过试卷ID开始考试，系统自动查找或创建考试记录，返回试卷题目内容

**响应示例**:
```json
{
  "code": 200,
  "message": "开始考试成功",
  "data": {
    "recordId": "record_xxx",
    "paperId": "paper_xxx",
    "paperTitle": "月度考核试卷",
    "status": "in_progress",
    "startTime": "2026-05-17T14:00:00",
    "questions": [
      {
        "questionId": "q_001",
        "questionType": "single_choice",
        "questionTypeName": "单选题",
        "score": 5.0,
        "content": {
          "stem": "题目内容...",
          "data": {"options": [...]}
        }
      }
    ]
  },
  "timestamp": "2026-05-17 14:00:00"
}
```

---

**重要说明**：正式考试提交接口已统一到 `/api/exam/grade（推荐使用）或 `/api/exam/record/{recordId}/grade`。

### 15.2 获取考试结果

**接口路径**: `GET /formal-exam/record/{recordId}/result`

**功能说明**: 获取考试结果详情，包含每题得分和反馈

---

## 十六、正式考管理接口 🟢 正式考管理

**基础路径**：`/admin/exam`

**功能说明**：正式考管理接口，供管理员预览、保存、发布正式考试试卷。管理员生成试卷后发布给指定部门/人员，员工在正式考试接口中答题。`type` 自动设置为 `formal_exam`。

### 16.1 预览试卷

**接口路径**: `POST /admin/exam/paper/preview`

**请求体**:
```json
{
  "single_choice_count": 5,
  "multiple_choice_count": 3,
  "true_false_count": 2,
  "fill_blank_count": 2,
  "subjective_count": 1,
  "difficulty": 3
}
```

---

### 16.2 保存试卷

**接口路径**: `POST /admin/exam/paper/save`

**请求体**:
```json
{
  "title": "月度考核试卷",
  "questionIds": ["q_001", "q_002", "q_003"]
}
```

---

### 16.3 发布试卷

**接口路径**: `POST /admin/exam/paper/{paperId}/publish`

**请求体**:
```json
{
  "deptId": 1,
  "userIds": [10, 20, 30],
  "excludeUserIds": [5],
  "publishTime": "2026-05-17T00:00:00",
  "deadline": "2026-05-20T23:59:59"
}
```

**请求参数说明**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| deptId | Long | 否 | 部门ID，发布给该部门的所有用户 |
| userIds | List\<Long\> | 否 | 指定用户ID列表 |
| excludeUserIds | List\<Long\> | 否 | 排除用户ID列表 |
| publishTime | DateTime | 否 | 发布时间，默认立即发布 |
| deadline | DateTime | 否 | 截止时间 |

**说明**：
- 最终考试人员 = (部门用户 + 指定用户) - 排除用户
- 三种组合方式：
  1. 只设置 `deptId`：发布给整个部门
  2. 只设置 `userIds`：只发布给指定用户
  3. 同时设置：覆盖更广泛范围，可排除特定人员

**响应示例**:
```json
{
  "code": 200,
  "message": "发布成功",
  "data": null,
  "timestamp": "2026-05-17 00:00:00"
}
```

---

### 16.4 撤销试卷

**接口路径**: `POST /admin/exam/paper/{paperId}/revoke`

---

### 16.5 删除试卷

**接口路径**: `DELETE /admin/exam/paper/{paperId}`

---

### 16.6 获取试卷详情（管理）

**接口路径**: `GET /admin/exam/paper/{paperId}`

---

### 16.7 获取试卷列表（管理）

**接口路径**: `GET /admin/exam/paper/list`

---

### 16.8 获取考试记录列表

**接口路径**: `GET /admin/exam/records/{paperId}`

---

### 16.9 获取考试记录详情

**接口路径**: `GET /admin/exam/record/{recordId}`

---

## 十七、题目管理接口

**基础路径**：`/api/question`

### 17.1 创建题目

**接口路径**: `POST /api/question`

**请求体**:
```json
{
  "question_type": "single_choice",
  "difficulty": 3,
  "content": {"stem": "题目内容", "data": {...}, "answer": "答案"},
  "score": 5.0,
  "document_name": "来源文档"
}
```

---

### 17.2 分页查询题目

**接口路径**: `GET /api/question/page`

**请求参数**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| pageNum | Integer | 否 | 1 | 页码 |
| pageSize | Integer | 否 | 10 | 每页大小 |
| questionType | String | 否 | - | 题型筛选 |
| difficulty | Integer | 否 | - | 难度筛选 |
| status | String | 否 | - | 状态筛选 |

---

### 17.3 获取题目详情

**接口路径**: `GET /api/question/{id}`

---

### 17.4 更新题目

**接口路径**: `PUT /api/question/{id}`

**请求体**:
```json
{
  "question_type": "更新后的题型（可选）",
  "difficulty": 4,
  "content": {"stem": "更新后的题目内容"},
  "status": "approved"
}
```

---

### 17.5 删除题目

**接口路径**: `DELETE /api/question/{id}`

---

### 17.6 批量删除题目

**接口路径**: `DELETE /api/question/batch?ids=1,2,3`

---

### 17.7 条件查询题目（按权限过滤）

**接口路径**: `GET /api/question/list`

**功能说明**: 根据用户权限过滤，返回用户可见的题目（本人库、本部门库、公共库的题目）

**请求参数**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| questionType | String | 否 | - | 题型筛选 |
| difficulty | Integer | 否 | - | 难度筛选 |
| status | String | 否 | - | 状态筛选 |
| documentName | String | 否 | - | 文档名称筛选 |
| limit | Integer | 否 | 100 | 返回数量限制 |

---

### 17.8 获取待审核题目

**接口路径**: `GET /api/question/pending`

---

### 17.9 审核题目

**接口路径**: `PUT /api/question/review/{questionId}`

**请求参数**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| status | String | 是 | 审核状态：approved/rejected |
| reviewerComment | String | 否 | 审核评论 |

---

### 17.10 获取题目统计

**接口路径**: `POST /api/question/stats`

**请求体**:
```json
{
  "group_by": "question_type"
}
```

---

## 十八、错题管理接口

**基础路径**：`/api/wrong-questions`

### 18.1 获取错题列表

**接口路径**: `POST /api/wrong-questions/list`

**请求体**:
```json
{
  "page": 1,
  "pageSize": 10,
  "collection": true
}
```

---

### 18.2 收藏/取消收藏错题

**接口路径**: `POST /api/wrong-questions/collection/toggle`

**请求体**:
```json
{
  "question_id": "q_001"
}
```

---

### 18.3 重新做题

**接口路径**: `POST /api/wrong-questions/redo`

**请求体**:
```json
{
  "question_ids": ["q_001", "q_002"]
}
```

---

### 18.4 导出错题

**接口路径**: `POST /api/wrong-questions/export`

**请求体**:
```json
{
  "question_ids": ["q_001", "q_002"]
}
```

---

## 十九、数据同步接口

**基础路径**：`/api/data-sync`

### 19.1 验证用户数据同步

**接口路径**: `GET /api/data-sync/validate/user/{userId}`

---

### 19.2 验证当前用户数据同步

**接口路径**: `GET /api/data-sync/validate/me`

---

### 19.3 验证所有用户数据同步

**接口路径**: `GET /api/data-sync/validate/all`

---

### 19.4 验证最近用户数据同步

**接口路径**: `GET /api/data-sync/validate/recent`

---

## 二十、接口权限说明

### 20.1 权限层级

| 用户类型  | 类型值 | 权限说明                |
| ----- | --- | ------------------- |
| 超级管理员 | 1   | 完全访问权限，可管理所有向量库和文档  |
| 部门管理员 | 2   | 可管理本部门的所有向量库和文档     |
| 普通用户  | 3   | 可管理个人上传的文档和本部门的公开文档 |

### 20.2 权限矩阵

| 接口 | 超级管理员 | 部门管理员 | 普通用户 |
|------|-----------|-----------|----------|
| 获取向量库列表 | ✅ | ✅ | ✅ |
| 创建向量库 | ✅ | ✅ | ❌ |
| 修改向量库 | ✅ | ✅ | ❌ |
| 删除向量库 | ✅ | ✅ | ❌ |
| 文件向量化 | ✅ | ✅ | ✅ |
| 获取文档列表 | ✅ | ✅ | ✅ |
| 删除文档 | ✅ | ✅ | ❌ |
| 生成题目 | ✅ | ✅ | ✅ |
| 批改答案 | ✅ | ✅ | ✅ |
| 提交反馈 | ✅ | ✅ | ✅ |
| 获取反馈列表 | ✅ | ✅ | ✅ |
| 题目CRUD | ✅ | ✅ | ❌ |
| FAQ CRUD | ✅ | ✅ | ❌ |
| 图片CRUD | ✅ | ✅ | ❌ |
| 试卷管理 | ✅ | ✅ | ❌ |
| 用户考试 | ✅ | ✅ | ✅ |

---

## 二十一、错误码详解

### 21.1 认证相关错误

| 错误码 | 错误信息     | 解决方案           |
| --- | -------- | -------------- |
| 401 | 用户未登录    | 请先登录获取Token    |
| 401 | Token无效  | 请重新登录获取有效Token |
| 401 | Token已过期 | 请重新登录          |
| 403 | 权限不足     | 联系管理员提升权限      |

### 21.2 业务逻辑错误

| 错误码 | 错误信息                 | 解决方案           |
| --- | -------------------- | -------------- |
| 400 | 参数错误                 | 检查请求参数格式和必填项   |
| 404 | 向量库不存在               | 检查向量库名称是否正确    |
| 404 | 文档不存在                | 检查文档路径是否正确     |
| 500 | 创建向量库失败              | 检查数据库连接或重试     |

---

## 二十二、使用限制

### 22.1 通用限制

| 限制项      | 限制值  | 说明          |
| -------- | ---- | ----------- |
| 文件上传大小   | 50MB | 单个文件最大50MB  |
| 批量上传文件数  | 20   | 一次最多上传20个文件 |
| 分页最大页码   | 1000 | 超过后性能下降     |
| 每页最大记录数  | 100  | 超过后建议优化查询   |
| Token有效期 | 24小时 | 登录Token有效期  |

### 22.2 频率限制

| 接口类型    | 限制   | 时间窗口 |
| ------- | ---- | ---- |
| 文件上传    | 10次  | 60秒  |
| 其他增删改接口 | 30次  | 60秒  |
| 查询接口    | 100次 | 60秒  |

---

## 二十三、变更记录

| 版本 | 日期 | 修改内容 |
|------|------|----------|
| V2.15.0 | 2026-05-29 | 1. 新增用户管理接口(用户CRUD);2. 新增部门管理接口;3. 新增AI会话管理接口(获取会话列表、会话详情、删除会话、批量删除会话);4. 新增向量库切片管理接口(新增切片、修改切片、删除切片、获取向量库切片列表);5. 优化文档结构,添加通用请求头说明;6. 完善向量库管理接口,新增获取文档切片列表等接口。 |
| V2.14.0 | 2026-05-28 | 1. 生成题目接口新增智能生成模式，不提供 `question_types` 参数时自动调用 AI 智能出题接口 `/exam/generate-smart`，AI 根据文档内容自动判断题型和数量；2. `question_types` 参数改为可选，仅在指定题型模式下需要提供；3. `process_message` 字段会追加 AI 分析结果（aiAnalysis），包含文档摘要和题型分布等信息；4. 更新文件详情查询接口响应示例，添加 `processMessage` 字段说明；5. 更新 `process_message` 字段类型从 varchar 改为 text，支持存储更长内容。 |
| V2.13.0 | 2026-05-19 | 1. 生成题目接口新增 `file_id` 参数支持，系统自动从 `collection_file` 表查询向量库信息；2. 新增 `question_scores` 参数支持自定义题型分数；3. 更新默认分值配置（单选2分、多选4分、判断1分、填空2分、简答6分）；4. 添加完整的反馈信息机制，包含文件匹配状态、向量库填充进度等。 |
| V2.12.0 | 2026-05-19 | 1. 新增图片完整处理流程说明（10.0节）；2. 新增前端图片展示示例（JavaScript/React/Vue）；3. 完善图片元数据字段说明（新增 score、type、description、full_description）；4. 新增图片自动下载和本地保存功能说明。 |
| V2.11.0 | 2026-05-17 | 1. 控制器重命名：KnowledgeBasePathController → CollectionAccessController，路径从 /api/kb-path 改为 /api/collection-access；2. 部门字段重命名：HR_DEPT → 人事部门，PUBLIC_DEPT → 公共部门；3. 图片接口路径更新：/api/images → /api/image。 |
| V2.10.0 | 2026-05-14 | 新增文件来源展示优化功能：1. AI流式问答 finish 事件新增 `sources`（文件来源列表）和 `images`（图片列表）字段；2. 新增 `GET /api/ai/message/{messageId}/sources` 接口获取文件来源列表（去重）；3. `GET /api/ai/message/{messageId}/references` 新增 `docName` 参数支持按文档过滤；4. 消息实体新增 `sources` 字段存储文件来源摘要；5. 图片接口新增兼容路径 `/api/images/list`；6. 修复异步题目生成问题：添加 `@EnableAsync` 配置和自定义线程池。 |
| V2.9.3 | 2026-05-11 | 统一考试接口架构：新增 `/api/exam/record/{recordId}/grade` 接口；`/api/exam/grade` 新增 `record_id` 参数支持正式考试提交；删除冗余接口 `/formal-exam/record/{recordId}/submit` 和 `/admin/exam/record/{recordId}/submit`。 |
| V2.9.2 | 2026-05-11 | 删除重复字段 `status_detail`，只保留 `status` 字段。`exam_record` 表新增 `answer_type` 字段，所有考试记录增加类型标识。 |
| V2.9.1 | 2026-05-11 | 参数重命名：answer_type → type，值改为英文（practice/mock_exam/formal_exam）。删除 recordId 方式开始考试接口，统一使用 paperId。删除旧 UserExamController。数据库 answer_type 字段默认值改为 practice。 |
| V2.8.0 | 2026-05-10 | 简化用户考试流程：删除获取试卷详情和保存答案接口，开始考试接口同时返回题目，提交试卷接口改为接收答案参数一次性提交 |
| V2.7.0 | 2026-05-10 | 完善生成试卷权限控制：根据用户类型（超级管理员/部门管理员/普通用户）进行题目权限过滤，删除重复接口 GET /api/exam/list |
| V2.6.0 | 2026-05-10 | 修改 GET /api/question/list 添加用户权限过滤（本人库、本部门库、公共库）；生成试卷添加公共部门向量库支持 |
| V2.5.0 | 2026-05-10 | 补充文件管理接口：新增查询文件详情、获取文件内容接口；更新RAG流式问答接口参数格式 |
| V2.4.0 | 2026-05-10 | 添加文件管理接口、用户考试接口、管理员考试接口、错题管理接口、AI数据接口、数据同步接口 |
| V2.3.0 | 2026-05-09 | 添加生成试卷接口、用户答题记录查询接口，完善考试管理模块 |
| V2.2.0 | 2026-05-07 | 更新向量库列表和文档列表接口说明，改为从本地数据库读取 |
| V2.1.0 | 2026-05-06 | 添加题目、FAQ、图片完整CRUD接口文档 |
| V2.0.0 | 2026-05-05 | 整合考试管理、知识库管理、AI交互、AI流式等接口文档 |
| V1.0.2 | 2026-05-02 | 重构向量库管理接口 |
| V1.0.1 | 2026-05-02 | 整合向量库/知识库接口 |
| V1.0.0 | 2026-04-30 | 初始版本 |

---

**文档结束**
