Files
my-springboot-project/docs/完整接口文档.md

2376 lines
60 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.
# 知识库管理系统 - 完整接口文档
## 文档信息
| 项目 | 内容 |
| ---------- | ------------------ |
| **文档名称** | 知识库管理系统完整接口文档 |
| **版本号** | V2.16.0 |
| **发布日期** | 2026-06-05 |
| **文档状态** | 正式发布 |
| **接口基础路径** | `/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 | 最终结果(包含 answer / citations / images将写入数据库 |
| error | 错误信息 |
**finish 事件核心字段说明**
| 字段 | 类型 | 说明 |
| ------------ | -------- | ------------------------------------------------------------ |
| answer | String | AI生成的回答文本`[ref:chunk_id]` 引用标记,前端可解析为可点击引用) |
| citations | Array | 真正被引用的切片列表,将写入 `context_reference` 表;每个元素包含 `chunk_id``chunk_index``source``collection``doc_type``section``chunk_type``page` 等字段 |
| images | Array | 回答中包含的图片列表,将写入 `context_image` 表;每个元素包含 `image_id``url``source``page``section``description``score``collection` 等字段 |
| duration_ms | Integer | 回答耗时(毫秒),写入 `context_message.duration_ms` |
**重要数据流程(保存时自动执行)**
1. **context_reference.preview 自动填充**:对 `citations` 中每个引用,系统自动调用 RAG 预览接口 `GET /documents/{path}/preview?chunk_index=N&context=0`,将目标切片的完整正文写入 `preview` 字段,供前端定位展示。若接口失败,`preview` 写入失败信息。
2. **context_message 无 sources 字段**:旧版 `sources` 已移除,仅在流式事件中返回来源提示信息用于前端展示。
3. **context_image 字段精简**:仅保留 `image_id``path``source``page``section``chunk_type``description``score``collection``create_time`;已移除 `filename``size_bytes``format``page_end``type``full_description` 等冗余字段。
---
## 七、AI 会话管理接口
**基础路径**`/api/ai`
### 7.1 获取用户会话列表
**接口路径**: `GET /api/ai/sessions?page=1&pageSize=10`
**请求参数**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| page | Integer | 否 | 1 | 页码 |
| pageSize | Integer | 否 | 10 | 每页数量 |
**返回结构**:
```json
{
"success": true,
"data": [
{
"id": 1,
"sessionId": "sess_1780410472658_9qg9a9hhp",
"userId": 1,
"createTime": "2026-06-02T14:27:53"
}
],
"total": 5,
"page": 1,
"pageSize": 10,
"pages": 1
}
```
---
### 7.2 获取会话详情
**接口路径**: `GET /api/ai/session/{sessionId}?page=1&pageSize=20`
**路径参数**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| sessionId | String | 是 | 会话ID |
**请求参数**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| page | Integer | 否 | 1 | 页码 |
| pageSize | Integer | 否 | 20 | 每页消息数 |
**返回结构**:
```json
{
"success": true,
"data": [
{
"id": 175,
"conversationId": 65,
"role": "assistant",
"content": "用户问: xxx",
"messageType": "rag",
"isFinished": 1,
"answer": "根据参考资料...",
"images": "[{\"image_id\":\"xxx\",\"url\":\"/api/image/xxx/data\"}]",
"durationMs": 75512,
"createTime": "2026-06-02T14:29:09"
}
],
"total": 3,
"page": 1,
"pageSize": 20,
"pages": 1
}
```
**说明**`context_message``sources` 字段;图片信息在 `images` 字段中JSON数组字符串
---
### 7.3 获取消息文件来源列表
**接口路径**: `GET /api/ai/message/{messageId}/sources`
**路径参数**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| messageId | Long | 是 | 消息ID来自 context_message.id |
**返回结构**(按文档名称聚合,去重显示):
```json
{
"success": true,
"data": [
{
"docName": "1.docx",
"docType": "other",
"referenceCount": 5,
"pages": "1-86"
},
{
"docName": "2.docx",
"docType": "other",
"referenceCount": 3,
"pages": "1"
}
],
"total": 2
}
```
**说明**:此接口从 `context_reference` 表按文档聚合查询,不依赖已移除的 `context_message.sources` 字段。
---
### 7.4 获取消息引用信息
**接口路径**: `GET /api/ai/message/{messageId}/references?docName=xxx`
**路径参数**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| messageId | Long | 是 | 消息ID |
**请求参数**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| docName | String | 否 | 按文档名称过滤 |
**返回结构**:
```json
{
"success": true,
"data": [
{
"id": 440,
"messageId": 178,
"chunkId": "1.docx_86",
"chunkIndex": 86,
"collection": "dept_1_kb",
"docName": "1.docx",
"docType": "other",
"page": 1,
"section": "3.1 权重计算公式",
"chunkType": "text",
"excerpt": "一级指标合计权重不低于70%。",
"preview": "完整的目标切片正文内容...",
"score": 0.838,
"createTime": "2026-06-04T15:52:49"
}
],
"total": 5
}
```
**关键字段说明**
| 字段 | 说明 |
|------|------|
| `chunkId` | 切片唯一标识,格式:`{docName}_{chunkIndex}` |
| `preview` | 目标切片完整正文(通过 RAG 预览接口自动获取),若接口失败则写入失败信息 |
| `score` | 相关性评分 |
| `excerpt` | 切片摘要内容 |
---
### 7.5 获取会话所有引用
**接口路径**: `GET /api/ai/session/{sessionId}/references`
**路径参数**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| sessionId | String | 是 | 会话ID |
**说明**:返回会话内所有消息关联的全部引用信息,结构同 7.4。
---
### 7.6 删除会话
**接口路径**: `DELETE /api/ai/session/{sessionId}`
**说明**:删除指定会话及其所有消息和引用数据。
---
### 7.7 批量删除会话
**接口路径**: `DELETE /api/ai/sessions/batch?ids=1,2,3`
**请求参数**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| ids | String | 是 | 会话ID列表逗号分隔 |
---
### 7.8 中断AI流式问答
**接口路径**: `POST /api/ai/chat/stop?sessionId=sess_xxx`
**请求参数**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| sessionId | String | 是 | 会话ID |
**返回**:
```json
{
"success": true,
"message": "已中断AI回答"
}
```
---
## 八、AI数据接口
**基础路径**`/api/ai/data`
### 8.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`
### 9.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 年,三峡电站累计发电量是多少?最好带图片说明"
}
```
**步骤2RAG服务返回完整数据**
```json
{
"type": "finish",
"answer": "根据【参考资料】...",
"images": [
{
"image_id": "ab77281e7913.jpg",
"path": "/api/image/ab77281e7913.jpg/data",
"source": "三峡公报_1-15页.pdf",
"page": 12,
"section": "3.1 数据图表",
"chunk_type": "image",
"description": "这是一张柱状图...",
"score": 0.85,
"collection": "public_kb"
}
]
}
```
**步骤3系统自动处理**
- ✅ 提取图片元数据image_id, path, source, page, section, chunk_type, description, score, collection
- ✅ 从AI服务下载图片到本地目录
- ✅ 保存图片元数据到 `context_image`
- ✅ 保存图片到本地文件系统
**已移除的旧字段**`filename``size_bytes``format``page_end``type``full_description`
**步骤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.chunk_type}</p>
<p><strong>描述</strong>{image.description}</p>
<p><strong>相关性评分</strong>{image.score}</p>
</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.chunk_type }}</p>
<p><strong>描述</strong>{{ image.description }}</p>
<p><strong>相关性评分</strong>{{ image.score }}</p>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['images']
}
</script>
```
### 10.1 创建图片记录
**接口路径**: `POST /api/image`
**请求体**:
```json
{
"image_id": "图片唯一标识",
"path": "存储路径/图片URL",
"source": "来源文档(可选)",
"page": 1,
"section": "所在章节(可选)",
"chunk_type": "切片类型(可选)如:image/table",
"description": "图片描述(可选)",
"score": 0.85,
"collection": "所属向量库(可选)"
}
```
**字段说明**`filename``size_bytes``format``page_end``type``full_description` 已移除。
---
### 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
{
"path": "更新后的路径(可选)",
"source": "更新后的来源文档(可选)",
"page": 2,
"section": "更新后的章节(可选)",
"chunk_type": "更新后的切片类型(可选)",
"description": "更新后的描述(可选)",
"score": 0.9,
"collection": "更新后的向量库(可选)"
}
```
---
### 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`
---
## 二十、接口权限说明
### 21.1 权限层级
| 用户类型 | 类型值 | 权限说明 |
| ----- | --- | ------------------- |
| 超级管理员 | 1 | 完全访问权限,可管理所有向量库和文档 |
| 部门管理员 | 2 | 可管理本部门的所有向量库和文档 |
| 普通用户 | 3 | 可管理个人上传的文档和本部门的公开文档 |
### 20.2 权限矩阵
| 接口 | 超级管理员 | 部门管理员 | 普通用户 |
|------|-----------|-----------|----------|
| 获取向量库列表 | ✅ | ✅ | ✅ |
| 创建向量库 | ✅ | ✅ | ❌ |
| 修改向量库 | ✅ | ✅ | ❌ |
| 删除向量库 | ✅ | ✅ | ❌ |
| 文件向量化 | ✅ | ✅ | ✅ |
| 获取文档列表 | ✅ | ✅ | ✅ |
| 删除文档 | ✅ | ✅ | ❌ |
| 生成题目 | ✅ | ✅ | ✅ |
| 批改答案 | ✅ | ✅ | ✅ |
| 提交反馈 | ✅ | ✅ | ✅ |
| 获取反馈列表 | ✅ | ✅ | ✅ |
| 题目CRUD | ✅ | ✅ | ❌ |
| FAQ CRUD | ✅ | ✅ | ❌ |
| 图片CRUD | ✅ | ✅ | ❌ |
| 试卷管理 | ✅ | ✅ | ❌ |
| 用户考试 | ✅ | ✅ | ✅ |
---
## 二十一、错误码详解
### 22.1 认证相关错误
| 错误码 | 错误信息 | 解决方案 |
| --- | -------- | -------------- |
| 401 | 用户未登录 | 请先登录获取Token |
| 401 | Token无效 | 请重新登录获取有效Token |
| 401 | Token已过期 | 请重新登录 |
| 403 | 权限不足 | 联系管理员提升权限 |
### 22.2 业务逻辑错误
| 错误码 | 错误信息 | 解决方案 |
| --- | -------------------- | -------------- |
| 400 | 参数错误 | 检查请求参数格式和必填项 |
| 404 | 向量库不存在 | 检查向量库名称是否正确 |
| 404 | 文档不存在 | 检查文档路径是否正确 |
| 500 | 创建向量库失败 | 检查数据库连接或重试 |
---
## 二十二、使用限制
### 23.1 通用限制
| 限制项 | 限制值 | 说明 |
| -------- | ---- | ----------- |
| 文件上传大小 | 50MB | 单个文件最大50MB |
| 批量上传文件数 | 20 | 一次最多上传20个文件 |
| 分页最大页码 | 1000 | 超过后性能下降 |
| 每页最大记录数 | 100 | 超过后建议优化查询 |
| Token有效期 | 24小时 | 登录Token有效期 |
### 23.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/Vue3. 完善图片元数据字段说明(新增 score、type、description、full_description4. 新增图片自动下载和本地保存功能说明。 |
| V2.11.0 | 2026-05-17 | 1. 控制器重命名KnowledgeBasePathController → CollectionAccessController路径从 /api/kb-path 改为 /api/collection-access2. 部门字段重命名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 | 初始版本 |
---
**文档结束**