From 82d4a3376b58d3fe83d293208b99d5565c3be73a Mon Sep 17 00:00:00 2001 From: wangdan-fit2cloud Date: Sun, 8 Jun 2025 16:43:40 +0800 Subject: [PATCH] feat: paragraph --- ui/src/api/knowledge/knowledge.ts | 168 ++++++++++++++---- .../generate-related-dialog/index.vue | 6 +- ui/src/stores/modules/knowledge.ts | 2 +- ui/src/views/hit-test/index.vue | 2 +- .../knowledge/component/SyncWebDialog.vue | 8 +- .../CreateWebKnowledgeDialog copy.vue | 6 +- .../paragraph/component/ParagraphCard.vue | 13 +- ui/src/views/paragraph/index.vue | 42 ++--- 8 files changed, 165 insertions(+), 82 deletions(-) diff --git a/ui/src/api/knowledge/knowledge.ts b/ui/src/api/knowledge/knowledge.ts index 438ef3fd4..138bd8434 100644 --- a/ui/src/api/knowledge/knowledge.ts +++ b/ui/src/api/knowledge/knowledge.ts @@ -1,8 +1,8 @@ -import {Result} from '@/request/Result' -import {get, post, del, put} from '@/request/index' -import {type Ref} from 'vue' -import type {pageRequest} from '@/api/type/common' -import type {knowledgeData} from '@/api/type/knowledge' +import { Result } from '@/request/Result' +import { get, post, del, put, exportFile, exportExcel } from '@/request/index' +import { type Ref } from 'vue' +import type { pageRequest } from '@/api/type/common' +import type { knowledgeData } from '@/api/type/knowledge' const prefix = '/workspace/' + localStorage.getItem('workspace_id') @@ -14,10 +14,10 @@ const prefix = '/workspace/' + localStorage.getItem('workspace_id') * user_id: string, * desc: string,} */ -const getKnowledgeByFolder: ( - data?: any, - loading?: Ref, -) => Promise>> = (data, loading) => { +const getKnowledgeByFolder: (data?: any, loading?: Ref) => Promise>> = ( + data, + loading, +) => { return get(`${prefix}/knowledge`, data, loading) } @@ -36,11 +36,7 @@ const getKnowledgeList: ( param?: any, loading?: Ref, ) => Promise> = (page, param, loading) => { - return get( - `${prefix}/knowledge/${page.current_page}/${page.page_size}`, - param, - loading, - ) + return get(`${prefix}/knowledge/${page.current_page}/${page.page_size}`, param, loading) } /** @@ -61,12 +57,7 @@ const putSyncWebKnowledge: ( sync_type: string, loading?: Ref, ) => Promise> = (knowledge_id, sync_type, loading) => { - return put( - `${prefix}/knowledge/${knowledge_id}/sync`, - undefined, - {sync_type}, - loading, - ) + return put(`${prefix}/knowledge/${knowledge_id}/sync`, undefined, { sync_type }, loading) } /** @@ -77,22 +68,17 @@ const putReEmbeddingKnowledge: ( knowledge_id: string, loading?: Ref, ) => Promise> = (knowledge_id, loading) => { - return put( - `${prefix}/knowledge/${knowledge_id}/embedding`, - undefined, - undefined, - loading, - ) + return put(`${prefix}/knowledge/${knowledge_id}/embedding`, undefined, undefined, loading) } /** * 知识库详情 * @param 参数 knowledge_id */ -const getKnowledgeDetail: ( - knowledge_id: string, - loading?: Ref, -) => Promise> = (knowledge_id, loading) => { +const getKnowledgeDetail: (knowledge_id: string, loading?: Ref) => Promise> = ( + knowledge_id, + loading, +) => { return get(`${prefix}/knowledge/${knowledge_id}`, undefined, loading) } @@ -106,10 +92,10 @@ const getKnowledgeDetail: ( "embedding": "string" } */ -const postKnowledge: ( - data: knowledgeData, - loading?: Ref, -) => Promise> = (data, loading) => { +const postKnowledge: (data: knowledgeData, loading?: Ref) => Promise> = ( + data, + loading, +) => { return post(`${prefix}/knowledge/base`, data, undefined, loading, 1000 * 60 * 5) } @@ -125,10 +111,10 @@ const postKnowledge: ( "selector": "string" } */ -const postWebKnowledge: ( - data: any, - loading?: Ref, -) => Promise> = (data, loading) => { +const postWebKnowledge: (data: any, loading?: Ref) => Promise> = ( + data, + loading, +) => { return post(`${prefix}/knowledge/web`, data, undefined, loading) } /** @@ -148,6 +134,105 @@ const putKnowledge: ( return put(`${prefix}/knowledge/${knowledge_id}`, data, undefined, loading) } +/** + * 命中测试列表 + * @param knowledge_id + * @param loading + * @query { query_text: string, top_number: number, similarity: number } + * @returns + */ +const getKnowledgeHitTest: ( + knowledge_id: string, + data: any, + loading?: Ref, +) => Promise>> = (knowledge_id, data, loading) => { + return get(`${prefix}/${knowledge_id}/hit_test`, data, loading) +} + +/** + * 导出知识库 + * @param knowledge_name 知识库名称 + * @param knowledge_id 知识库id + * @returns + */ +const exportKnowledge: ( + knowledge_name: string, + knowledge_id: string, + loading?: Ref, +) => Promise = (knowledge_name, knowledge_id, loading) => { + return exportExcel(knowledge_name + '.xlsx', `dataset/${knowledge_id}/export`, undefined, loading) +} +/** + *导出Zip知识库 + * @param knowledge_name 知识库名称 + * @param knowledge_id 知识库id + * @param loading 加载器 + * @returns + */ +const exportZipKnowledge: ( + knowledge_name: string, + knowledge_id: string, + loading?: Ref, +) => Promise = (knowledge_name, knowledge_id, loading) => { + return exportFile( + knowledge_name + '.zip', + `dataset/${knowledge_id}/export_zip`, + undefined, + loading, + ) +} + +/** + * 获取当前用户可使用的模型列表 + * @param application_id + * @param loading + * @query { query_text: string, top_number: number, similarity: number } + * @returns + */ +const getKnowledgeModel: ( + knowledge_id: string, + loading?: Ref, +) => Promise>> = (knowledge_id, loading) => { + return get(`${prefix}/${knowledge_id}/model`, loading) +} +/** + * 获取飞书文档列表 + * @param knowledge_id + * @param folder_token + * @param loading + * @returns + */ +const getLarkDocumentList: ( + knowledge_id: string, + folder_token: string, + data: any, + loading?: Ref, +) => Promise>> = (knowledge_id, folder_token, data, loading) => { + return post(`${prefix}/lark/${knowledge_id}/${folder_token}/doc_list`, data, null, loading) +} + +const importLarkDocument: ( + knowledge_id: string, + data: any, + loading?: Ref, +) => Promise>> = (knowledge_id, data, loading) => { + return post(`${prefix}/lark/${knowledge_id}/import`, data, null, loading) +} +/** + * 生成关联问题 + * @param knowledge_id 知识库id + * @param data + * @param loading + * @returns + */ +const generateRelated: ( + knowledge_id: string, + data: any, + loading?: Ref, +) => Promise>> = (knowledge_id, data, loading) => { + return put(`${prefix}/${knowledge_id}/generate_related`, data, null, loading) +} + export default { getKnowledgeByFolder, getKnowledgeList, @@ -157,4 +242,11 @@ export default { postKnowledge, postWebKnowledge, putKnowledge, + getKnowledgeHitTest, + exportKnowledge, + exportZipKnowledge, + getKnowledgeModel, + getLarkDocumentList, + importLarkDocument, + generateRelated, } diff --git a/ui/src/components/generate-related-dialog/index.vue b/ui/src/components/generate-related-dialog/index.vue index dd507152e..0b9c1bba8 100644 --- a/ui/src/components/generate-related-dialog/index.vue +++ b/ui/src/components/generate-related-dialog/index.vue @@ -176,7 +176,7 @@ const submitHandle = async (formEl: FormInstance) => { ...form.value, state_list: stateMap[state.value] } - datasetApi.generateRelated(id ? id : datasetId.value, data, loading).then(() => { + knowledgeApi.generateRelated(id ? id : datasetId.value, data, loading).then(() => { MsgSuccess(t('views.document.generateQuestion.successMessage')) dialogVisible.value = false }) @@ -187,8 +187,8 @@ const submitHandle = async (formEl: FormInstance) => { function getModel() { loading.value = true - datasetApi - .getDatasetModel(id ? id : datasetId.value) + knowledgeApi + .getKnowledgeModel(id ? id : datasetId.value) .then((res: any) => { modelOptions.value = groupBy(res?.data, 'provider') loading.value = false diff --git a/ui/src/stores/modules/knowledge.ts b/ui/src/stores/modules/knowledge.ts index 876cc2d00..f3d945e21 100644 --- a/ui/src/stores/modules/knowledge.ts +++ b/ui/src/stores/modules/knowledge.ts @@ -58,7 +58,7 @@ const useKnowledgeStore = defineStore('knowledge', { }) }) }, - async asyncSyncDataset( + async asyncSyncKnowledge( id: string, sync_type: string, loading?: Ref, diff --git a/ui/src/views/hit-test/index.vue b/ui/src/views/hit-test/index.vue index 1a113487e..82dcc6116 100644 --- a/ui/src/views/hit-test/index.vue +++ b/ui/src/views/hit-test/index.vue @@ -312,7 +312,7 @@ function getHitTestList() { ...formInline.value, } if (isDataset.value) { - datasetApi.getDatasetHitTest(id, obj, loading).then((res) => { + knowledgeApi.getDatasetHitTest(id, obj, loading).then((res) => { paragraphDetail.value = res.data && arraySort(res.data, 'comprehensive_score', true) questionTitle.value = inputValue.value inputValue.value = '' diff --git a/ui/src/views/knowledge/component/SyncWebDialog.vue b/ui/src/views/knowledge/component/SyncWebDialog.vue index dbff35316..2701cfd73 100644 --- a/ui/src/views/knowledge/component/SyncWebDialog.vue +++ b/ui/src/views/knowledge/component/SyncWebDialog.vue @@ -38,12 +38,12 @@ import { ref, watch } from 'vue' import useStore from '@/stores' -const { dataset } = useStore() +const { knowledge } = useStore() const emit = defineEmits(['refresh']) const loading = ref(false) const method = ref('replace') -const datasetId = ref('') +const knowledgeId = ref('') const dialogVisible = ref(false) @@ -54,12 +54,12 @@ watch(dialogVisible, (bool) => { }) const open = (id: string) => { - datasetId.value = id + knowledgeId.value = id dialogVisible.value = true } const submit = () => { - dataset.asyncSyncDataset(datasetId.value, method.value, loading).then((res: any) => { + knowledge.asyncSyncKnowledge(knowledgeId.value, method.value, loading).then((res: any) => { emit('refresh', res.data) dialogVisible.value = false }) diff --git a/ui/src/views/knowledge/create-component/CreateWebKnowledgeDialog copy.vue b/ui/src/views/knowledge/create-component/CreateWebKnowledgeDialog copy.vue index d9d7b8429..f30a2d591 100644 --- a/ui/src/views/knowledge/create-component/CreateWebKnowledgeDialog copy.vue +++ b/ui/src/views/knowledge/create-component/CreateWebKnowledgeDialog copy.vue @@ -184,21 +184,21 @@ const submitHandle = async () => { ...BaseFormRef.value.form, type: datasetForm.value.type } - datasetApi.postDataset(obj, loading).then((res) => { + knowledgeApi.postDataset(obj, loading).then((res) => { MsgSuccess(t('common.createSuccess')) router.push({ path: `/dataset/${res.data.id}/document` }) emit('refresh') }) } else if (datasetForm.value.type === '1') { const obj = { ...BaseFormRef.value.form, ...datasetForm.value } - datasetApi.postWebDataset(obj, loading).then((res) => { + knowledgeApi.postWebDataset(obj, loading).then((res) => { MsgSuccess(t('common.createSuccess')) router.push({ path: `/dataset/${res.data.id}/document` }) emit('refresh') }) } else if (datasetForm.value.type === '2') { const obj = { ...BaseFormRef.value.form, ...datasetForm.value } - datasetApi.postLarkDataset(obj, loading).then((res) => { + knowledgeApi.postLarkDataset(obj, loading).then((res) => { MsgSuccess(t('common.createSuccess')) router.push({ path: `/dataset/${res.data.id}/document` }) emit('refresh') diff --git a/ui/src/views/paragraph/component/ParagraphCard.vue b/ui/src/views/paragraph/component/ParagraphCard.vue index 41a9f8076..18838b25f 100644 --- a/ui/src/views/paragraph/component/ParagraphCard.vue +++ b/ui/src/views/paragraph/component/ParagraphCard.vue @@ -6,7 +6,8 @@ @mouseleave="cardLeave()" >

{{ data.title || '-' }}

- () +const emit = defineEmits(['changeState', 'deleteParagraph']) +const loading = ref(false) const changeStateloading = ref(false) const show = ref(false) // card上面存在dropdown菜单 @@ -105,8 +109,7 @@ function changeState(row: any) { paragraph .asyncPutParagraph(id, documentId, row.id, obj, changeStateloading) .then((res) => { - // const index = paragraphDetail.value.findIndex((v) => v.id === row.id) - // paragraphDetail.value[index].is_active = !paragraphDetail.value[index].is_active + emit('changeState', row.id) return true }) .catch(() => { @@ -138,8 +141,7 @@ function deleteParagraph(row: any) { ) .then(() => { paragraph.asyncDelParagraph(id, documentId, row.id, loading).then(() => { - // const index = paragraphDetail.value.findIndex((v) => v.id === row.id) - // paragraphDetail.value.splice(index, 1) + emit('deleteParagraph', row.id) MsgSuccess(t('common.deleteSuccess')) }) }) @@ -163,7 +165,6 @@ function refreshMigrateParagraph() {} border: 1px solid #ffffff; box-shadow: none !important; position: relative; - z-index: 9999; &:hover { background: rgba(31, 35, 41, 0.1); border: 1px solid #dee0e3; diff --git a/ui/src/views/paragraph/index.vue b/ui/src/views/paragraph/index.vue index 11e47ab01..d84925936 100644 --- a/ui/src/views/paragraph/index.vue +++ b/ui/src/views/paragraph/index.vue @@ -89,7 +89,12 @@ height="15" class="handle-img mr-8 mt-24 cursor" /> - + @@ -132,7 +137,6 @@ import ParagraphDialog from './component/ParagraphDialog.vue' import ParagraphCard from './component/ParagraphCard.vue' import SelectDocumentDialog from './component/SelectDocumentDialog.vue' import GenerateRelatedDialog from '@/components/generate-related-dialog/index.vue' -import { numberFormat } from '@/utils/common' import { VueDraggable } from 'vue-draggable-plus' import { MsgSuccess, MsgConfirm } from '@/utils/message' import useStore from '@/stores' @@ -143,7 +147,6 @@ const { params: { id, documentId }, } = route as any -const containerRef = ref(null) const SelectDocumentDialogRef = ref() const ParagraphDialogRef = ref() const loading = ref(false) @@ -168,6 +171,16 @@ const paginationConfig = reactive({ total: 0, }) +function deleteParagraph(id: string) { + const index = paragraphDetail.value.findIndex((v) => v.id === id) + paragraphDetail.value.splice(index, 1) +} + +function changeState(id: string) { + const index = paragraphDetail.value.findIndex((v) => v.id === id) + paragraphDetail.value[index].is_active = !paragraphDetail.value[index].is_active +} + function refreshMigrateParagraph() { paragraphDetail.value = paragraphDetail.value.filter( (v) => !multipleSelection.value.includes(v.id), @@ -224,33 +237,10 @@ function searchHandle() { getParagraphList() } -function deleteParagraph(row: any) { - MsgConfirm( - `${t('views.paragraph.delete.confirmTitle')} ${row.title || '-'} ?`, - t('views.paragraph.delete.confirmMessage'), - { - confirmButtonText: t('common.confirm'), - confirmButtonClass: 'danger', - }, - ) - .then(() => { - paragraph.asyncDelParagraph(id, documentId, row.id, loading).then(() => { - const index = paragraphDetail.value.findIndex((v) => v.id === row.id) - paragraphDetail.value.splice(index, 1) - MsgSuccess(t('common.deleteSuccess')) - }) - }) - .catch(() => {}) -} - function addParagraph() { title.value = t('views.paragraph.addParagraph') ParagraphDialogRef.value.open() } -function editParagraph(row: any) { - title.value = t('views.paragraph.paragraphDetail') - ParagraphDialogRef.value.open(row) -} function getDetail() { loading.value = true