fix(pkb): fix create KB and upload issues - remove simulated upload, fix department mapping, add upload modal

Fixed issues:
- Remove simulateUpload function from DashboardPage Step 3
- Map department to description field when creating KB
- Add upload modal in WorkspacePage knowledge assets tab
- Fix DocumentUpload import path (../../stores to ../stores)

Known issue: Dify API validation error during document upload (file uploaded but DB record failed, needs investigation)

Testing: KB creation works, upload dialog opens correctly
This commit is contained in:
2026-01-13 13:17:20 +08:00
parent d595037316
commit 4088275290
280 changed files with 4344 additions and 150 deletions

View File

@@ -0,0 +1,568 @@
# AIA V2.1 后端 API 设计
> **版本**V2.1
> **创建日期**2026-01-11
> **基础路径**`/api/v2/aia`
---
## 📋 API 概览
| 方法 | 路径 | 描述 | 认证 |
|------|------|------|------|
| GET | `/agents` | 获取智能体列表 | ✅ |
| GET | `/agents/:id` | 获取智能体详情 | ✅ |
| POST | `/intent/route` | 意图路由 | ✅ |
| GET | `/conversations` | 获取对话列表 | ✅ |
| POST | `/conversations` | 创建对话 | ✅ |
| GET | `/conversations/:id` | 获取对话详情 | ✅ |
| DELETE | `/conversations/:id` | 删除对话 | ✅ |
| POST | `/conversations/:id/messages/stream` | 发送消息(流式) | ✅ |
| POST | `/conversations/:id/attachments` | 上传附件 | ✅ |
| GET | `/projects` | 获取项目列表 | ✅ |
| GET | `/projects/:id` | 获取项目详情 | ✅ |
---
## 🔐 认证
所有 API 需要在请求头中携带 JWT Token
```
Authorization: Bearer <token>
```
---
## 📖 API 详细定义
### 1. 智能体相关
#### 1.1 获取智能体列表
```http
GET /api/v2/aia/agents
```
**查询参数**
| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| stage | string | 否 | 筛选阶段:`design`, `data`, `analysis`, `write`, `publish` |
**响应**
```json
{
"code": 0,
"data": {
"agents": [
{
"id": "research-design",
"name": "科研设计小助手",
"description": "帮助您完成研究方案设计、文献检索、方法学指导",
"icon": "🔬",
"stage": "design",
"color": "#3B82F6",
"knowledgeBaseId": "kb-001",
"isTool": false
},
{
"id": "dc-tool",
"name": "数据采集工具",
"description": "跳转到数据采集模块",
"icon": "📊",
"stage": "data",
"color": "#8B5CF6",
"targetModule": "/data-collection",
"isTool": true
}
]
}
}
```
#### 1.2 获取智能体详情
```http
GET /api/v2/aia/agents/:id
```
**响应**
```json
{
"code": 0,
"data": {
"id": "research-design",
"name": "科研设计小助手",
"description": "帮助您完成研究方案设计、文献检索、方法学指导",
"icon": "🔬",
"stage": "design",
"color": "#3B82F6",
"knowledgeBaseId": "kb-001",
"systemPrompt": "你是一个专业的医学科研设计专家...",
"welcomeMessage": "您好!我是科研设计小助手,我可以帮您:\n- 设计研究方案\n- 检索相关文献\n- 指导研究方法",
"suggestedQuestions": [
"如何设计一个RCT研究",
"帮我检索近5年糖尿病研究文献",
"什么情况下使用倾向性评分匹配?"
]
}
}
```
---
### 2. 意图路由
#### 2.1 智能意图识别
```http
POST /api/v2/aia/intent/route
```
**请求体**
```json
{
"query": "帮我分析一下这份数据"
}
```
**响应**
```json
{
"code": 0,
"data": {
"agentId": "data-analysis",
"agentName": "统计分析小助手",
"confidence": 0.92,
"prefillPrompt": "请帮我分析这份数据,包括描述性统计和相关性分析"
}
}
```
---
### 3. 对话管理
#### 3.1 获取对话列表
```http
GET /api/v2/aia/conversations
```
**查询参数**
| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| agentId | string | 否 | 按智能体筛选 |
| projectId | string | 否 | 按项目筛选NULL 表示通用对话) |
| page | number | 否 | 页码,默认 1 |
| pageSize | number | 否 | 每页数量,默认 20 |
**响应**
```json
{
"code": 0,
"data": {
"conversations": [
{
"id": "conv-001",
"title": "RCT研究设计咨询",
"agentId": "research-design",
"agentName": "科研设计小助手",
"projectId": null,
"messageCount": 12,
"lastMessage": "好的,我来帮您设计研究方案...",
"createdAt": "2026-01-11T10:00:00Z",
"updatedAt": "2026-01-11T12:30:00Z"
}
],
"pagination": {
"total": 25,
"page": 1,
"pageSize": 20,
"totalPages": 2
}
}
}
```
#### 3.2 创建对话
```http
POST /api/v2/aia/conversations
```
**请求体**
```json
{
"agentId": "research-design",
"projectId": null,
"title": "新对话"
}
```
**响应**
```json
{
"code": 0,
"data": {
"id": "conv-002",
"title": "新对话",
"agentId": "research-design",
"projectId": null,
"createdAt": "2026-01-11T14:00:00Z"
}
}
```
#### 3.3 获取对话详情(含历史消息)
```http
GET /api/v2/aia/conversations/:id
```
**查询参数**
| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| limit | number | 否 | 获取最近N条消息默认 50 |
**响应**
```json
{
"code": 0,
"data": {
"id": "conv-001",
"title": "RCT研究设计咨询",
"agentId": "research-design",
"agentName": "科研设计小助手",
"projectId": null,
"createdAt": "2026-01-11T10:00:00Z",
"updatedAt": "2026-01-11T12:30:00Z",
"messages": [
{
"id": "msg-001",
"role": "user",
"content": "帮我设计一个关于糖尿病的RCT研究",
"attachments": [],
"createdAt": "2026-01-11T10:00:00Z"
},
{
"id": "msg-002",
"role": "assistant",
"content": "好的我来帮您设计一个糖尿病RCT研究方案...",
"thinkingContent": "用户想设计RCT研究需要考虑1研究目的 2入排标准 3样本量 4随机化方法 5盲法 6结局指标...",
"model": "deepseek-v3",
"tokens": 1250,
"createdAt": "2026-01-11T10:00:30Z"
}
]
}
}
```
#### 3.4 删除对话
```http
DELETE /api/v2/aia/conversations/:id
```
**响应**
```json
{
"code": 0,
"data": {
"deleted": true
}
}
```
---
### 4. 消息发送(流式)
#### 4.1 发送消息并获取流式响应
```http
POST /api/v2/aia/conversations/:id/messages/stream
```
**请求头**
```
Content-Type: application/json
Accept: text/event-stream
```
**请求体**
```json
{
"content": "帮我分析这份数据",
"attachmentIds": ["att-001", "att-002"],
"enableDeepThinking": true
}
```
**响应SSE 格式)**
```
event: thinking_start
data: {}
event: thinking_delta
data: {"content": "用户上传了数据文件,需要"}
event: thinking_delta
data: {"content": "进行描述性统计分析..."}
event: thinking_end
data: {"duration": 3200}
event: message_start
data: {"id": "msg-003"}
event: delta
data: {"content": "根据您上传的数据,"}
event: delta
data: {"content": "我来为您进行分析..."}
event: message_end
data: {"id": "msg-003", "tokens": 850, "model": "deepseek-v3"}
event: done
data: {}
```
**SSE 事件类型**
| 事件 | 描述 | 数据格式 |
|------|------|---------|
| `thinking_start` | 开始深度思考 | `{}` |
| `thinking_delta` | 思考内容片段 | `{"content": "..."}` |
| `thinking_end` | 思考结束 | `{"duration": number}` |
| `message_start` | 开始生成回复 | `{"id": "..."}` |
| `delta` | 回复内容片段 | `{"content": "..."}` |
| `message_end` | 回复结束 | `{"id": "...", "tokens": number, "model": "..."}` |
| `error` | 发生错误 | `{"code": "...", "message": "..."}` |
| `done` | 流结束 | `{}` |
---
### 5. 附件上传
#### 5.1 上传附件
```http
POST /api/v2/aia/conversations/:id/attachments
```
**请求头**
```
Content-Type: multipart/form-data
```
**请求体FormData**
| 字段 | 类型 | 必填 | 描述 |
|------|------|------|------|
| file | File | 是 | 文件PDF/Word/TXT/Excel最大20MB |
**响应**
```json
{
"code": 0,
"data": {
"id": "att-001",
"filename": "研究数据.xlsx",
"mimeType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"size": 1024000,
"ossUrl": "https://oss.example.com/attachments/att-001.xlsx",
"textExtracted": true,
"tokenCount": 15000,
"truncated": false,
"createdAt": "2026-01-11T14:00:00Z"
}
}
```
**错误码**
| 错误码 | 描述 |
|--------|------|
| `ATTACHMENT_TOO_LARGE` | 文件超过 20MB |
| `ATTACHMENT_TYPE_NOT_SUPPORTED` | 不支持的文件类型 |
| `ATTACHMENT_LIMIT_EXCEEDED` | 附件数量超过上限5个 |
| `TEXT_EXTRACTION_FAILED` | 文本提取失败 |
---
### 6. 项目管理
#### 6.1 获取项目列表
```http
GET /api/v2/aia/projects
```
**响应**
```json
{
"code": 0,
"data": {
"projects": [
{
"id": "proj-001",
"name": "糖尿病研究项目",
"description": "2型糖尿病患者生活方式干预研究",
"conversationCount": 5,
"createdAt": "2026-01-01T10:00:00Z",
"updatedAt": "2026-01-11T12:00:00Z"
}
]
}
}
```
---
## 🔧 错误处理
### 错误响应格式
```json
{
"code": -1,
"error": {
"code": "CONVERSATION_NOT_FOUND",
"message": "对话不存在"
}
}
```
### 通用错误码
| 错误码 | HTTP 状态码 | 描述 |
|--------|------------|------|
| `UNAUTHORIZED` | 401 | 未授权 |
| `FORBIDDEN` | 403 | 无权限 |
| `NOT_FOUND` | 404 | 资源不存在 |
| `VALIDATION_ERROR` | 400 | 参数验证失败 |
| `INTERNAL_ERROR` | 500 | 服务器内部错误 |
| `LLM_ERROR` | 500 | LLM 调用失败 |
| `RATE_LIMITED` | 429 | 请求过于频繁 |
---
## 📊 数据模型
### Attachment附件
```typescript
interface Attachment {
id: string; // 附件ID
filename: string; // 原始文件名
mimeType: string; // MIME 类型
size: number; // 文件大小(字节)
ossUrl: string; // OSS 存储地址
textContent?: string; // 提取的文本内容(存储时截断)
tokenCount: number; // 文本 Token 数
truncated: boolean; // 是否被截断超过30K tokens
createdAt: string; // 创建时间
}
```
### Message消息
```typescript
interface Message {
id: string;
conversationId: string;
role: 'user' | 'assistant';
content: string;
thinkingContent?: string; // 深度思考内容
attachments?: Attachment[];
model?: string;
tokens?: number;
isPinned: boolean;
createdAt: string;
}
```
---
## 🧪 测试示例REST Client
```http
###
GET {{baseUrl}}/api/v2/aia/agents
Authorization: Bearer {{token}}
###
POST {{baseUrl}}/api/v2/aia/intent/route
Authorization: Bearer {{token}}
Content-Type: application/json
{
"query": ""
}
###
POST {{baseUrl}}/api/v2/aia/conversations
Authorization: Bearer {{token}}
Content-Type: application/json
{
"agentId": "research-design",
"title": ""
}
###
POST {{baseUrl}}/api/v2/aia/conversations/{{conversationId}}/messages/stream
Authorization: Bearer {{token}}
Content-Type: application/json
Accept: text/event-stream
{
"content": "RCT",
"enableDeepThinking": true
}
###
POST {{baseUrl}}/api/v2/aia/conversations/{{conversationId}}/attachments
Authorization: Bearer {{token}}
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="data.xlsx"
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
< ./data.xlsx
------WebKitFormBoundary--
```
---
## 📝 更新日志
| 日期 | 版本 | 内容 |
|------|------|------|
| 2026-01-11 | V1.0 | 创建 API 设计文档 |