diff --git a/apps/web-antd/src/api/ai/knowledge/document/index.ts b/apps/web-antd/src/api/ai/knowledge/document/index.ts index a26e80e76..6c754d53e 100644 --- a/apps/web-antd/src/api/ai/knowledge/document/index.ts +++ b/apps/web-antd/src/api/ai/knowledge/document/index.ts @@ -26,10 +26,12 @@ export function getKnowledgeDocumentPage(params: PageParam) { export function getKnowledgeDocument(id: number) { return requestClient.get(`/ai/knowledge/document/get?id=${id}`); } + // 新增知识库文档(单个) export function createKnowledge(data: any) { return requestClient.post('/ai/knowledge/document/create', data); } + // 新增知识库文档(多个) export function createKnowledgeDocumentList(data: any) { return requestClient.post('/ai/knowledge/document/create-list', data); @@ -44,6 +46,7 @@ export function updateKnowledgeDocument(data: any) { export function updateKnowledgeDocumentStatus(data: any) { return requestClient.put('/ai/knowledge/document/update-status', data); } + // 删除知识库文档 export function deleteKnowledgeDocument(id: number) { return requestClient.delete(`/ai/knowledge/document/delete?id=${id}`); diff --git a/apps/web-antd/src/api/ai/knowledge/knowledge/index.ts b/apps/web-antd/src/api/ai/knowledge/knowledge/index.ts index 7140d8b48..03f70bd9a 100644 --- a/apps/web-antd/src/api/ai/knowledge/knowledge/index.ts +++ b/apps/web-antd/src/api/ai/knowledge/knowledge/index.ts @@ -27,6 +27,7 @@ export function getKnowledge(id: number) { `/ai/knowledge/get?id=${id}`, ); } + // 新增知识库 export function createKnowledge(data: AiKnowledgeKnowledgeApi.Knowledge) { return requestClient.post('/ai/knowledge/create', data); diff --git a/apps/web-antd/src/api/ai/knowledge/segment/index.ts b/apps/web-antd/src/api/ai/knowledge/segment/index.ts index 63ea4e752..e9baf662e 100644 --- a/apps/web-antd/src/api/ai/knowledge/segment/index.ts +++ b/apps/web-antd/src/api/ai/knowledge/segment/index.ts @@ -32,6 +32,7 @@ export function getKnowledgeSegment(id: number) { `/ai/knowledge/segment/get?id=${id}`, ); } + // 新增知识库分段 export function createKnowledgeSegment( data: AiKnowledgeSegmentApi.KnowledgeSegment, @@ -47,9 +48,13 @@ export function updateKnowledgeSegment( } // 修改知识库分段状态 -export function updateKnowledgeSegmentStatus(data: any) { - return requestClient.put('/ai/knowledge/segment/update-status', data); +export function updateKnowledgeSegmentStatus(id: number, status: number) { + return requestClient.put('/ai/knowledge/segment/update-status', { + id, + status, + }); } + // 删除知识库分段 export function deleteKnowledgeSegment(id: number) { return requestClient.delete(`/ai/knowledge/segment/delete?id=${id}`); diff --git a/apps/web-antd/src/views/ai/knowledge/document/data.ts b/apps/web-antd/src/views/ai/knowledge/document/data.ts index a6433040a..14c088e26 100644 --- a/apps/web-antd/src/views/ai/knowledge/document/data.ts +++ b/apps/web-antd/src/views/ai/knowledge/document/data.ts @@ -1,11 +1,13 @@ import type { VbenFormSchema } from '#/adapter/form'; import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { AiKnowledgeDocumentApi } from '#/api/ai/knowledge/document'; import { AiModelTypeEnum, CommonStatusEnum, DICT_TYPE } from '@vben/constants'; import { getDictOptions } from '@vben/hooks'; import { z } from '#/adapter/form'; import { getModelSimpleList } from '#/api/ai/model/model'; + /** 新增/修改的表单 */ export function useFormSchema(): VbenFormSchema[] { return [ @@ -92,12 +94,17 @@ export function useGridFormSchema(): VbenFormSchema[] { fieldName: 'name', label: '文件名称', component: 'Input', + componentProps: { + placeholder: '请输入文件名称', + allowClear: true, + }, }, { fieldName: 'status', label: '是否启用', component: 'Select', componentProps: { + placeholder: '请选择是否启用', allowClear: true, options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), }, @@ -106,45 +113,66 @@ export function useGridFormSchema(): VbenFormSchema[] { } /** 列表的字段 */ -export function useGridColumns(): VxeTableGridOptions['columns'] { +export function useGridColumns( + onStatusChange?: ( + newStatus: number, + row: AiKnowledgeDocumentApi.KnowledgeDocument, + ) => PromiseLike, +): VxeTableGridOptions['columns'] { return [ { field: 'id', title: '文档编号', + minWidth: 100, }, { field: 'name', title: '文件名称', + minWidth: 200, }, { field: 'contentLength', title: '字符数', + minWidth: 100, }, { field: 'tokens', title: 'Token 数', + minWidth: 100, }, { field: 'segmentMaxTokens', title: '分片最大 Token 数', + minWidth: 150, }, { field: 'retrievalCount', title: '召回次数', + minWidth: 100, }, { field: 'status', title: '是否启用', - slots: { default: 'status' }, + minWidth: 100, + align: 'center', + cellRender: { + attrs: { beforeChange: onStatusChange }, + name: 'CellSwitch', + props: { + checkedValue: CommonStatusEnum.ENABLE, + unCheckedValue: CommonStatusEnum.DISABLE, + }, + }, }, { field: 'createTime', title: '上传时间', + minWidth: 180, formatter: 'formatDateTime', }, { title: '操作', - width: 150, + minWidth: 150, fixed: 'right', slots: { default: 'actions' }, }, diff --git a/apps/web-antd/src/views/ai/knowledge/document/form/UploadStep.vue b/apps/web-antd/src/views/ai/knowledge/document/form/UploadStep.vue index b7e317370..f1ff0f22a 100644 --- a/apps/web-antd/src/views/ai/knowledge/document/form/UploadStep.vue +++ b/apps/web-antd/src/views/ai/knowledge/document/form/UploadStep.vue @@ -9,7 +9,6 @@ import type { AxiosProgressEvent } from '#/api/infra/file'; import { computed, getCurrentInstance, inject, onMounted, ref } from 'vue'; import { IconifyIcon } from '@vben/icons'; -import { $t } from '@vben/locales'; import { generateAcceptedFileTypes } from '@vben/utils'; import { Button, Form, message, UploadDragger } from 'ant-design-vue'; @@ -124,7 +123,7 @@ async function customRequest(info: UploadRequestOption) { }; const res = await httpRequest(info.file as File, progressEvent); info.onSuccess!(res); - message.success($t('ui.upload.uploadSuccess')); + message.success('上传成功'); ensureListExists(); emit('update:modelValue', { ...props.modelValue, diff --git a/apps/web-antd/src/views/ai/knowledge/document/index.vue b/apps/web-antd/src/views/ai/knowledge/document/index.vue index 16062f1ee..6094f6a67 100644 --- a/apps/web-antd/src/views/ai/knowledge/document/index.vue +++ b/apps/web-antd/src/views/ai/knowledge/document/index.vue @@ -5,11 +5,11 @@ import type { AiKnowledgeDocumentApi } from '#/api/ai/knowledge/document'; import { onMounted } from 'vue'; import { useRoute, useRouter } from 'vue-router'; -import { useAccess } from '@vben/access'; import { confirm, Page } from '@vben/common-ui'; -import { CommonStatusEnum } from '@vben/constants'; +import { DICT_TYPE } from '@vben/constants'; +import { getDictLabel } from '@vben/hooks'; -import { message, Switch } from 'ant-design-vue'; +import { message } from 'ant-design-vue'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { @@ -21,18 +21,18 @@ import { $t } from '#/locales'; import { useGridColumns, useGridFormSchema } from './data'; -/** AI 知识库文档 列表 */ +/** AI 知识库文档列表 */ defineOptions({ name: 'AiKnowledgeDocument' }); -const { hasAccessByCodes } = useAccess(); const route = useRoute(); const router = useRouter(); + /** 刷新表格 */ function handleRefresh() { gridApi.query(); } -/** 创建 */ +/** 创建知识库文档 */ function handleCreate() { router.push({ name: 'AiKnowledgeDocumentCreate', @@ -40,7 +40,7 @@ function handleCreate() { }); } -/** 编辑 */ +/** 编辑知识库文档 */ function handleEdit(id: number) { router.push({ name: 'AiKnowledgeDocumentUpdate', @@ -48,7 +48,7 @@ function handleEdit(id: number) { }); } -/** 删除 */ +/** 删除知识库文档 */ async function handleDelete(row: AiKnowledgeDocumentApi.KnowledgeDocument) { const hideLoading = message.loading({ content: $t('ui.actionMessage.deleting', [row.name]), @@ -56,14 +56,13 @@ async function handleDelete(row: AiKnowledgeDocumentApi.KnowledgeDocument) { }); try { await deleteKnowledgeDocument(row.id as number); - message.success({ - content: $t('ui.actionMessage.deleteSuccess', [row.name]), - }); + message.success($t('ui.actionMessage.deleteSuccess', [row.name])); handleRefresh(); } finally { hideLoading(); } } + /** 跳转到知识库分段页面 */ function handleSegment(id: number) { router.push({ @@ -71,33 +70,38 @@ function handleSegment(id: number) { query: { documentId: id }, }); } -/** 修改是否发布 */ + +/** 更新文档状态 */ async function handleStatusChange( + newStatus: number, row: AiKnowledgeDocumentApi.KnowledgeDocument, -) { - try { - // 修改状态的二次确认 - const text = row.status ? '启用' : '禁用'; - await confirm(`确认要"${text}"${row.name}文档吗?`).then(async () => { - await updateKnowledgeDocumentStatus({ - id: row.id, - status: row.status, +): Promise { + return new Promise((resolve, reject) => { + confirm({ + content: `你要将${row.name}的状态切换为【${getDictLabel(DICT_TYPE.COMMON_STATUS, newStatus)}】吗?`, + }) + .then(async () => { + // 更新文档状态 + await updateKnowledgeDocumentStatus({ + id: row.id, + status: newStatus, + }); + // 提示并返回成功 + message.success($t('ui.actionMessage.operationSuccess')); + resolve(true); + }) + .catch(() => { + reject(new Error('取消操作')); }); - handleRefresh(); - }); - } catch { - row.status = - row.status === CommonStatusEnum.ENABLE - ? CommonStatusEnum.DISABLE - : CommonStatusEnum.ENABLE; - } + }); } + const [Grid, gridApi] = useVbenVxeGrid({ formOptions: { schema: useGridFormSchema(), }, gridOptions: { - columns: useGridColumns(), + columns: useGridColumns(handleStatusChange), height: 'auto', keepSource: true, proxyConfig: { @@ -114,6 +118,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, rowConfig: { keyField: 'id', + isHover: true, }, toolbarConfig: { refresh: true, @@ -121,6 +126,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, } as VxeTableGridOptions, }); + /** 初始化 */ onMounted(() => { // 如果知识库 ID 不存在,显示错误提示并关闭页面 @@ -148,15 +154,6 @@ onMounted(() => { ]" /> - -