diff --git a/ui/src/api/API_README.md b/ui/src/api/API_README.md index be96a5a02df..653cb606c09 100644 --- a/ui/src/api/API_README.md +++ b/ui/src/api/API_README.md @@ -566,7 +566,20 @@ Workspace、System 资源管理及 System 共享资源的 `knowledge.ts` 提供 `workspace/knowledge/paragraph.ts` 维护普通 Workspace 文档分段接口,前缀为 `/workspace//knowledge//document//paragraph`。 `getParagraphList` 查询完整分段列表,支持 `title`、`content`,服务端按 `position`、创建时间排序; -`postParagraph` 提交 `title`、`content`、`is_active`,返回新增分段,默认插入首位并触发索引。 +`postParagraph` 提交 `title`、`content`、`is_active` 和可选的 `problem_list: [{ content }]`, +返回新增分段详情,默认插入首位并触发索引。 +`getParagraphDetail` 查询 `/`,返回 `ParagraphDetail`,包含 `problem_list`、 +`hit_num` 和 `last_hit_time`。`putParagraph` 向同一路径提交标题和正文,解包后端三元素编辑响应的 +首项为最新详情;不提交 `problem_list`,关联关系通过专属接口维护。 +`postParagraphProblem` 向 `//problem` 提交 `{ content }`,创建或复用问题并关联分段; +`putUnassociateParagraphProblem` PUT 到 `/unassociation`,以查询参数传递 `paragraph_id`、 +`problem_id`,不传请求体,仅解除当前分段的关联。 +`putMigrateParagraphs` 向分段前缀下的 `/migrate/knowledge//document/` +提交 PUT `{ id_list }`,将所选分段迁移到目标文档;目标不能为当前文档。 +`putGenerateParagraphQuestions` 向分段前缀下的 `/batch_generate_related` 提交 PUT +`ParagraphGeneratePayload`,包含生成配置与 `paragraph_id_list`,不包含 `state_list`。 +`putBatchDeleteParagraphs` 向分段前缀下的 `/batch_delete` 提交 PUT `{ id_list }`, +删除所选分段并由服务端清理关联问题、映射及索引。 响应及载荷类型维护在 `types/paragraph.ts`,通过 `@/api/types` 导入。 标题最多 256 字符,内容必填且最多 102400 字符;loading、弹窗和成功后刷新由页面维护。 本次只接入普通 Workspace,不为其他范围推测接口或回退 Workspace。 @@ -643,7 +656,7 @@ Workspace、System 资源管理及 System 共享资源的 `knowledge.ts` 提供 `DocumentTaskState` 和 `DocumentTaskType` 从文档枚举派生,统一从 `@/api/types` 导入。 启用状态传布尔值,`false` 不省略;单选全部时省略该字段。`tags` 传数组,沿用 Axios 的 `tags[]` 序列化,内容为标签 ID 或特殊值 `NO_TAG`,不传标签名称或 JSON 字符串。 -`workspace/knowledge/knowledge.ts` 和 `workspace/shared/knowledge/knowledge.ts` 的 +`workspace/knowledge/tags.ts` 和 `workspace/shared/knowledge/tags.ts` 的 `getKnowledgeTags(knowledgeId)` 分别请求对应资源前缀的 `//tags`,返回 `KnowledgeTagGroup[]`;页面将分组转换为级联选项,MkTableFilter 内部展开父组并去重,页面直接用组件返回的叶子标签 ID 数组查询。 文档页传 `resource_type: 'document'`,创建者选项复用 Workspace `common.ts` 的 `getAllUsers`。 @@ -651,9 +664,9 @@ Workspace、System 资源管理及 System 共享资源的 `knowledge.ts` 提供 ### 知识库标签与文档关联 -`workspace/knowledge/tags.ts` 维护标签创建、编辑和删除,前缀为 +`workspace/knowledge/tags.ts` 维护标签查询、创建、编辑和删除,前缀为 `/workspace//knowledge//tags`,工作空间由 `getWorkspaceId()` 读取。 -标签查询暂保留在 `workspace/knowledge/knowledge.ts`,`getKnowledgeTags(knowledgeId)` 返回非分页 `KnowledgeTagGroup[]`; +`getKnowledgeTags(knowledgeId)` 返回非分页 `KnowledgeTagGroup[]`; 标签值中的可选 `doc_count` 表示关联文档数量。`postKnowledgeTags` 直接提交 `KnowledgeTagPayload[]`(`key`、`value`),用于创建标签和新增标签值; `putKnowledgeTag` 向 `/` 提交完整 `KnowledgeTagUpdatePayload`(`id`、`key`、`value`), @@ -692,6 +705,10 @@ Workspace、System 资源管理及 System 共享资源的 `knowledge.ts` 提供 共享与普通知识库文档查询统一使用 `ParamsPage`、`ResponsePage` 和 `Dict`, 不传 loading,不保留 v2 的 `Result` 或下划线分页参数。两个文件各自默认导出 API 对象。 +`workspace/shared/knowledge/tags.ts` 提供只读的 `getKnowledgeTags(knowledgeId)`, +请求 `/system/shared/workspace//knowledge//tags`,返回 `KnowledgeTagGroup[]`。 +与普通工作空间标签 API 同时使用时,分别导入为 `SharedTagsApi` 与 `TagsApi`。 + 共享知识库 `getKnowledgeDetail(knowledgeId)` 请求知识库资源 `/`,返回 `KnowledgeDetail`。 Workspace 共享知识库详情由 `resourceScope: 'workspace-shared'` 选择上述完整共享 API 对象; @@ -715,7 +732,10 @@ Workspace 共享知识库详情由 `resourceScope: 'workspace-shared'` 选择上 日志业务类型经 `@/api/types` 导出,来源枚举经 `@/api/enums` 导出,loading 由调用方维护。 清除策略通过 PUT `batch_clean_time` 提交当前智能体的单元素 `id_list`、`clean_time`、 `file_clean_time`,避免调用通用应用编辑流程;成功后页面刷新应用详情。 -聊天记录、标注、添加知识库接口保留在同一 API 文件,尚未接入本次日志列表页面。 +添加知识库通过 POST `//add_knowledge` 提交 `ChatLogAddKnowledgePayload` +(`knowledge_id`、`document_id`、`chat_ids`),将所选对话的问答写入目标文档。 +目标文档选项通过 `workspace/knowledge/document.ts` 的 `getAllDocuments(knowledgeId)` +请求不分页的文档列表。聊天记录与标注接口保留在同一 API 文件,尚未接入日志详情正文。 Web 知识库创建的 `WebKnowledgeCreatePayload.doc_strategy` 使用公共 `DocumentStrategy` 类型, 包含 `split`、`visual` 和 `index`,字段与后端文档处理策略协议一致。 diff --git a/ui/src/api/admin/workspace/application/chat-log.ts b/ui/src/api/admin/workspace/application/chat-log.ts index 4f10ce11eac..b877a8a49a9 100644 --- a/ui/src/api/admin/workspace/application/chat-log.ts +++ b/ui/src/api/admin/workspace/application/chat-log.ts @@ -1,6 +1,6 @@ import { del, get, post, postExportExcel, put } from '../../core/request' import type { ParamsPage, ResponsePage } from '../../core/types' -import type { ChatLog, Dict } from '@/api/types' +import type { ChatLog, ChatLogAddKnowledgePayload, Dict } from '@/api/types' import { getWorkspaceId } from '@/utils/resource-context' const getPrefix = () => `/workspace/${getWorkspaceId()}/application` @@ -22,7 +22,8 @@ const putChatLogCleanTime = (applicationId: string, cleanTime: number, fileClean }) /** 将对话记录添加至知识库。 */ -const postChatLogAddKnowledge = (applicationId: string, data: Dict) => post(`${getPrefix()}/${applicationId}/add_knowledge`, data) +const postChatLogAddKnowledge = (applicationId: string, data: ChatLogAddKnowledgePayload) => + post(`${getPrefix()}/${applicationId}/add_knowledge`, data) /** 分页获取对话中的聊天记录。 */ const getChatRecordLog = (applicationId: string, chatId: string, page: ParamsPage, orderAsc = true) => diff --git a/ui/src/api/admin/workspace/knowledge/document.ts b/ui/src/api/admin/workspace/knowledge/document.ts index 09b4223a007..a54d4178b8a 100644 --- a/ui/src/api/admin/workspace/knowledge/document.ts +++ b/ui/src/api/admin/workspace/knowledge/document.ts @@ -22,6 +22,9 @@ import { getWorkspaceId } from '@/utils/resource-context' const getPrefix = (knowledgeId: string) => `/workspace/${getWorkspaceId()}/knowledge/${knowledgeId}/document` +/** 获取知识库不分页的文档选项。 */ +const getAllDocuments = (knowledgeId: string) => get(getPrefix(knowledgeId)) + /** 获取文档分页列表,支持名称和创建者筛选。 */ const getDocumentPage = (knowledgeId: string, page: ParamsPage, query?: Dict) => get>(`${getPrefix(knowledgeId)}/${page.currentPage}/${page.pageSize}`, query) @@ -178,6 +181,7 @@ const putUnlinkTagDocuments = (knowledgeId: string, tagId: string, documentIds: put(`/workspace/${getWorkspaceId()}/knowledge/${knowledgeId}/tag/${tagId}/docs_delete`, { id_list: documentIds }) export default { + getAllDocuments, getDocumentDetail, getDocumentTags, postAddDocumentTags, diff --git a/ui/src/api/admin/workspace/knowledge/knowledge.ts b/ui/src/api/admin/workspace/knowledge/knowledge.ts index a7fa8630890..1cf1faaab98 100644 --- a/ui/src/api/admin/workspace/knowledge/knowledge.ts +++ b/ui/src/api/admin/workspace/knowledge/knowledge.ts @@ -3,7 +3,6 @@ import type LogicFlow from '@logicflow/core' import type { ParamsPage, ResponsePage } from '../../core/types' import type { Dict, - KnowledgeTagGroup, KnowledgeDetail, KnowledgeItem, KnowledgeGeneratePayload, @@ -89,7 +88,7 @@ const putBatchDeleteKnowledge = (knowledgeIds: string[]) => { return put<{ id_list: string[] }, boolean>(`${getPrefix()}/batch_delete`, { id_list: knowledgeIds }) } -/** 批量转移工作空间知识库。 */ +/** 批量移动工作空间知识库。 */ const putBatchMoveKnowledge = (knowledgeIds: string[], folderId: string) => { return put<{ id_list: string[]; folder_id: string }, boolean>(`${getPrefix()}/batch_move`, { id_list: knowledgeIds, folder_id: folderId }) } @@ -130,13 +129,7 @@ const putKnowledgeKeywordIndex = (knowledgeId: string) => put(` const postTransformWorkflow = (knowledgeId: string, payload: { work_flow: LogicFlow.GraphConfigData }) => post<{ work_flow: LogicFlow.GraphConfigData }, boolean>(`${getPrefix()}/${knowledgeId}/transform_workflow`, payload) -/** 获取知识库按标签名称分组的标签选项。 */ - -// TODO -const getKnowledgeTags = (knowledgeId: string) => get(`${getPrefix()}/${knowledgeId}/tags`) - export default { - getKnowledgeTags, getKnowledgeMcpConfig, putKnowledgeKeywordIndex, exportKnowledgeExcel, diff --git a/ui/src/api/admin/workspace/knowledge/paragraph.ts b/ui/src/api/admin/workspace/knowledge/paragraph.ts index a3de2304e5f..513fe4c39f7 100644 --- a/ui/src/api/admin/workspace/knowledge/paragraph.ts +++ b/ui/src/api/admin/workspace/knowledge/paragraph.ts @@ -1,5 +1,13 @@ -import { get, post } from '../../core/request' -import type { ParagraphCreatePayload, ParagraphItem, ParagraphQuery } from '@/api/types' +import { get, post, put } from '../../core/request' +import type { + ParagraphCreatePayload, + ParagraphDetail, + ParagraphGeneratePayload, + ParagraphItem, + ParagraphProblem, + ParagraphQuery, + ParagraphUpdatePayload, +} from '@/api/types' import { getWorkspaceId } from '@/utils/resource-context' const getPrefix = (knowledgeId: string, documentId: string) => @@ -11,6 +19,49 @@ const getParagraphList = (knowledgeId: string, documentId: string, query?: Parag /** 在文档首位新增分段,由服务端触发索引。 */ const postParagraph = (knowledgeId: string, documentId: string, payload: ParagraphCreatePayload) => - post(getPrefix(knowledgeId, documentId), payload) + post(getPrefix(knowledgeId, documentId), payload) -export default { getParagraphList, postParagraph } +/** 查询分段正文、召回统计及关联问题。 */ +const getParagraphDetail = (knowledgeId: string, documentId: string, paragraphId: string) => + get(`${getPrefix(knowledgeId, documentId)}/${paragraphId}`) + +/** 保存分段标题和内容,提取后端编辑响应中的最新详情。 */ +const putParagraph = (knowledgeId: string, documentId: string, paragraphId: string, payload: ParagraphUpdatePayload) => + put( + `${getPrefix(knowledgeId, documentId)}/${paragraphId}`, + payload, + ).then(([paragraph]) => paragraph) + +/** 新增问题并关联到当前分段。 */ +const postParagraphProblem = (knowledgeId: string, documentId: string, paragraphId: string, content: string) => + post<{ content: string }, ParagraphProblem>(`${getPrefix(knowledgeId, documentId)}/${paragraphId}/problem`, { content }) + +/** 解除当前分段的问题关联,保留问题及其他分段的关联。 */ +const putUnassociateParagraphProblem = (knowledgeId: string, documentId: string, paragraphId: string, problemId: string) => + put(`${getPrefix(knowledgeId, documentId)}/unassociation`, undefined, { paragraph_id: paragraphId, problem_id: problemId }) + +/** 批量/单个将所选分段批量迁移至目标知识库的文档。 */ +const putMigrateParagraphs = (knowledgeId: string, documentId: string, targetKnowledgeId: string, targetDocumentId: string, paragraphIds: string[]) => + put<{ id_list: string[] }, boolean>(`${getPrefix(knowledgeId, documentId)}/migrate/knowledge/${targetKnowledgeId}/document/${targetDocumentId}`, { + id_list: paragraphIds, + }) + +/** 批量/单个为所选分段提交关联问题生成任务。 */ +const putGenerateParagraphQuestions = (knowledgeId: string, documentId: string, payload: ParagraphGeneratePayload) => + put(`${getPrefix(knowledgeId, documentId)}/batch_generate_related`, payload) + +/** 批量删除当前文档中所选的分段。 */ +const putBatchDeleteParagraphs = (knowledgeId: string, documentId: string, paragraphIds: string[]) => + put<{ id_list: string[] }, boolean>(`${getPrefix(knowledgeId, documentId)}/batch_delete`, { id_list: paragraphIds }) + +export default { + getParagraphList, + postParagraph, + getParagraphDetail, + putParagraph, + postParagraphProblem, + putUnassociateParagraphProblem, + putMigrateParagraphs, + putGenerateParagraphQuestions, + putBatchDeleteParagraphs, +} diff --git a/ui/src/api/admin/workspace/knowledge/tags.ts b/ui/src/api/admin/workspace/knowledge/tags.ts index 3a0e8689dce..23a0694cf61 100644 --- a/ui/src/api/admin/workspace/knowledge/tags.ts +++ b/ui/src/api/admin/workspace/knowledge/tags.ts @@ -1,9 +1,12 @@ -import { del, getExportFile, post, put } from '../../core/request' -import type { KnowledgeTagPayload, KnowledgeTagUpdatePayload } from '@/api/types' +import { del, get, getExportFile, post, put } from '../../core/request' +import type { KnowledgeTagGroup, KnowledgeTagPayload, KnowledgeTagUpdatePayload } from '@/api/types' import { getWorkspaceId } from '@/utils/resource-context' const getPrefix = (knowledgeId: string) => `/workspace/${getWorkspaceId()}/knowledge/${knowledgeId}/tags` +/** 获取知识库按标签名称分组的标签选项。 */ +const getKnowledgeTags = (knowledgeId: string) => get(getPrefix(knowledgeId)) + /** 创建知识库标签或为已有标签新增值。 */ const postKnowledgeTags = (knowledgeId: string, tags: KnowledgeTagPayload[]) => post(getPrefix(knowledgeId), tags) @@ -29,6 +32,7 @@ const postImportKnowledgeTags = (knowledgeId: string, file: File) => { const exportKnowledgeTagTemplate = (knowledgeId: string) => getExportFile('标签模板.xlsx', `${getPrefix(knowledgeId)}/template/export`) export default { + getKnowledgeTags, postKnowledgeTags, putKnowledgeTag, deleteKnowledgeTag, diff --git a/ui/src/api/admin/workspace/shared/knowledge/knowledge.ts b/ui/src/api/admin/workspace/shared/knowledge/knowledge.ts index acee1cd1679..c74ec55a775 100644 --- a/ui/src/api/admin/workspace/shared/knowledge/knowledge.ts +++ b/ui/src/api/admin/workspace/shared/knowledge/knowledge.ts @@ -1,6 +1,6 @@ import { get } from '../../../core/request' import type { ParamsPage, ResponsePage } from '../../../core/types' -import type { Dict, KnowledgeTagGroup, KnowledgeDetail, KnowledgeItem } from '@/api/types' +import type { Dict, KnowledgeDetail, KnowledgeItem } from '@/api/types' import { getWorkspaceId } from '@/utils/resource-context' const getPrefix = () => `/system/shared/workspace/${getWorkspaceId()}/knowledge` @@ -15,7 +15,4 @@ const getAllKnowledge = (query?: Dict) => get(getPrefi /** 获取工作空间共享的知识库详情。 */ const getKnowledgeDetail = (knowledgeId: string) => get(`${getPrefix()}/${knowledgeId}`) -/** 获取知识库按标签名称分组的标签选项。 */ -const getKnowledgeTags = (knowledgeId: string) => get(`${getPrefix()}/${knowledgeId}/tags`) - -export default { getKnowledgeTags, getKnowledgePage, getAllKnowledge, getKnowledgeDetail } +export default { getKnowledgePage, getAllKnowledge, getKnowledgeDetail } diff --git a/ui/src/api/admin/workspace/shared/knowledge/tags.ts b/ui/src/api/admin/workspace/shared/knowledge/tags.ts new file mode 100644 index 00000000000..188b850ac35 --- /dev/null +++ b/ui/src/api/admin/workspace/shared/knowledge/tags.ts @@ -0,0 +1,10 @@ +import { get } from '../../../core/request' +import type { KnowledgeTagGroup } from '@/api/types' +import { getWorkspaceId } from '@/utils/resource-context' + +const getPrefix = (knowledgeId: string) => `/system/shared/workspace/${getWorkspaceId()}/knowledge/${knowledgeId}/tags` + +/** 获取工作空间共享知识库按标签名称分组的标签选项。 */ +const getKnowledgeTags = (knowledgeId: string) => get(getPrefix(knowledgeId)) + +export default { getKnowledgeTags } diff --git a/ui/src/api/types/chat-log.ts b/ui/src/api/types/chat-log.ts index 0bb7d175592..2e5585fb9cc 100644 --- a/ui/src/api/types/chat-log.ts +++ b/ui/src/api/types/chat-log.ts @@ -2,6 +2,13 @@ import type { CHAT_LOG_SOURCE } from '@/api/enums' export type ChatLogSource = (typeof CHAT_LOG_SOURCE)[keyof typeof CHAT_LOG_SOURCE] +/** 将所选对话的问答添加至目标文档。 */ +export interface ChatLogAddKnowledgePayload { + knowledge_id: string + document_id: string + chat_ids: string[] +} + /** 智能体对话日志列表记录。 */ export interface ChatLog { id: string diff --git a/ui/src/api/types/paragraph.ts b/ui/src/api/types/paragraph.ts index 95428b62771..df0a6c46425 100644 --- a/ui/src/api/types/paragraph.ts +++ b/ui/src/api/types/paragraph.ts @@ -1,3 +1,5 @@ +import type { RelatedQuestionsConfig } from './knowledge' + /** 文档分段的查询响应与新增载荷。 */ export interface ParagraphItem { id: string @@ -8,6 +10,23 @@ export interface ParagraphItem { is_active: boolean create_time: string update_time: string + hit_num: number + last_hit_time: string | null +} + +/** 分段关联的问题及详情。 */ +export interface ParagraphProblem { + id: string + content: string +} + +export interface ParagraphDetail extends ParagraphItem { + problem_list: ParagraphProblem[] +} + +export interface ParagraphUpdatePayload { + title: string + content: string } export interface ParagraphQuery { @@ -19,4 +38,10 @@ export interface ParagraphCreatePayload { title: string content: string is_active: boolean + problem_list?: { content: string }[] +} + +/** 为选中的分段生成关联问题。 */ +export interface ParagraphGeneratePayload extends RelatedQuestionsConfig { + paragraph_id_list: string[] } diff --git a/ui/src/components/COMPONENT_README.md b/ui/src/components/COMPONENT_README.md index aae6529931d..29a485bb6a8 100644 --- a/ui/src/components/COMPONENT_README.md +++ b/ui/src/components/COMPONENT_README.md @@ -319,6 +319,11 @@ Element Plus 的 `v-infinite-scroll`。组件通过 `v-model` 管理已经加载 `paginationConfig` 由组件接收,其余 Table 属性和事件通过 `$attrs` 传入,列继续使用 `el-table-column`。 +`row-click(row, column, event)` 由组件统一转发,保持 Element Plus 的参数。 +与 `MkEditName` 配合时,组件在按下阶段识别当前表格内正在编辑的名称输入框; +点击空白使名称失焦保存的同一次点击不发出 `row-click`,下一次正常点击继续转发。 +不阻止失焦、勾选和按钮交互,业务页面无需绑定 `pointerdown` 或维护编辑判断。 + `body-prepend` 插槽用于在表头下、数据行之前插入独立操作区,例如快速创建。内部借用 Element Plus `append`,仅在传入该插槽时将直属表体滚动容器设为纵向 Flex,并将插槽排到前面; 内容自然占位,不写固定高度,不向 `data` 插入占位记录,不影响选择、排序、分页总数和空状态。 @@ -460,7 +465,9 @@ Dialog、Drawer、Popover、嵌套区域等其他大、小表格均禁止开启 `footer-batch-actions` 插槽,当前选择通过 `selection-change` 返回。组件暴露 `tableRef` 和 `clearSelection()`。操作栏与 `MkViewLayout` 复用 `LayoutBatchFooter`,统一全选、半选、数量和 取消行为;它在主内容滚动区域内吸附于页面底部,不随表格内容滚出可视区域。 -分页表格暂不支持跨页勾选,翻页或切换每页条数时统一清空选择,选择列不配置 `reserve-selection`。 +分页表格暂不支持跨页勾选,翻页或切换每页条数时统一清空选择。 +有轮询刷新的表格选择列配置 `reserve-selection`,按 `row-key` 保留同一页刷新后的勾选; +其他分页表格不配置该属性,不自行实现轮询选择恢复。 非分页表格不受此限制,可按数据刷新、搜索和懒加载需求保留选择。 `selectionGroupKey` 可按需开启同组选择,接受字段路径或返回字符串/数字的函数;不传时保持 @@ -564,6 +571,8 @@ Dialog、Drawer、Popover、嵌套区域等其他大、小表格均禁止开启 业务错误文案并通过消息提示,返回 `undefined` 表示通过。名称未变化直接退出,不请求。 保存期间输入框只读,失败保留草稿,接口错误由请求层提示,允许重新聚焦后修改、重试或取消。 名称展示区域保留父级点击行为,编辑按钮和输入区域阻止点击冒泡。 +编辑期间根节点自动设置内部标记 `data-mk-edit-name-editing`,供 `MkTable` 识别编辑焦点; +退出编辑时移除,调用方无需传入标记或编辑状态。 ```vue