diff --git a/ui/src/api/API_README.md b/ui/src/api/API_README.md index aa73e90d0cc..32573d9b978 100644 --- a/ui/src/api/API_README.md +++ b/ui/src/api/API_README.md @@ -541,7 +541,7 @@ Workspace 共享 Paragraph API 仅 getParagraphPage、getParagraphDetail,不 Workspace、System 资源管理、System 共享提供完整问题 API: `postProblems` 直接提交内容字符串数组,`putProblem` 提交 `{ content }`,单项 DELETE 使用问题 ID, `putBatchDeleteProblems` 直接提交问题 ID 数组;单个问题内容最多 256 字符。 -`getProblemParagraphs` 返回 `ProblemParagraph[]`,包含分段字段及 knowledge_id、document_name。 +`getProblemDetail` 返回 `ProblemParagraph[]`,包含分段字段及 knowledge_id、document_name。 取消关联复用 Paragraph API 的 `putUnassociateParagraphProblem`,不调用问题或分段删除接口。 Workspace 共享仅有 `getProblemsPage`,不补造详情或写接口,不回退其他范围。 diff --git a/ui/src/api/admin/system/resource-management/knowledge/problem.ts b/ui/src/api/admin/system/resource-management/knowledge/problem.ts index bf2e3f7c109..f558fc797dc 100644 --- a/ui/src/api/admin/system/resource-management/knowledge/problem.ts +++ b/ui/src/api/admin/system/resource-management/knowledge/problem.ts @@ -18,8 +18,8 @@ const putProblem = (knowledgeId: string, problemId: string, content: string) => /** 删除单个知识库问题。 */ const deleteProblem = (knowledgeId: string, problemId: string) => del(`${getPrefix(knowledgeId)}/${problemId}`) -/** 获取问题当前关联的文档分段。 */ -const getProblemParagraphs = (knowledgeId: string, problemId: string) => get(`${getPrefix(knowledgeId)}/${problemId}/paragraph`) +/** 获取问题详情,返回当前关联的文档分段。 */ +const getProblemDetail = (knowledgeId: string, problemId: string) => get(`${getPrefix(knowledgeId)}/${problemId}/paragraph`) /** 批量将问题关联到指定文档分段。 */ const putBatchAssociateProblems = (knowledgeId: string, payload: ProblemBatchAssociationPayload) => @@ -34,7 +34,7 @@ export default { getProblemsPage, putProblem, deleteProblem, - getProblemParagraphs, + getProblemDetail, putBatchAssociateProblems, putBatchDeleteProblems, } diff --git a/ui/src/api/admin/system/shared-resources/knowledge/problem.ts b/ui/src/api/admin/system/shared-resources/knowledge/problem.ts index 296822d727d..f2ebfc09c5d 100644 --- a/ui/src/api/admin/system/shared-resources/knowledge/problem.ts +++ b/ui/src/api/admin/system/shared-resources/knowledge/problem.ts @@ -18,8 +18,8 @@ const putProblem = (knowledgeId: string, problemId: string, content: string) => /** 删除单个知识库问题。 */ const deleteProblem = (knowledgeId: string, problemId: string) => del(`${getPrefix(knowledgeId)}/${problemId}`) -/** 获取问题当前关联的文档分段。 */ -const getProblemParagraphs = (knowledgeId: string, problemId: string) => get(`${getPrefix(knowledgeId)}/${problemId}/paragraph`) +/** 获取问题详情,返回当前关联的文档分段。 */ +const getProblemDetail = (knowledgeId: string, problemId: string) => get(`${getPrefix(knowledgeId)}/${problemId}/paragraph`) /** 批量将问题关联到指定文档分段。 */ const putBatchAssociateProblems = (knowledgeId: string, payload: ProblemBatchAssociationPayload) => @@ -34,7 +34,7 @@ export default { getProblemsPage, putProblem, deleteProblem, - getProblemParagraphs, + getProblemDetail, putBatchAssociateProblems, putBatchDeleteProblems, } diff --git a/ui/src/api/admin/workspace/knowledge/problem.ts b/ui/src/api/admin/workspace/knowledge/problem.ts index 7dc6a08c812..d85890bf069 100644 --- a/ui/src/api/admin/workspace/knowledge/problem.ts +++ b/ui/src/api/admin/workspace/knowledge/problem.ts @@ -19,8 +19,8 @@ const putProblem = (knowledgeId: string, problemId: string, content: string) => /** 删除单个知识库问题。 */ const deleteProblem = (knowledgeId: string, problemId: string) => del(`${getPrefix(knowledgeId)}/${problemId}`) -/** 获取问题当前关联的文档分段。 */ -const getProblemParagraphs = (knowledgeId: string, problemId: string) => get(`${getPrefix(knowledgeId)}/${problemId}/paragraph`) +/** 获取问题详情,返回当前关联的文档分段。 */ +const getProblemDetail = (knowledgeId: string, problemId: string) => get(`${getPrefix(knowledgeId)}/${problemId}/paragraph`) /** 批量将问题关联到指定文档分段。 */ const putBatchAssociateProblems = (knowledgeId: string, payload: ProblemBatchAssociationPayload) => @@ -35,7 +35,7 @@ export default { getProblemsPage, putProblem, deleteProblem, - getProblemParagraphs, + getProblemDetail, putBatchAssociateProblems, putBatchDeleteProblems, } diff --git a/ui/src/router/admin/system/modules/knowledge-system-resource.ts b/ui/src/router/admin/system/modules/knowledge-system-resource.ts index fd903fcb4dd..9d98a96b615 100644 --- a/ui/src/router/admin/system/modules/knowledge-system-resource.ts +++ b/ui/src/router/admin/system/modules/knowledge-system-resource.ts @@ -65,9 +65,9 @@ export const systemResourceKnowledgeRoutes: RouteRecordRaw[] = [ meta: { title: '召回测试', order: 10 }, }, { - path: 'question', - name: 'system-resource-knowledge-question', - component: () => import('@/views/knowledge-detail/question/index.vue'), + path: 'problem', + name: 'system-resource-knowledge-problem', + component: () => import('@/views/knowledge-detail/problem/index.vue'), meta: { title: '问题', order: 20 }, }, { diff --git a/ui/src/router/admin/system/modules/knowledge-system-shared.ts b/ui/src/router/admin/system/modules/knowledge-system-shared.ts index 2575cada38f..0c379a62efe 100644 --- a/ui/src/router/admin/system/modules/knowledge-system-shared.ts +++ b/ui/src/router/admin/system/modules/knowledge-system-shared.ts @@ -65,9 +65,9 @@ export const systemSharedKnowledgeRoutes: RouteRecordRaw[] = [ meta: { title: '召回测试', order: 10 }, }, { - path: 'question', - name: 'system-shared-knowledge-question', - component: () => import('@/views/knowledge-detail/question/index.vue'), + path: 'problem', + name: 'system-shared-knowledge-problem', + component: () => import('@/views/knowledge-detail/problem/index.vue'), meta: { title: '问题', order: 20 }, }, { diff --git a/ui/src/router/admin/workspace/modules/knowledge-shared.ts b/ui/src/router/admin/workspace/modules/knowledge-shared.ts index 89ffbc2456e..b8413f09af2 100644 --- a/ui/src/router/admin/workspace/modules/knowledge-shared.ts +++ b/ui/src/router/admin/workspace/modules/knowledge-shared.ts @@ -65,9 +65,9 @@ export const sharedKnowledgeRoutes: RouteRecordRaw[] = [ meta: { title: '召回测试', order: 10 }, }, { - path: 'question', - name: 'workspace-shared-knowledge-question', - component: () => import('@/views/knowledge-detail/question/index.vue'), + path: 'problem', + name: 'workspace-shared-knowledge-problem', + component: () => import('@/views/knowledge-detail/problem/index.vue'), meta: { title: '问题', order: 20 }, }, { diff --git a/ui/src/router/admin/workspace/modules/knowledge.ts b/ui/src/router/admin/workspace/modules/knowledge.ts index 7e2ab0bba85..93b2d4b5147 100644 --- a/ui/src/router/admin/workspace/modules/knowledge.ts +++ b/ui/src/router/admin/workspace/modules/knowledge.ts @@ -65,7 +65,7 @@ export const knowledgeRoutes: RouteRecordRaw[] = [ meta: { title: '工作流', icon: 'icon_ticket-flow_outlined', order: 20 }, }, { - path: 'retrieval', + path: '', name: 'workspace-knowledge-retrieval', redirect: { name: 'workspace-knowledge-hit-test' }, meta: { title: '检索优化', icon: 'icon_trace_outlined', order: 30 }, @@ -77,9 +77,9 @@ export const knowledgeRoutes: RouteRecordRaw[] = [ meta: { title: '召回测试', order: 10 }, }, { - path: 'question', - name: 'workspace-knowledge-question', - component: () => import('@/views/knowledge-detail/question/index.vue'), + path: 'problem', + name: 'workspace-knowledge-problem', + component: () => import('@/views/knowledge-detail/problem/index.vue'), meta: { title: '问题', order: 20 }, }, { @@ -91,7 +91,7 @@ export const knowledgeRoutes: RouteRecordRaw[] = [ ], }, { - path: 'integration', + path: '', name: 'workspace-knowledge-integration', redirect: { name: 'workspace-knowledge-chat-user' }, meta: { title: '授权与集成', icon: 'icon_personal-privacy_outlined', order: 40 }, diff --git a/ui/src/views/document-detail/index.vue b/ui/src/views/document-detail/index.vue index 5845fc52dcd..41b2cf453ca 100644 --- a/ui/src/views/document-detail/index.vue +++ b/ui/src/views/document-detail/index.vue @@ -420,8 +420,6 @@ onMounted(() => { -

{{ paragraph.title || '-' }}

- { @change="(selected: boolean | string | number) => handleSelectBatchParagraph(paragraph.id, Boolean(selected))" /> +

{{ paragraph.title || '-' }}

{{ paragraph.content.length }} 字符

diff --git a/ui/src/views/knowledge-detail/question/components/AssociateProblemParagraphDialog.vue b/ui/src/views/knowledge-detail/problem/components/AssociateParagraphDialog.vue similarity index 89% rename from ui/src/views/knowledge-detail/question/components/AssociateProblemParagraphDialog.vue rename to ui/src/views/knowledge-detail/problem/components/AssociateParagraphDialog.vue index 7d9edb45e1f..9063d0f9e13 100644 --- a/ui/src/views/knowledge-detail/question/components/AssociateProblemParagraphDialog.vue +++ b/ui/src/views/knowledge-detail/problem/components/AssociateParagraphDialog.vue @@ -4,14 +4,14 @@ import type MkViewLayout from '@/components/global/mk-view-layout/index.vue' import MkSearchList from '@/components/mk-search-list/index.vue' import type { ParamsPage } from '@/api/admin/core/types' import { DOCUMENT_RESOURCE_TYPE } from '@/api/enums' -import type { DocumentItem, DocumentResourceType, ParagraphItem, ProblemParagraph, ProblemParagraphReference } from '@/api/types' +import type { DocumentItem, DocumentResourceType, ParagraphItem, ProblemParagraphReference } from '@/api/types' import { getFileUrl } from '@/utils/common' import { getFileIconUrl } from '@/utils/icon' import { MsgSuccess } from '@/utils/message' import { useKnowledgeDetailContext } from '@/views/knowledge-detail/context' import ParagraphDialog from '@/views/document-detail/paragraph-dialog/ParagraphDialog.vue' -defineOptions({ name: 'AssociateProblemParagraphDialog' }) +defineOptions({ name: 'AssociateParagraphDialog' }) const emit = defineEmits<{ success: [] }>() const { knowledgeId, resourceApi } = useKnowledgeDetailContext({ resourceScopes: ['workspace', 'system-resource', 'system-shared'] as const }) @@ -19,7 +19,7 @@ const visible = ref(false) const documentLoading = ref(false) const operationLoading = ref(false) const problemIds = ref([]) -const documents = ref([]) +const documentData = ref([]) const resourceType = ref(DOCUMENT_RESOURCE_TYPE.DOCUMENT) const documentSearchText = ref('') const selectedDocumentId = ref('') @@ -32,7 +32,7 @@ const paragraphLayoutRef = useTemplateRef>('pa const paragraphDialogRef = useTemplateRef>('paragraphDialogRef') const isBatchAssociation = computed(() => problemIds.value.length > 1) -const selectedDocument = computed(() => documents.value.find(({ id }) => id === selectedDocumentId.value)) +const selectedDocument = computed(() => documentData.value.find(({ id }) => id === selectedDocumentId.value)) const selectedParagraphIds = computed(() => new Set(selectedParagraphs.value.map(({ paragraph_id }) => paragraph_id))) function getSelectedCount(documentId: string) { @@ -45,14 +45,14 @@ function isSelected(paragraphId: string) { function loadDocuments() { paragraphLayoutRef.value?.setScrollTop(0) - documents.value = [] + documentData.value = [] selectedDocumentId.value = '' documentSearchText.value = '' paragraphSearchText.value = '' paragraphs.value = [] - return resourceApi.document.getAllDocuments(knowledgeId.value, { resource_type: resourceType.value }).then((documentList) => { - documents.value = documentList - selectedDocumentId.value = documentList[0]?.id ?? '' + return resourceApi.document.getAllDocuments(knowledgeId.value, { resource_type: resourceType.value }).then((documentRecords) => { + documentData.value = documentRecords + selectedDocumentId.value = documentRecords[0]?.id ?? '' }) } @@ -152,34 +152,21 @@ function handleParagraphDialogClosed() { const problemId = problemIds.value[0] if (isBatchAssociation.value || !problemId) return // 分段详情可修改问题关联,关闭后重新读取当前问题的关联状态。 - void resourceApi.problem.getProblemParagraphs(knowledgeId.value, problemId).then((associatedParagraphs) => { + void resourceApi.problem.getProblemDetail(knowledgeId.value, problemId).then((associatedParagraphs) => { selectedParagraphs.value = associatedParagraphs.map(({ id, document_id }) => ({ paragraph_id: id, document_id })) }) } -function handleClosed() { - problemIds.value = [] - documents.value = [] - documentSearchText.value = '' - selectedDocumentId.value = '' - paragraphSearchText.value = '' - paragraphs.value = [] - selectedParagraphs.value = [] - detailParagraph.value = undefined -} - function open(targetProblemIds: string[]) { - if (visible.value || operationLoading.value || !targetProblemIds.length) return - const problemId = targetProblemIds[0] - if (!problemId) return + if (visible.value || operationLoading.value || !targetProblemIds[0]) return problemIds.value = [...targetProblemIds] - resourceType.value = DOCUMENT_RESOURCE_TYPE.DOCUMENT visible.value = true documentLoading.value = true - // TODO(图片联调):确认已关联分段查询包含图片分段,并返回 id、document_id,供选中态和关联数量回显。 - const associatedParagraphs = - targetProblemIds.length === 1 ? resourceApi.problem.getProblemParagraphs(knowledgeId.value, problemId) : Promise.resolve([]) - return Promise.all([loadDocuments(), associatedParagraphs]) + return Promise.all([ + loadDocuments(), + // TODO(图片联调):确认已关联分段查询包含图片分段,并返回 id、document_id,供选中态和关联数量回显。 + targetProblemIds.length === 1 ? resourceApi.problem.getProblemDetail(knowledgeId.value, targetProblemIds[0]) : [], + ]) .then(([, problemParagraphs]) => { selectedParagraphs.value = problemParagraphs.map(({ id, document_id }) => ({ paragraph_id: id, document_id })) }) @@ -191,6 +178,18 @@ function open(targetProblemIds: string[]) { }) } +function handleClosed() { + problemIds.value = [] + documentData.value = [] + documentSearchText.value = '' + selectedDocumentId.value = '' + paragraphSearchText.value = '' + paragraphs.value = [] + selectedParagraphs.value = [] + detailParagraph.value = undefined + resourceType.value = DOCUMENT_RESOURCE_TYPE.DOCUMENT +} + defineExpose({ open }) @@ -215,7 +214,7 @@ defineExpose({ open }) -

{{ paragraph.title || '-' }}

-

{{ paragraph.content }}

- {{ paragraph.content.length }} 字符 + - + - +

{{ paragraph.title || '-' }}

+ + +

{{ paragraph.content.length }} 字符

diff --git a/ui/src/views/knowledge-detail/question/components/ButtonCreateProblem.vue b/ui/src/views/knowledge-detail/problem/components/ButtonCreateProblem.vue similarity index 100% rename from ui/src/views/knowledge-detail/question/components/ButtonCreateProblem.vue rename to ui/src/views/knowledge-detail/problem/components/ButtonCreateProblem.vue diff --git a/ui/src/views/knowledge-detail/question/components/ProblemDetailDrawer.vue b/ui/src/views/knowledge-detail/problem/components/ProblemDetailDrawer.vue similarity index 93% rename from ui/src/views/knowledge-detail/question/components/ProblemDetailDrawer.vue rename to ui/src/views/knowledge-detail/problem/components/ProblemDetailDrawer.vue index d0039564cdb..a11db64ad10 100644 --- a/ui/src/views/knowledge-detail/question/components/ProblemDetailDrawer.vue +++ b/ui/src/views/knowledge-detail/problem/components/ProblemDetailDrawer.vue @@ -24,7 +24,7 @@ const paragraphDialogRef = ref>() function loadParagraphs() { loadFailed.value = false return ( - resourceApi.problem.getProblemParagraphs?.(knowledgeId.value, problem.value.id).then((records) => { + resourceApi.problem.getProblemDetail?.(knowledgeId.value, problem.value.id).then((records) => { paragraphs.value = records problem.value.paragraph_count = records.length }) ?? Promise.resolve() @@ -114,14 +114,6 @@ watch( diff --git a/ui/src/views/knowledge-detail/question/index.vue b/ui/src/views/knowledge-detail/problem/index.vue similarity index 95% rename from ui/src/views/knowledge-detail/question/index.vue rename to ui/src/views/knowledge-detail/problem/index.vue index 8f43ac784b5..af473d1ca1c 100644 --- a/ui/src/views/knowledge-detail/question/index.vue +++ b/ui/src/views/knowledge-detail/problem/index.vue @@ -10,11 +10,11 @@ import { numberFormat } from '@/utils/number' import { MsgSuccess } from '@/utils/message' import { isWorkspaceSharedResource } from '@/utils/resource-context' import { useKnowledgeDetailContext } from '@/views/knowledge-detail/context' -import AssociateProblemParagraphDialog from './components/AssociateProblemParagraphDialog.vue' +import AssociateParagraphDialog from './components/AssociateParagraphDialog.vue' import ButtonCreateProblem from './components/ButtonCreateProblem.vue' import ProblemDetailDrawer from './components/ProblemDetailDrawer.vue' -defineOptions({ name: 'QuestionListView' }) +defineOptions({ name: 'ProblemListView' }) defineProps() defineExpose({ customHeader: true }) @@ -27,7 +27,7 @@ const paginationConfig = ref({ currentPage: 1, pageSize: 20, total: 0 }) const selectedProblems = ref([]) const problemTableRef = ref<{ clearSelection: () => void }>() const quickCreateRef = ref>() -const associateProblemParagraphDialogRef = ref>() +const associateParagraphDialogRef = ref>() const detailProblem = ref() const currentIndex = computed(() => problems.value.findIndex(({ id }) => id === detailProblem.value?.id)) const hasPrevious = computed(() => currentIndex.value > 0 || (currentIndex.value === 0 && paginationConfig.value.currentPage > 1)) @@ -149,7 +149,7 @@ function handleBatchDeleteProblems() { function handleOpenAssociateParagraphs(problemIds: string[]) { if (operationLoading.value || !problemIds.length) return - associateProblemParagraphDialogRef.value?.open(problemIds) + associateParagraphDialogRef.value?.open(problemIds) } function handleAssociateParagraphsSuccess() { @@ -273,9 +273,5 @@ onMounted(() => loadProblems()) @associate="handleOpenAssociateParagraphs([detailProblem.id])" @closed="detailProblem = undefined" /> - +