# Vue 前端页面生成提示词 — 知识库管理模块 > 目标:基于以下 API 生成 Vue 3 + Element Plus 的知识库管理前端页面。 > 技术栈:Vue 3 Composition API + TypeScript + Element Plus + Axios。 > 接口 Base URL:`/knowledge-base` --- ## 一、系统概述 本项目是 AI 医疗开放平台,后端采用可插拔引擎架构(`KnowledgeEngineFactory` → `DifyKnowledgeEngine`),前端通过 `/knowledge-base` 控制器调用 Dify 知识库 API。 ### 后端分层 ``` 前端 Vue 页面 → /knowledge-base Controller(OpenPlatform 模块) → KnowledgeEngineFactory.getEngine("dify") → DifyKnowledgeEngine(OkHttp → Dify REST API) ``` --- ## 二、统一响应格式 所有接口返回 `com.emoon.common.core.domain.R` 格式: ```typescript interface ApiResponse { code: number // 200=成功 msg: string // 提示信息 data: T // 业务数据 } // 分页接口(Admin 端) interface TableDataInfo { rows: T[] total: number } ``` Axios 拦截器应统一处理 `code !== 200` 的错误,弹出 `msg` 提示。 --- ## 三、认证机制 所有 API 请求需带 4 个签名 Header(由 Axios 拦截器统一添加): ```typescript headers = { 'X-Emoon-Timestamp': Date.now().toString(), // 毫秒时间戳 'X-Emoon-Request-Id': crypto.randomUUID(), // UUID 'X-Emoon-Public-Key': projectStore.publicKey, // 项目公钥 'X-Emoon-Sign': md5(requestId + '&' + timestamp + '&' + payload + '&' + privateKey).toLowerCase() } ``` 签名算法:`MD5(requestId + "&" + timestamp + "&" + payload + "&" + privateKey)` - POST 请求 payload = JSON.stringify(body) - GET 请求 payload = ""(空字符串) - 时间戳有效期 5 分钟 --- ## 四、知识库 API 接口清单(17 个) ### 4.1 知识库 CRUD(5 个) | # | 方法 | 路径 | 说明 | |---|------|------|------| | 1 | GET | `/knowledge-base/list-from-dify` | 分页列表 | | 2 | GET | `/knowledge-base/detail` | 详情 | | 3 | POST | `/knowledge-base/create` | 创建 | | 4 | PUT | `/knowledge-base/update` | 更新 | | 5 | DELETE | `/knowledge-base/delete` | 删除 | #### 4.1.1 获取知识库列表(分页) ``` GET /knowledge-base/list-from-dify?engineConfig=xxx&page=1&limit=20&keyword= ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | engineConfig | String | 是 | 引擎配置 JSON | | page | int | 否 | 页码,默认 1 | | limit | int | 否 | 每页条数,默认 20 | | keyword | String | 否 | 按名称模糊搜索 | | includeAll | boolean | 否 | 是否包含所有知识库,默认 false | | tagIds | String[] | 否 | 按标签 ID 筛选 | ```json // 响应 data: { "data": [{ "id": "c42e2a6e-...", "name": "中医舌诊知识库", "description": "舌象诊断相关文献", "provider": "vendor", "permission": "only_me", "indexingTechnique": "high_quality", "appCount": 0, "documentCount": 0, "wordCount": 0, "createdBy": "...", "authorName": "admin", "createdAt": 1741267200, "updatedAt": 1741267200, "embeddingModel": "text-embedding-3-small", "embeddingModelProvider": "openai", "embeddingAvailable": true, "docForm": "text_model", "tags": [{ "id": "...", "name": "中医" }], "retrievalModelDict": { "searchMethod": "semantic_search", "rerankingEnable": false, "topK": 3, "scoreThresholdEnabled": false }, "enableApi": true, "isPublished": false, "totalDocuments": 0 }], "hasMore": false, "limit": 20, "total": 1, "page": 1 } ``` #### 4.1.2 获取知识库详情 ``` GET /knowledge-base/detail?datasetId=xxx&engineConfig=xxx ``` 响应 `data` 为 `KnowledgeDatasetInfo` 对象(字段同上)。 #### 4.1.3 创建知识库 ``` POST /knowledge-base/create Content-Type: application/json { "name": "中医舌诊知识库", "description": "舌象诊断相关文献和病例", "engineConfig": "{\"baseUrl\":\"http://...\",\"secretKey\":\"app-xxx\"}", "indexingTechnique": "high_quality", "permission": "only_me", "embeddingModel": "bge-large-zh-v1.5", "embeddingModelProvider": "huggingface", "retrievalModel": { "searchMethod": "semantic_search", "rerankingEnable": true, "rerankingProviderName": "cohere", "rerankingModelName": "rerank-multilingual-v3.0", "topK": 5, "scoreThresholdEnabled": true, "scoreThreshold": 0.5 } } ``` 响应 `data` 为创建后的 `KnowledgeDatasetInfo`。 #### 4.1.4 更新知识库 ``` PUT /knowledge-base/update Content-Type: application/json { "datasetId": "c42e2a6e-...", "name": "中医舌诊知识库(更新)", "description": "更新后的描述", "engineConfig": "{\"baseUrl\":\"...\",\"secretKey\":\"...\"}" } ``` #### 4.1.5 删除知识库 ``` DELETE /knowledge-base/delete?datasetId=xxx&engineConfig=xxx ``` --- ### 4.2 文档管理(5 个) | # | 方法 | 路径 | 说明 | |---|------|------|------| | 6 | GET | `/knowledge-base/document/list` | 文档分页列表 | | 7 | GET | `/knowledge-base/document/detail` | 文档详情 | | 8 | DELETE | `/knowledge-base/document/delete` | 删除文档 | | 9 | POST | `/knowledge-base/document/upload` | 上传文件创建文档 | | 10 | POST | `/knowledge-base/document/update-by-file` | 上传文件更新文档 | | 11 | GET | `/knowledge-base/document/download` | 获取下载 URL | | 12 | GET | `/knowledge-base/document/indexing-status` | 索引进度轮询 | #### 4.2.1 获取文档列表 ``` GET /knowledge-base/document/list?datasetId=xxx&engineConfig=xxx&page=1&limit=20&keyword=&status= ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | datasetId | String | 是 | 知识库 ID | | engineConfig | String | 是 | 引擎配置 JSON | | page | int | 否 | 默认 1 | | limit | int | 否 | 默认 20,上限 100 | | keyword | String | 否 | 按文档名称搜索 | | status | String | 否 | queuing/indexing/paused/error/available/disabled/archived | ```json // 响应 data: { "data": [{ "id": "a8e0e5b5-...", "position": 1, "name": "guide.txt", "dataSourceType": "upload_file", "createdFrom": "api", "createdBy": "...", "createdAt": 1741267200, "tokens": 512, "indexingStatus": "completed", "error": null, "enabled": true, "archived": false, "displayStatus": "available", "wordCount": 350, "hitCount": 0, "docForm": "text_model", "docMetadata": [] }], "hasMore": false, "limit": 20, "total": 1, "page": 1 } ``` #### 4.2.2 获取文档详情 ``` GET /knowledge-base/document/detail?datasetId=xxx&documentId=xxx&engineConfig=xxx&metadata=all ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | metadata | String | 否 | all=全部 / only=仅id+docType+docMetadata / without=除docMetadata外 | 响应额外包含: ```json { "docLanguage": "English", "docType": null, "completedAt": 1741267260, "updatedAt": 1741267260, "indexingLatency": 60, "segmentCount": 5, "averageSegmentLength": 70, "summaryIndexStatus": null, "needSummary": false, "datasetProcessRule": { "id": "...", "mode": "custom" }, "documentProcessRule": { "mode": "custom", "rules": { "preProcessingRules": [], "segmentation": { "separator": "###", "maxTokens": 500, "chunkOverlap": 50 } } } } ``` #### 4.2.3 删除文档 ``` DELETE /knowledge-base/document/delete?datasetId=xxx&documentId=xxx&engineConfig=xxx ``` #### 4.2.4 上传文件创建文档 ``` POST /knowledge-base/document/upload Content-Type: multipart/form-data file: (binary) datasetId: xxx engineConfig: xxx indexingTechnique: high_quality (可选) docForm: text_model (可选) docLanguage: Chinese (可选) processRuleJson: {"mode":"automatic"} (可选) retrievalModelJson: {"searchMethod":"semantic_search",...} (可选) embeddingModel: bge-large-zh-v1.5 (可选) embeddingModelProvider: huggingface (可选) ``` ```json // 响应 data: { "document": { "id": "...", "name": "...", "indexingStatus": "waiting", ... }, "batch": "20250306150245647595" } ``` **重要**:返回的 `batch` 用于轮询索引进度(见 4.2.6)。 #### 4.2.5 上传文件更新文档 ``` POST /knowledge-base/document/update-by-file Content-Type: multipart/form-data file: (binary) datasetId: xxx documentId: xxx engineConfig: xxx // ...其他可选参数同上传 ``` 响应格式同 4.2.4(`document` + `batch`)。 #### 4.2.6 获取文档下载 URL ``` GET /knowledge-base/document/download?datasetId=xxx&documentId=xxx&engineConfig=xxx ``` ```json // 响应 data: { "url": "https://cdn.dify.ai/..." } ``` #### 4.2.7 获取索引进度(轮询) ``` GET /knowledge-base/document/indexing-status?datasetId=xxx&batch=xxx&engineConfig=xxx ``` ```json // 响应 data: { "data": [{ "id": "a8e0e5b5-...", "indexingStatus": "completed", "processingStartedAt": 1741267200, "parsingCompletedAt": 1741267200, "cleaningCompletedAt": 1741267200, "splittingCompletedAt": 1741267200, "completedAt": 1741267200, "pausedAt": null, "error": null, "stoppedAt": null, "completedSegments": 5, "totalSegments": 5 }] } ``` **轮询逻辑**: ``` 状态推进:waiting → parsing → cleaning → splitting → indexing → completed - 每 2 秒轮询一次 - indexingStatus === 'completed' → 停止轮询,刷新文档列表 - indexingStatus === 'error' → 停止轮询,显示 error 内容 ``` --- ### 4.3 分段管理(4 个) | # | 方法 | 路径 | 说明 | |---|------|------|------| | 13 | GET | `/knowledge-base/segment/list` | 分段分页列表 | | 14 | GET | `/knowledge-base/segment/detail` | 分段详情 | | 15 | POST | `/knowledge-base/segment/create` | 添加分段 | | 16 | GET | `/knowledge-base/segment/child-chunks` | 子分段列表 | #### 4.3.1 获取分段列表 ``` GET /knowledge-base/segment/list?datasetId=xxx&documentId=xxx&engineConfig=xxx&page=1&limit=20&keyword=&status= ``` ```json // 响应 data: { "data": [{ "id": "f3d1c7be-...", "position": 1, "documentId": "a8e0e5b5-...", "content": "Dify is an open-source LLM app development platform.", "signContent": "", "answer": "", "wordCount": 9, "tokens": 12, "keywords": ["dify", "platform", "llm"], "indexNodeId": "...", "indexNodeHash": "...", "hitCount": 0, "enabled": true, "status": "completed", "createdBy": "...", "createdAt": 1741267200, "updatedAt": 1741267200, "childChunks": [], "attachments": [], "summary": null }], "docForm": "text_model", "total": 1, "hasMore": false, "limit": 20, "page": 1 } ``` #### 4.3.2 获取分段详情 ``` GET /knowledge-base/segment/detail?datasetId=xxx&documentId=xxx&segmentId=xxx&engineConfig=xxx ``` ```json // 响应 data: { "data": { /* KnowledgeSegmentInfo 单个对象 */ }, "docForm": "text_model" } ``` #### 4.3.3 添加分段 ``` POST /knowledge-base/segment/create Content-Type: application/json { "datasetId": "xxx", "documentId": "xxx", "engineConfig": "xxx", "segments": [ { "content": "分段文本内容", "answer": "QA 模式的答案(可选)", "keywords": ["关键词1", "关键词2"], "attachmentIds": ["附件ID1"] } ] } ``` 响应同 `segment/list` 结构(`data` + `docForm`)。 #### 4.3.4 获取子分段(分层模式文档) ``` GET /knowledge-base/segment/child-chunks?datasetId=xxx&documentId=xxx&segmentId=xxx&engineConfig=xxx&page=1&limit=20&keyword= ``` ```json // 响应 data: { "data": [{ "id": "d7e8f9a0-...", "segmentId": "f3d1c7be-...", "content": "Dify is an open-source platform.", "position": 1, "wordCount": 6, "type": "automatic", "createdAt": 1741267200, "updatedAt": 1741267200 }], "total": 1, "totalPages": 1, "page": 1, "limit": 20 } ``` --- ### 4.4 知识检索(1 个) | # | 方法 | 路径 | 说明 | |---|------|------|------| | 17 | POST | `/knowledge-base/retrieve` | 检索知识库 | #### 4.4.1 检索知识库 ``` POST /knowledge-base/retrieve Content-Type: application/json { "query": "舌苔发白是什么原因", "datasetIds": ["c42e2a6e-...", "d53f3b7f-..."], "engineConfig": "xxx" } ``` ```json // 响应 data: { "records": [ { "content": "舌苔发白多见于寒证...", "score": 0.95, "documentName": "舌诊入门.pdf", "datasetName": "中医舌诊知识库" } ] } ``` --- ## 五、页面结构推荐 建议创建以下 Vue 页面(路由 `/knowledge-base` 下): ### 5.1 知识库列表页 `views/knowledge/DatasetList.vue` - 搜索栏:关键词输入框 + 标签筛选 + 搜索按钮 - 表格/卡片列表: - 列:名称、描述、文档数、索引技术、嵌入模型、创建时间、操作 - 操作:查看详情、编辑、删除(二次确认)、进入文档列表 - 创建按钮 → 弹出创建对话框(表单:名称、描述、权限、索引技术、嵌入模型配置) - 分页组件 ### 5.2 知识库详情页 `views/knowledge/DatasetDetail.vue` - 基本信息区:名称、描述、权限、提供者、创建者、时间 - 检索配置区:searchMethod、topK、rerankingEnable、scoreThreshold - 嵌入模型区:embeddingModel、embeddingModelProvider - 编辑按钮 → 弹出编辑对话框 ### 5.3 文档列表页 `views/knowledge/DocumentList.vue` - **路由**:`/knowledge-base/:datasetId/documents` - 顶部显示当前知识库名称(面包屑导航) - 搜索栏:关键词 + 状态下拉筛选(queuing/indexing/paused/error/available/disabled/archived) - 文档表格: - 列:名称、状态(带颜色标签)、来源、字数、命中次数、创建时间、操作 - 状态标签:`waiting(灰) → parsing → cleaning → splitting → indexing(蓝) → completed(绿) / error(红) / paused(黄)` - 操作:查看分段、查看详情、下载、删除 - 上传文档按钮 → 弹出上传对话框: - 文件选择器(支持 .pdf .txt .docx .md .html .csv) - 索引技术选择、分块模式选择、语言选择 - 上传后显示进度条,轮询 `indexing-status` 直到完成 - 分页组件 ### 5.4 文档详情抽屉/对话框 `views/knowledge/DocumentDetail.vue` - 基本信息:名称、来源、创建者、创建时间、更新/完成时间 - 索引信息:status、进度、segmentCount、averageSegmentLength、indexingLatency - 处理规则:datasetProcessRule(知识库级)、documentProcessRule(文档级分段规则) - 元数据列表:docMetadata(键值对表格) ### 5.5 分段列表页 `views/knowledge/SegmentList.vue` - **路由**:`/knowledge-base/:datasetId/documents/:documentId/segments` - 面包屑:知识库 > 文档名称 > 分段列表 - 搜索栏:关键词 + 状态筛选 - 分段表格/卡片: - 每条分段显示:position、content(截断,可展开)、wordCount、keywords、status、hitCount - 操作:查看详情、查看子分段(分层模式文档) - 添加分段按钮 → 弹出对话框: - 批量添加(可增加多行):content、answer、keywords ### 5.6 知识检索页(可选)`views/knowledge/Retrieve.vue` - 知识库多选下拉 - 搜索输入框 - 结果列表(card 布局):content 片段 + score 分数 + 来源文档/知识库 --- ## 六、全局状态建议 ```typescript // stores/knowledge.ts (Pinia) interface KnowledgeStore { engineConfig: string // 由智能体配置传入 currentDatasetId: string | null // 当前选中知识库 currentDataset: KnowledgeDatasetInfo | null pollingTimer: ReturnType | null } ``` --- ## 七、关键交互细节 1. **索引进度轮询**:上传文档后,每 2s 轮询 `/document/indexing-status`,使用 `batch` 参数。格式化各阶段耗时(processingStartedAt → parsingCompletedAt → ... → completedAt)。 2. **时间格式化**:所有时间戳为 Unix 秒,需 `new Date(timestamp * 1000).toLocaleString()`。 3. **错误处理**:删除操作弹出二次确认,后端抛 404 时("文档不存在"/"分段不存在")给出友好提示。 4. **引擎配置传递**:所有 API 都需带 `engineConfig` 参数(JSON String),由前端从上级页面(智能体配置)获取并全局存储。 5. **分段关键词**:以 Tag 标签形式展示,添加分段时支持 Tag 输入。 6. **文件上传**:使用 `` 组件,支持拖拽,限制文件大小(建议 15MB),显示上传进度。 --- ## 八、TypeScript 类型定义建议 在 `types/knowledge.d.ts` 中定义以下 interface: - `KnowledgeDatasetInfo` — 知识库信息 - `KnowledgeDocumentInfo` — 文档信息 - `KnowledgeSegmentInfo` — 分段信息 - `KnowledgeChildChunkInfo` — 子分段信息 - `KnowledgeRetrievalModel` — 检索模型配置 - `KnowledgeProcessRule` — 处理规则 - `KnowledgeIndexingStatusInfo` — 索引进度 - `PageResult` — 通用分页结果 `{ data: T[], hasMore: boolean, limit: number, total: number, page: number }` - `ApiResponse` — 统一响应 `{ code: number, msg: string, data: T }`