From 78bd8bee8f3edb3575a492ef8fd1d91f67b3021a Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 14 Nov 2025 13:52:11 +0800 Subject: [PATCH 01/53] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90ai=E3=80=91=E7=9F=A5=E8=AF=86=E5=BA=93=E7=9A=84=20know?= =?UTF-8?q?ledge=20=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/ai/knowledge/document/data.ts | 180 +++++++++++ .../ai/knowledge/document/form/index.vue | 200 ++++++++++++ .../document/form/modules/process-step.vue | 159 ++++++++++ .../document/form/modules/split-step.vue | 286 ++++++++++++++++++ .../document/form/modules/upload-step.vue | 270 +++++++++++++++++ .../src/views/ai/knowledge/document/index.vue | 192 ++++++++++++ .../src/views/ai/knowledge/knowledge/data.ts | 173 +++++++++++ .../views/ai/knowledge/knowledge/index.vue | 166 ++++++++++ .../ai/knowledge/knowledge/modules/form.vue | 90 ++++++ .../knowledge/knowledge/retrieval/index.vue | 214 +++++++++++++ .../src/views/ai/knowledge/segment/data.ts | 131 ++++++++ .../src/views/ai/knowledge/segment/index.vue | 171 +++++++++++ .../ai/knowledge/segment/modules/form.vue | 90 ++++++ 13 files changed, 2322 insertions(+) create mode 100644 apps/web-ele/src/views/ai/knowledge/document/data.ts create mode 100644 apps/web-ele/src/views/ai/knowledge/document/form/index.vue create mode 100644 apps/web-ele/src/views/ai/knowledge/document/form/modules/process-step.vue create mode 100644 apps/web-ele/src/views/ai/knowledge/document/form/modules/split-step.vue create mode 100644 apps/web-ele/src/views/ai/knowledge/document/form/modules/upload-step.vue create mode 100644 apps/web-ele/src/views/ai/knowledge/document/index.vue create mode 100644 apps/web-ele/src/views/ai/knowledge/knowledge/data.ts create mode 100644 apps/web-ele/src/views/ai/knowledge/knowledge/index.vue create mode 100644 apps/web-ele/src/views/ai/knowledge/knowledge/modules/form.vue create mode 100644 apps/web-ele/src/views/ai/knowledge/knowledge/retrieval/index.vue create mode 100644 apps/web-ele/src/views/ai/knowledge/segment/data.ts create mode 100644 apps/web-ele/src/views/ai/knowledge/segment/index.vue create mode 100644 apps/web-ele/src/views/ai/knowledge/segment/modules/form.vue diff --git a/apps/web-ele/src/views/ai/knowledge/document/data.ts b/apps/web-ele/src/views/ai/knowledge/document/data.ts new file mode 100644 index 000000000..fda42e4a3 --- /dev/null +++ b/apps/web-ele/src/views/ai/knowledge/document/data.ts @@ -0,0 +1,180 @@ +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 [ + { + component: 'Input', + fieldName: 'id', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + component: 'Input', + fieldName: 'name', + label: '知识库名称', + rules: 'required', + }, + { + fieldName: 'description', + label: '知识库描述', + component: 'Textarea', + componentProps: { + rows: 3, + placeholder: '请输入知识库描述', + }, + }, + { + component: 'ApiSelect', + fieldName: 'embeddingModelId', + label: '向量模型', + componentProps: { + api: () => getModelSimpleList(AiModelTypeEnum.EMBEDDING), + labelField: 'name', + valueField: 'id', + allowClear: true, + placeholder: '请选择向量模型', + }, + rules: 'required', + }, + { + fieldName: 'topK', + label: '检索 topK', + component: 'InputNumber', + componentProps: { + placeholder: '请输入检索 topK', + controlsPosition: 'right', + class: '!w-full', + min: 0, + max: 10, + }, + rules: 'required', + }, + { + fieldName: 'similarityThreshold', + label: '检索相似度阈值', + component: 'InputNumber', + componentProps: { + placeholder: '请输入检索相似度阈值', + controlsPosition: 'right', + class: '!w-full', + min: 0, + max: 1, + step: 0.01, + precision: 2, + }, + rules: 'required', + }, + { + fieldName: 'status', + label: '是否启用', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + 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'), + }, + }, + ]; +} + +/** 列表的字段 */ +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: '是否启用', + 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: '操作', + minWidth: 150, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/ai/knowledge/document/form/index.vue b/apps/web-ele/src/views/ai/knowledge/document/form/index.vue new file mode 100644 index 000000000..bee03dc25 --- /dev/null +++ b/apps/web-ele/src/views/ai/knowledge/document/form/index.vue @@ -0,0 +1,200 @@ + + + diff --git a/apps/web-ele/src/views/ai/knowledge/document/form/modules/process-step.vue b/apps/web-ele/src/views/ai/knowledge/document/form/modules/process-step.vue new file mode 100644 index 000000000..d94dd9f2a --- /dev/null +++ b/apps/web-ele/src/views/ai/knowledge/document/form/modules/process-step.vue @@ -0,0 +1,159 @@ + + + + diff --git a/apps/web-ele/src/views/ai/knowledge/document/form/modules/split-step.vue b/apps/web-ele/src/views/ai/knowledge/document/form/modules/split-step.vue new file mode 100644 index 000000000..65f4126a9 --- /dev/null +++ b/apps/web-ele/src/views/ai/knowledge/document/form/modules/split-step.vue @@ -0,0 +1,286 @@ + + + diff --git a/apps/web-ele/src/views/ai/knowledge/document/form/modules/upload-step.vue b/apps/web-ele/src/views/ai/knowledge/document/form/modules/upload-step.vue new file mode 100644 index 000000000..456aafd58 --- /dev/null +++ b/apps/web-ele/src/views/ai/knowledge/document/form/modules/upload-step.vue @@ -0,0 +1,270 @@ + + + diff --git a/apps/web-ele/src/views/ai/knowledge/document/index.vue b/apps/web-ele/src/views/ai/knowledge/document/index.vue new file mode 100644 index 000000000..181fea3d8 --- /dev/null +++ b/apps/web-ele/src/views/ai/knowledge/document/index.vue @@ -0,0 +1,192 @@ + + + diff --git a/apps/web-ele/src/views/ai/knowledge/knowledge/data.ts b/apps/web-ele/src/views/ai/knowledge/knowledge/data.ts new file mode 100644 index 000000000..b85233e95 --- /dev/null +++ b/apps/web-ele/src/views/ai/knowledge/knowledge/data.ts @@ -0,0 +1,173 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +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'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + fieldName: 'id', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + component: 'Input', + fieldName: 'name', + label: '知识库名称', + componentProps: { + placeholder: '请输入知识库名称', + }, + rules: 'required', + }, + { + fieldName: 'description', + label: '知识库描述', + component: 'Textarea', + componentProps: { + rows: 3, + placeholder: '请输入知识库描述', + }, + }, + { + component: 'ApiSelect', + fieldName: 'embeddingModelId', + label: '向量模型', + componentProps: { + api: () => getModelSimpleList(AiModelTypeEnum.EMBEDDING), + labelField: 'name', + valueField: 'id', + allowClear: true, + placeholder: '请选择向量模型', + }, + rules: 'required', + }, + { + fieldName: 'topK', + label: '检索 topK', + component: 'InputNumber', + componentProps: { + placeholder: '请输入检索 topK', + controlsPosition: 'right', + class: '!w-full', + min: 0, + max: 10, + }, + rules: 'required', + }, + { + fieldName: 'similarityThreshold', + label: '检索相似度阈值', + component: 'InputNumber', + componentProps: { + placeholder: '请输入检索相似度阈值', + controlsPosition: 'right', + class: '!w-full', + min: 0, + max: 1, + step: 0.01, + precision: 2, + }, + rules: 'required', + }, + { + fieldName: 'status', + label: '是否启用', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '知识库名称', + component: 'Input', + componentProps: { + placeholder: '请输入知识库名称', + allowClear: true, + }, + }, + { + fieldName: 'status', + label: '是否启用', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + placeholder: '请选择是否启用', + allowClear: true, + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: '编号', + minWidth: 100, + }, + { + field: 'name', + title: '知识库名称', + minWidth: 150, + }, + { + field: 'description', + title: '知识库描述', + minWidth: 200, + }, + { + field: 'embeddingModel', + title: '向量化模型', + minWidth: 150, + }, + { + field: 'status', + title: '是否启用', + minWidth: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 180, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 280, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + diff --git a/apps/web-ele/src/views/ai/knowledge/knowledge/index.vue b/apps/web-ele/src/views/ai/knowledge/knowledge/index.vue new file mode 100644 index 000000000..29db6c688 --- /dev/null +++ b/apps/web-ele/src/views/ai/knowledge/knowledge/index.vue @@ -0,0 +1,166 @@ + + + diff --git a/apps/web-ele/src/views/ai/knowledge/knowledge/modules/form.vue b/apps/web-ele/src/views/ai/knowledge/knowledge/modules/form.vue new file mode 100644 index 000000000..fd439b5b2 --- /dev/null +++ b/apps/web-ele/src/views/ai/knowledge/knowledge/modules/form.vue @@ -0,0 +1,90 @@ + + + + diff --git a/apps/web-ele/src/views/ai/knowledge/knowledge/retrieval/index.vue b/apps/web-ele/src/views/ai/knowledge/knowledge/retrieval/index.vue new file mode 100644 index 000000000..9c99231ed --- /dev/null +++ b/apps/web-ele/src/views/ai/knowledge/knowledge/retrieval/index.vue @@ -0,0 +1,214 @@ + + diff --git a/apps/web-ele/src/views/ai/knowledge/segment/data.ts b/apps/web-ele/src/views/ai/knowledge/segment/data.ts new file mode 100644 index 000000000..bcc52234a --- /dev/null +++ b/apps/web-ele/src/views/ai/knowledge/segment/data.ts @@ -0,0 +1,131 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { AiKnowledgeSegmentApi } from '#/api/ai/knowledge/segment'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + fieldName: 'id', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + component: 'Input', + fieldName: 'documentId', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'content', + label: '切片内容', + component: 'Textarea', + componentProps: { + placeholder: '请输入切片内容', + rows: 6, + showCount: true, + }, + rules: 'required', + }, + ]; +} +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'documentId', + label: '文档编号', + component: 'Input', + componentProps: { + placeholder: '请输入文档编号', + allowClear: true, + }, + }, + { + fieldName: 'status', + label: '是否启用', + component: 'Select', + componentProps: { + placeholder: '请选择是否启用', + allowClear: true, + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns( + onStatusChange?: ( + newStatus: number, + row: AiKnowledgeSegmentApi.KnowledgeSegment, + ) => PromiseLike, +): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: '分段编号', + minWidth: 100, + }, + { + type: 'expand', + width: 40, + slots: { content: 'expand_content' }, + }, + { + field: 'content', + title: '切片内容', + minWidth: 250, + }, + { + field: 'contentLength', + title: '字符数', + minWidth: 100, + }, + { + field: 'tokens', + title: 'token 数量', + minWidth: 120, + }, + { + field: 'retrievalCount', + title: '召回次数', + minWidth: 100, + }, + { + field: 'status', + title: '状态', + 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, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + diff --git a/apps/web-ele/src/views/ai/knowledge/segment/index.vue b/apps/web-ele/src/views/ai/knowledge/segment/index.vue new file mode 100644 index 000000000..6cfa04b11 --- /dev/null +++ b/apps/web-ele/src/views/ai/knowledge/segment/index.vue @@ -0,0 +1,171 @@ + + + diff --git a/apps/web-ele/src/views/ai/knowledge/segment/modules/form.vue b/apps/web-ele/src/views/ai/knowledge/segment/modules/form.vue new file mode 100644 index 000000000..69b176f6f --- /dev/null +++ b/apps/web-ele/src/views/ai/knowledge/segment/modules/form.vue @@ -0,0 +1,90 @@ + + + + From 5dc6f2d6722081a258c8caa2fdf99d39c48c2e50 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 14 Nov 2025 18:22:56 +0800 Subject: [PATCH 02/53] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90ai=E3=80=91=E7=9F=A5=E8=AF=86=E5=BA=93=E7=9A=84=20know?= =?UTF-8?q?ledge=20=E4=BC=98=E5=8C=96=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/ai/knowledge/segment/index.ts | 8 +- .../src/components/table-action/icons.ts | 1 + apps/web-ele/src/router/routes/modules/ai.ts | 113 ++++++++++++++++++ .../src/views/ai/knowledge/document/data.ts | 12 +- .../src/views/ai/knowledge/document/index.vue | 3 +- .../src/views/ai/knowledge/knowledge/data.ts | 9 +- .../ai/knowledge/knowledge/modules/form.vue | 1 - .../knowledge/knowledge/retrieval/index.vue | 2 +- .../src/views/ai/knowledge/segment/data.ts | 5 +- .../ai/knowledge/segment/modules/form.vue | 1 - 10 files changed, 134 insertions(+), 21 deletions(-) create mode 100644 apps/web-ele/src/router/routes/modules/ai.ts diff --git a/apps/web-ele/src/api/ai/knowledge/segment/index.ts b/apps/web-ele/src/api/ai/knowledge/segment/index.ts index 2635c772f..e9baf662e 100644 --- a/apps/web-ele/src/api/ai/knowledge/segment/index.ts +++ b/apps/web-ele/src/api/ai/knowledge/segment/index.ts @@ -48,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-ele/src/components/table-action/icons.ts b/apps/web-ele/src/components/table-action/icons.ts index 985871956..e6722e155 100644 --- a/apps/web-ele/src/components/table-action/icons.ts +++ b/apps/web-ele/src/components/table-action/icons.ts @@ -10,4 +10,5 @@ export const ACTION_ICON = { MORE: 'lucide:ellipsis-vertical', VIEW: 'lucide:eye', COPY: 'lucide:copy', + BOOK: 'lucide:book', }; diff --git a/apps/web-ele/src/router/routes/modules/ai.ts b/apps/web-ele/src/router/routes/modules/ai.ts new file mode 100644 index 000000000..639906e81 --- /dev/null +++ b/apps/web-ele/src/router/routes/modules/ai.ts @@ -0,0 +1,113 @@ +import type { RouteRecordRaw } from 'vue-router'; + +const routes: RouteRecordRaw[] = [ + { + path: '/ai', + name: 'Ai', + meta: { + title: 'Ai', + hideInMenu: true, + }, + children: [ + // { + // path: 'image/square', + // component: () => import('#/views/ai/image/square/index.vue'), + // name: 'AiImageSquare', + // meta: { + // noCache: true, + // hidden: true, + // canTo: true, + // title: '绘图作品', + // activePath: '/ai/image', + // }, + // }, + { + path: 'knowledge/document', + component: () => import('#/views/ai/knowledge/document/index.vue'), + name: 'AiKnowledgeDocument', + meta: { + noCache: true, + hidden: true, + canTo: true, + title: '知识库文档', + activePath: '/ai/knowledge', + }, + }, + { + path: 'knowledge/document/create', + component: () => import('#/views/ai/knowledge/document/form/index.vue'), + name: 'AiKnowledgeDocumentCreate', + meta: { + noCache: true, + hidden: true, + canTo: true, + title: '创建文档', + activePath: '/ai/knowledge', + }, + }, + { + path: 'knowledge/document/update', + component: () => import('#/views/ai/knowledge/document/form/index.vue'), + name: 'AiKnowledgeDocumentUpdate', + meta: { + noCache: true, + hidden: true, + canTo: true, + title: '修改文档', + activePath: '/ai/knowledge', + }, + }, + { + path: 'knowledge/retrieval', + component: () => + import('#/views/ai/knowledge/knowledge/retrieval/index.vue'), + name: 'AiKnowledgeRetrieval', + meta: { + noCache: true, + hidden: true, + canTo: true, + title: '文档召回测试', + activePath: '/ai/knowledge', + }, + }, + { + path: 'knowledge/segment', + component: () => import('#/views/ai/knowledge/segment/index.vue'), + name: 'AiKnowledgeSegment', + meta: { + noCache: true, + hidden: true, + canTo: true, + title: '知识库分段', + activePath: '/ai/knowledge', + }, + }, + // { + // path: String.raw`workflow/create/:id(\d+)/:type(update|create)`, + // component: () => import('#/views/ai/workflow/form/index.vue'), + // name: 'AiWorkflowCreate', + // meta: { + // noCache: true, + // hidden: true, + // canTo: true, + // title: '设计 AI 工作流', + // activePath: '/ai/workflow', + // }, + // }, + // { + // path: 'console/workflow/:type/:id', + // component: () => import('#/views/ai/workflow/form/index.vue'), + // name: 'AiWorkflowUpdate', + // meta: { + // noCache: true, + // hidden: true, + // canTo: true, + // title: '设计 AI 工作流', + // activePath: '/ai/workflow', + // }, + // }, + ], + }, +]; + +export default routes; diff --git a/apps/web-ele/src/views/ai/knowledge/document/data.ts b/apps/web-ele/src/views/ai/knowledge/document/data.ts index fda42e4a3..668fb09c7 100644 --- a/apps/web-ele/src/views/ai/knowledge/document/data.ts +++ b/apps/web-ele/src/views/ai/knowledge/document/data.ts @@ -53,10 +53,10 @@ export function useFormSchema(): VbenFormSchema[] { component: 'InputNumber', componentProps: { placeholder: '请输入检索 topK', - controlsPosition: 'right', - class: '!w-full', min: 0, max: 10, + controlsPosition: 'right', + class: '!w-full', }, rules: 'required', }, @@ -66,12 +66,12 @@ export function useFormSchema(): VbenFormSchema[] { component: 'InputNumber', componentProps: { placeholder: '请输入检索相似度阈值', - controlsPosition: 'right', - class: '!w-full', min: 0, max: 1, step: 0.01, precision: 2, + controlsPosition: 'right', + class: '!w-full', }, rules: 'required', }, @@ -159,8 +159,8 @@ export function useGridColumns( attrs: { beforeChange: onStatusChange }, name: 'CellSwitch', props: { - checkedValue: CommonStatusEnum.ENABLE, - unCheckedValue: CommonStatusEnum.DISABLE, + activeValue: CommonStatusEnum.ENABLE, + inactiveValue: CommonStatusEnum.DISABLE, }, }, }, diff --git a/apps/web-ele/src/views/ai/knowledge/document/index.vue b/apps/web-ele/src/views/ai/knowledge/document/index.vue index 181fea3d8..946962a7e 100644 --- a/apps/web-ele/src/views/ai/knowledge/document/index.vue +++ b/apps/web-ele/src/views/ai/knowledge/document/index.vue @@ -164,12 +164,11 @@ onMounted(() => { auth: ['ai:knowledge:update'], onClick: handleEdit.bind(null, row.id), }, - ]" - :drop-down-actions="[ { label: '分段', type: 'primary', link: true, + icon: ACTION_ICON.BOOK, auth: ['ai:knowledge:query'], onClick: handleSegment.bind(null, row.id), }, diff --git a/apps/web-ele/src/views/ai/knowledge/knowledge/data.ts b/apps/web-ele/src/views/ai/knowledge/knowledge/data.ts index b85233e95..1e69f2c85 100644 --- a/apps/web-ele/src/views/ai/knowledge/knowledge/data.ts +++ b/apps/web-ele/src/views/ai/knowledge/knowledge/data.ts @@ -56,10 +56,10 @@ export function useFormSchema(): VbenFormSchema[] { component: 'InputNumber', componentProps: { placeholder: '请输入检索 topK', - controlsPosition: 'right', - class: '!w-full', min: 0, max: 10, + controlsPosition: 'right', + class: '!w-full', }, rules: 'required', }, @@ -69,12 +69,12 @@ export function useFormSchema(): VbenFormSchema[] { component: 'InputNumber', componentProps: { placeholder: '请输入检索相似度阈值', - controlsPosition: 'right', - class: '!w-full', min: 0, max: 1, step: 0.01, precision: 2, + controlsPosition: 'right', + class: '!w-full', }, rules: 'required', }, @@ -170,4 +170,3 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { }, ]; } - diff --git a/apps/web-ele/src/views/ai/knowledge/knowledge/modules/form.vue b/apps/web-ele/src/views/ai/knowledge/knowledge/modules/form.vue index fd439b5b2..5daf71447 100644 --- a/apps/web-ele/src/views/ai/knowledge/knowledge/modules/form.vue +++ b/apps/web-ele/src/views/ai/knowledge/knowledge/modules/form.vue @@ -87,4 +87,3 @@ const [Modal, modalApi] = useVbenModal({
- diff --git a/apps/web-ele/src/views/ai/knowledge/knowledge/retrieval/index.vue b/apps/web-ele/src/views/ai/knowledge/knowledge/retrieval/index.vue index 9c99231ed..1af68dfd4 100644 --- a/apps/web-ele/src/views/ai/knowledge/knowledge/retrieval/index.vue +++ b/apps/web-ele/src/views/ai/knowledge/knowledge/retrieval/index.vue @@ -9,8 +9,8 @@ import { ElButton, ElCard, ElEmpty, - ElInputNumber, ElInput, + ElInputNumber, ElMessage, } from 'element-plus'; diff --git a/apps/web-ele/src/views/ai/knowledge/segment/data.ts b/apps/web-ele/src/views/ai/knowledge/segment/data.ts index bcc52234a..33cb64b01 100644 --- a/apps/web-ele/src/views/ai/knowledge/segment/data.ts +++ b/apps/web-ele/src/views/ai/knowledge/segment/data.ts @@ -109,8 +109,8 @@ export function useGridColumns( attrs: { beforeChange: onStatusChange }, name: 'CellSwitch', props: { - checkedValue: CommonStatusEnum.ENABLE, - unCheckedValue: CommonStatusEnum.DISABLE, + activeValue: CommonStatusEnum.ENABLE, + inactiveValue: CommonStatusEnum.DISABLE, }, }, }, @@ -128,4 +128,3 @@ export function useGridColumns( }, ]; } - diff --git a/apps/web-ele/src/views/ai/knowledge/segment/modules/form.vue b/apps/web-ele/src/views/ai/knowledge/segment/modules/form.vue index 69b176f6f..1b4b1354e 100644 --- a/apps/web-ele/src/views/ai/knowledge/segment/modules/form.vue +++ b/apps/web-ele/src/views/ai/knowledge/segment/modules/form.vue @@ -87,4 +87,3 @@ const [Modal, modalApi] = useVbenModal({ - From 6d1f7a7d9891c6e7843424f354c3b32d5b5015a3 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 14 Nov 2025 18:25:03 +0800 Subject: [PATCH 03/53] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90ai=E3=80=91=E7=9F=A5=E8=AF=86=E5=BA=93=E7=9A=84=20know?= =?UTF-8?q?ledge=20=E4=BC=98=E5=8C=96=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/views/ai/knowledge/document/data.ts | 2 -- apps/web-antd/src/views/ai/knowledge/document/index.vue | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) 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 14c088e26..46f251a18 100644 --- a/apps/web-antd/src/views/ai/knowledge/document/data.ts +++ b/apps/web-antd/src/views/ai/knowledge/document/data.ts @@ -53,7 +53,6 @@ export function useFormSchema(): VbenFormSchema[] { component: 'InputNumber', componentProps: { placeholder: '请输入检索 topK', - class: 'w-full', min: 0, max: 10, }, @@ -65,7 +64,6 @@ export function useFormSchema(): VbenFormSchema[] { component: 'InputNumber', componentProps: { placeholder: '请输入检索相似度阈值', - class: 'w-full', min: 0, max: 1, step: 0.01, 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 6094f6a67..16d0d06fd 100644 --- a/apps/web-antd/src/views/ai/knowledge/document/index.vue +++ b/apps/web-antd/src/views/ai/knowledge/document/index.vue @@ -164,11 +164,10 @@ onMounted(() => { auth: ['ai:knowledge:update'], onClick: handleEdit.bind(null, row.id), }, - ]" - :drop-down-actions="[ { label: '分段', type: 'link', + icon: ACTION_ICON.BOOK, auth: ['ai:knowledge:query'], onClick: handleSegment.bind(null, row.id), }, From d0566293327470f04df95fb56095e1418e4345e0 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 14 Nov 2025 20:51:14 +0800 Subject: [PATCH 04/53] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90ai=E3=80=91=E7=9F=A5=E8=AF=86=E5=BA=93=E7=9A=84=20know?= =?UTF-8?q?ledge=20=E4=BC=98=E5=8C=96=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/ai/knowledge/document/form/modules/process-step.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/web-ele/src/views/ai/knowledge/document/form/modules/process-step.vue b/apps/web-ele/src/views/ai/knowledge/document/form/modules/process-step.vue index d94dd9f2a..e790c7344 100644 --- a/apps/web-ele/src/views/ai/knowledge/document/form/modules/process-step.vue +++ b/apps/web-ele/src/views/ai/knowledge/document/form/modules/process-step.vue @@ -156,4 +156,3 @@ onBeforeUnmount(() => { - From 1cbd4033b8e482714fc714393e4bd6f8ba8ee7a6 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 14 Nov 2025 22:22:43 +0800 Subject: [PATCH 05/53] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90ai=E3=80=91=E9=9F=B3=E4=B9=90=E7=9A=84=E8=BF=81?= =?UTF-8?q?=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/ai/knowledge/knowledge/index.ts | 1 + .../src/views/ai/music/index/index.vue | 29 +++++ .../ai/music/index/list/audioBar/index.vue | 99 ++++++++++++++++ .../src/views/ai/music/index/list/index.vue | 100 ++++++++++++++++ .../ai/music/index/list/songCard/index.vue | 50 ++++++++ .../ai/music/index/list/songInfo/index.vue | 25 ++++ .../src/views/ai/music/index/mode/desc.vue | 66 +++++++++++ .../src/views/ai/music/index/mode/index.vue | 38 +++++++ .../src/views/ai/music/index/mode/lyric.vue | 107 ++++++++++++++++++ .../src/views/ai/music/index/title/index.vue | 27 +++++ 10 files changed, 542 insertions(+) create mode 100644 apps/web-ele/src/views/ai/music/index/index.vue create mode 100644 apps/web-ele/src/views/ai/music/index/list/audioBar/index.vue create mode 100644 apps/web-ele/src/views/ai/music/index/list/index.vue create mode 100644 apps/web-ele/src/views/ai/music/index/list/songCard/index.vue create mode 100644 apps/web-ele/src/views/ai/music/index/list/songInfo/index.vue create mode 100644 apps/web-ele/src/views/ai/music/index/mode/desc.vue create mode 100644 apps/web-ele/src/views/ai/music/index/mode/index.vue create mode 100644 apps/web-ele/src/views/ai/music/index/mode/lyric.vue create mode 100644 apps/web-ele/src/views/ai/music/index/title/index.vue diff --git a/apps/web-ele/src/api/ai/knowledge/knowledge/index.ts b/apps/web-ele/src/api/ai/knowledge/knowledge/index.ts index 7140d8b48..03f70bd9a 100644 --- a/apps/web-ele/src/api/ai/knowledge/knowledge/index.ts +++ b/apps/web-ele/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-ele/src/views/ai/music/index/index.vue b/apps/web-ele/src/views/ai/music/index/index.vue new file mode 100644 index 000000000..af00e1819 --- /dev/null +++ b/apps/web-ele/src/views/ai/music/index/index.vue @@ -0,0 +1,29 @@ + + + diff --git a/apps/web-ele/src/views/ai/music/index/list/audioBar/index.vue b/apps/web-ele/src/views/ai/music/index/list/audioBar/index.vue new file mode 100644 index 000000000..4399afde6 --- /dev/null +++ b/apps/web-ele/src/views/ai/music/index/list/audioBar/index.vue @@ -0,0 +1,99 @@ + + + diff --git a/apps/web-ele/src/views/ai/music/index/list/index.vue b/apps/web-ele/src/views/ai/music/index/list/index.vue new file mode 100644 index 000000000..50dbf3385 --- /dev/null +++ b/apps/web-ele/src/views/ai/music/index/list/index.vue @@ -0,0 +1,100 @@ + + + + diff --git a/apps/web-ele/src/views/ai/music/index/list/songCard/index.vue b/apps/web-ele/src/views/ai/music/index/list/songCard/index.vue new file mode 100644 index 000000000..2d7bdb661 --- /dev/null +++ b/apps/web-ele/src/views/ai/music/index/list/songCard/index.vue @@ -0,0 +1,50 @@ + + + diff --git a/apps/web-ele/src/views/ai/music/index/list/songInfo/index.vue b/apps/web-ele/src/views/ai/music/index/list/songInfo/index.vue new file mode 100644 index 000000000..eb4fbc8ad --- /dev/null +++ b/apps/web-ele/src/views/ai/music/index/list/songInfo/index.vue @@ -0,0 +1,25 @@ + + + diff --git a/apps/web-ele/src/views/ai/music/index/mode/desc.vue b/apps/web-ele/src/views/ai/music/index/mode/desc.vue new file mode 100644 index 000000000..bcf9a01eb --- /dev/null +++ b/apps/web-ele/src/views/ai/music/index/mode/desc.vue @@ -0,0 +1,66 @@ + + + diff --git a/apps/web-ele/src/views/ai/music/index/mode/index.vue b/apps/web-ele/src/views/ai/music/index/mode/index.vue new file mode 100644 index 000000000..813ea73ba --- /dev/null +++ b/apps/web-ele/src/views/ai/music/index/mode/index.vue @@ -0,0 +1,38 @@ + + + diff --git a/apps/web-ele/src/views/ai/music/index/mode/lyric.vue b/apps/web-ele/src/views/ai/music/index/mode/lyric.vue new file mode 100644 index 000000000..c64f91564 --- /dev/null +++ b/apps/web-ele/src/views/ai/music/index/mode/lyric.vue @@ -0,0 +1,107 @@ + + + diff --git a/apps/web-ele/src/views/ai/music/index/title/index.vue b/apps/web-ele/src/views/ai/music/index/title/index.vue new file mode 100644 index 000000000..04dc58bcc --- /dev/null +++ b/apps/web-ele/src/views/ai/music/index/title/index.vue @@ -0,0 +1,27 @@ + + + From 02f2e90d4312bc55744a0abeea0e8fe8a98b5a2f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 14 Nov 2025 22:23:05 +0800 Subject: [PATCH 06/53] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90antd=E3=80=91=E4=BB=A3=E7=A0=81=E7=9A=84=E5=B7=AE?= =?UTF-8?q?=E5=BC=82=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ai/music/index/list/audioBar/index.vue | 5 ++--- .../src/views/ai/music/index/list/index.vue | 17 ++--------------- .../src/views/ai/music/index/mode/index.vue | 5 ----- .../mall/promotion/kefu/conversation/index.ts | 4 +--- apps/web-ele/src/api/mp/account/index.ts | 11 ++++++----- apps/web-ele/src/views/member/level/index.vue | 1 + .../user/detail/modules/favorite-list.vue | 4 ++-- apps/web-ele/src/views/mp/account/index.vue | 4 +++- 8 files changed, 17 insertions(+), 34 deletions(-) diff --git a/apps/web-antd/src/views/ai/music/index/list/audioBar/index.vue b/apps/web-antd/src/views/ai/music/index/list/audioBar/index.vue index 3a2b7df9a..1fed73a75 100644 --- a/apps/web-antd/src/views/ai/music/index/list/audioBar/index.vue +++ b/apps/web-antd/src/views/ai/music/index/list/audioBar/index.vue @@ -11,7 +11,6 @@ defineOptions({ name: 'AiMusicAudioBarIndex' }); const currentSong = inject('currentSong', {}); const audioRef = ref(null); -// 音频相关属性https://www.runoob.com/tags/ref-av-dom.html const audioProps = reactive({ autoplay: true, paused: false, @@ -19,7 +18,7 @@ const audioProps = reactive({ duration: '00:00', muted: false, volume: 50, -}); +}); // 音频相关属性https://www.runoob.com/tags/ref-av-dom.html function toggleStatus(type: string) { audioProps[type] = !audioProps[type]; @@ -32,7 +31,7 @@ function toggleStatus(type: string) { } } -// 更新播放位置 +/** 更新播放位置 */ function audioTimeUpdate(args: any) { audioProps.currentTime = formatPast(new Date(args.timeStamp), 'mm:ss'); } diff --git a/apps/web-antd/src/views/ai/music/index/list/index.vue b/apps/web-antd/src/views/ai/music/index/list/index.vue index b67b3898f..1975973db 100644 --- a/apps/web-antd/src/views/ai/music/index/list/index.vue +++ b/apps/web-antd/src/views/ai/music/index/list/index.vue @@ -12,19 +12,11 @@ import songInfo from './songInfo/index.vue'; defineOptions({ name: 'AiMusicListIndex' }); const currentType = ref('mine'); -// loading 状态 -const loading = ref(false); -// 当前音乐 -const currentSong = ref({}); - +const loading = ref(false); // loading 状态 +const currentSong = ref({}); // 当前音乐 const mySongList = ref[]>([]); const squareSongList = ref[]>([]); -/* - *@Description: 调接口生成音乐列表 - *@MethodAuthor: xiaohong - *@Date: 2024-06-27 17:06:44 - */ function generateMusic(formData: Recordable) { loading.value = true; setTimeout(() => { @@ -53,11 +45,6 @@ function generateMusic(formData: Recordable) { }, 3000); } -/* - *@Description: 设置当前播放的音乐 - *@MethodAuthor: xiaohong - *@Date: 2024-07-19 11:22:33 - */ function setCurrentSong(music: Recordable) { currentSong.value = music; } diff --git a/apps/web-antd/src/views/ai/music/index/mode/index.vue b/apps/web-antd/src/views/ai/music/index/mode/index.vue index a76fce27e..35df306da 100644 --- a/apps/web-antd/src/views/ai/music/index/mode/index.vue +++ b/apps/web-antd/src/views/ai/music/index/mode/index.vue @@ -16,11 +16,6 @@ const generateMode = ref('lyric'); const modeRef = ref }>>(null); -/* - *@Description: 根据信息生成音乐 - *@MethodAuthor: xiaohong - *@Date: 2024-06-27 16:40:16 - */ function generateMusic() { emits('generateMusic', { formData: unref(modeRef)?.formData }); } diff --git a/apps/web-ele/src/api/mall/promotion/kefu/conversation/index.ts b/apps/web-ele/src/api/mall/promotion/kefu/conversation/index.ts index 6510dc0ec..497bd1a50 100644 --- a/apps/web-ele/src/api/mall/promotion/kefu/conversation/index.ts +++ b/apps/web-ele/src/api/mall/promotion/kefu/conversation/index.ts @@ -1,5 +1,3 @@ -import type { PageResult } from '@vben/request'; - import { requestClient } from '#/api/request'; export namespace MallKefuConversationApi { @@ -28,7 +26,7 @@ export namespace MallKefuConversationApi { /** 获得客服会话列表 */ export function getConversationList() { - return requestClient.get>( + return requestClient.get( '/promotion/kefu-conversation/list', ); } diff --git a/apps/web-ele/src/api/mp/account/index.ts b/apps/web-ele/src/api/mp/account/index.ts index c5ee331b0..5bd402230 100644 --- a/apps/web-ele/src/api/mp/account/index.ts +++ b/apps/web-ele/src/api/mp/account/index.ts @@ -5,18 +5,19 @@ import { requestClient } from '#/api/request'; export namespace MpAccountApi { /** 公众号账号信息 */ export interface Account { - id?: number; + id: number; name: string; - account: string; - appId: string; - appSecret: string; - token: string; + account?: string; + appId?: string; + appSecret?: string; + token?: string; aesKey?: string; qrCodeUrl?: string; remark?: string; createTime?: Date; } + // TODO @dylan:这个直接使用 Account,简化一点; export interface AccountSimple { id: number; name: string; diff --git a/apps/web-ele/src/views/member/level/index.vue b/apps/web-ele/src/views/member/level/index.vue index 396c74fa7..3284397f4 100644 --- a/apps/web-ele/src/views/member/level/index.vue +++ b/apps/web-ele/src/views/member/level/index.vue @@ -87,6 +87,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ url="https://doc.iocoder.cn/member/level/" /> + +
, default: () => [] as AiModelModelApi.Model[], }, -}); +}); // 接收父组件传入的模型列表 const emits = defineEmits(['onDrawStart', 'onDrawComplete']); -// 定义属性 const drawIn = ref(false); // 生成中 const selectHotWord = ref(''); // 选中的热词 -// 表单 + const prompt = ref(''); // 提示词 const referImageUrl = ref(); // 参考图 const selectModel = ref('midjourney'); // 选中的模型 @@ -58,7 +54,6 @@ async function handleHotWordClick(hotWord: string) { selectHotWord.value = ''; return; } - // 情况二:选中 selectHotWord.value = hotWord; // 选中 prompt.value = hotWord; // 设置提示次 diff --git a/apps/web-antd/src/views/ai/image/index/components/stableDiffusion/index.vue b/apps/web-antd/src/views/ai/image/index/modules/stable-diffusion/index.vue similarity index 98% rename from apps/web-antd/src/views/ai/image/index/components/stableDiffusion/index.vue rename to apps/web-antd/src/views/ai/image/index/modules/stable-diffusion/index.vue index 03c826016..5ba08c9b2 100644 --- a/apps/web-antd/src/views/ai/image/index/components/stableDiffusion/index.vue +++ b/apps/web-antd/src/views/ai/image/index/modules/stable-diffusion/index.vue @@ -25,14 +25,12 @@ import { import { drawImage } from '#/api/ai/image'; -// 接收父组件传入的模型列表 const props = defineProps({ models: { type: Array, default: () => [] as AiModelModelApi.Model[], }, -}); - +}); // 接收父组件传入的模型列表 const emits = defineEmits(['onDrawStart', 'onDrawComplete']); function hasChinese(str: string) { @@ -60,7 +58,6 @@ async function handleHotWordClick(hotWord: string) { selectHotWord.value = ''; return; } - // 情况二:选中 selectHotWord.value = hotWord; // 选中 prompt.value = hotWord; // 替换提示词 @@ -82,7 +79,7 @@ async function handleGenerateImage() { // 二次确认 if (hasChinese(prompt.value)) { - alert('暂不支持中文!'); + await alert('暂不支持中文!'); return; } await confirm(`确认生成内容?`); From cc8703ca90c645ac4c6aecfd602e69f955ead3d8 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 15 Nov 2025 13:50:55 +0800 Subject: [PATCH 10/53] =?UTF-8?q?feat=EF=BC=9A=E3=80=90antd=E3=80=91?= =?UTF-8?q?=E3=80=90ai=E3=80=91chat=20=E7=9A=84=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/ai/chat/index/index.vue | 27 +++++++++++-------- .../conversation/list.vue} | 17 +++++------- .../conversation/update-form.vue} | 0 .../message/knowledge.vue} | 0 .../message/list-empty.vue} | 7 ++--- .../message/list.vue} | 5 ++-- .../message/loading.vue} | 0 .../message/new-conversation.vue} | 0 .../role/category-list.vue} | 5 ++-- .../RoleList.vue => modules/role/list.vue} | 7 ++--- .../role/repository.vue} | 7 ++--- 11 files changed, 36 insertions(+), 39 deletions(-) rename apps/web-antd/src/views/ai/chat/index/{components/conversation/ConversationList.vue => modules/conversation/list.vue} (97%) rename apps/web-antd/src/views/ai/chat/index/{components/conversation/ConversationUpdateForm.vue => modules/conversation/update-form.vue} (100%) rename apps/web-antd/src/views/ai/chat/index/{components/message/MessageKnowledge.vue => modules/message/knowledge.vue} (100%) rename apps/web-antd/src/views/ai/chat/index/{components/message/MessageListEmpty.vue => modules/message/list-empty.vue} (95%) rename apps/web-antd/src/views/ai/chat/index/{components/message/MessageList.vue => modules/message/list.vue} (98%) rename apps/web-antd/src/views/ai/chat/index/{components/message/MessageLoading.vue => modules/message/loading.vue} (100%) rename apps/web-antd/src/views/ai/chat/index/{components/message/MessageNewConversation.vue => modules/message/new-conversation.vue} (100%) rename apps/web-antd/src/views/ai/chat/index/{components/role/RoleCategoryList.vue => modules/role/category-list.vue} (91%) rename apps/web-antd/src/views/ai/chat/index/{components/role/RoleList.vue => modules/role/list.vue} (97%) rename apps/web-antd/src/views/ai/chat/index/{components/role/RoleRepository.vue => modules/role/repository.vue} (98%) diff --git a/apps/web-antd/src/views/ai/chat/index/index.vue b/apps/web-antd/src/views/ai/chat/index/index.vue index 9e6cc2559..c18ae1b76 100644 --- a/apps/web-antd/src/views/ai/chat/index/index.vue +++ b/apps/web-antd/src/views/ai/chat/index/index.vue @@ -18,12 +18,12 @@ import { sendChatMessageStream, } from '#/api/ai/chat/message'; -import ConversationList from './components/conversation/ConversationList.vue'; -import ConversationUpdateForm from './components/conversation/ConversationUpdateForm.vue'; -import MessageList from './components/message/MessageList.vue'; -import MessageListEmpty from './components/message/MessageListEmpty.vue'; -import MessageLoading from './components/message/MessageLoading.vue'; -import MessageNewConversation from './components/message/MessageNewConversation.vue'; +import ConversationList from './modules/conversation/list.vue'; +import ConversationUpdateForm from './modules/conversation/update-form.vue'; +import MessageListEmpty from './modules/message/list-empty.vue'; +import MessageList from './modules/message/list.vue'; +import MessageLoading from './modules/message/loading.vue'; +import MessageNewConversation from './modules/message/new-conversation.vue'; /** AI 聊天对话 列表 */ defineOptions({ name: 'AiChat' }); @@ -33,6 +33,7 @@ const [FormModal, formModalApi] = useVbenModal({ connectedComponent: ConversationUpdateForm, destroyOnClose: true, }); + // 聊天对话 const conversationListRef = ref(); const activeConversationId = ref(null); // 选中的对话编号 @@ -87,7 +88,7 @@ async function handleConversationClick( ) { // 对话进行中,不允许切换 if (conversationInProgress.value) { - alert('对话中,不允许切换!'); + await alert('对话中,不允许切换!'); return false; } @@ -97,6 +98,7 @@ async function handleConversationClick( // 刷新 message 列表 await getMessageList(); // 滚动底部 + // TODO @AI:看看要不要 await scrollToBottom(true); // 清空输入框 prompt.value = ''; @@ -117,7 +119,7 @@ async function handlerConversationDelete( async function handleConversationClear() { // 对话进行中,不允许切换 if (conversationInProgress.value) { - alert('对话中,不允许切换!'); + await alert('对话中,不允许切换!'); return false; } activeConversationId.value = null; @@ -128,8 +130,9 @@ async function handleConversationClear() { async function openChatConversationUpdateForm() { formModalApi.setData({ id: activeConversationId.value }).open(); } + +/** 对话更新成功,刷新最新信息 */ async function handleConversationUpdateSuccess() { - // 对话更新成功,刷新最新信息 await getConversation(activeConversationId.value); } @@ -138,6 +141,7 @@ async function handleConversationCreate() { // 创建对话 await conversationListRef.value.createConversation(); } + /** 处理聊天对话的创建成功 */ async function handleConversationCreateSuccess() { // 创建新的对话,清空输入框 @@ -228,6 +232,7 @@ function handleGoTopMessage() { } // =========== 【发送消息】相关 =========== + /** 处理来自 keydown 的发送消息 */ async function handleSendByKeydown(event: any) { // 判断用户是否在输入 @@ -282,7 +287,6 @@ function onCompositionstart() { } function onCompositionend() { - // console.log('输入结束...') setTimeout(() => { isComposing.value = false; }, 200); @@ -339,6 +343,7 @@ async function doSendMessageStream(userMessage: AiChatMessageApi.ChatMessage) { await nextTick(); await scrollToBottom(); // 底部 // 1.3 开始滚动 + // TODO @AI:要不要 await textRoll(); // 2. 发送 event stream @@ -351,7 +356,7 @@ async function doSendMessageStream(userMessage: AiChatMessageApi.ChatMessage) { async (res: any) => { const { code, data, msg } = JSON.parse(res.data); if (code !== 0) { - alert(`对话异常! ${msg}`); + await alert(`对话异常! ${msg}`); return; } diff --git a/apps/web-antd/src/views/ai/chat/index/components/conversation/ConversationList.vue b/apps/web-antd/src/views/ai/chat/index/modules/conversation/list.vue similarity index 97% rename from apps/web-antd/src/views/ai/chat/index/components/conversation/ConversationList.vue rename to apps/web-antd/src/views/ai/chat/index/modules/conversation/list.vue index e6526ecf8..a52ed6291 100644 --- a/apps/web-antd/src/views/ai/chat/index/components/conversation/ConversationList.vue +++ b/apps/web-antd/src/views/ai/chat/index/modules/conversation/list.vue @@ -19,9 +19,8 @@ import { } from '#/api/ai/chat/conversation'; import { $t } from '#/locales'; -import RoleRepository from '../role/RoleRepository.vue'; +import RoleRepository from '../role/repository.vue'; -// 定义组件 props const props = defineProps({ activeId: { type: [Number, null] as PropType, @@ -29,7 +28,6 @@ const props = defineProps({ }, }); -// 定义钩子 const emits = defineEmits([ 'onConversationCreate', 'onConversationClick', @@ -41,7 +39,6 @@ const [Drawer, drawerApi] = useVbenDrawer({ connectedComponent: RoleRepository, }); -// 定义属性 const searchName = ref(''); // 对话搜索 const activeConversationId = ref(null); // 选中的对话,默认为 null const hoverConversationId = ref(null); // 悬浮上去的对话 @@ -180,7 +177,7 @@ async function updateConversationTitle( conversation: AiChatConversationApi.ChatConversation, ) { // 1. 二次确认 - prompt({ + await prompt({ async beforeClose(scope) { if (scope.isConfirm) { if (scope.value) { @@ -202,8 +199,7 @@ async function updateConversationTitle( if ( filterConversationList.length > 0 && filterConversationList[0] && // tip:避免切换对话 - activeConversationId.value === - (filterConversationList[0].id!) + activeConversationId.value === filterConversationList[0].id! ) { emits('onConversationClick', filterConversationList[0]); } @@ -252,9 +248,9 @@ async function handleClearConversation() { await confirm('确认后对话会全部清空,置顶的对话除外。'); await deleteChatConversationMyByUnpinned(); message.success($t('ui.actionMessage.operationSuccess')); - // 清空 对话 和 对话内容 + // 清空对话、对话内容 activeConversationId.value = null; - // 获取 对话列表 + // 获取对话列表 await getChatConversationList(); // 回调 方法 emits('onConversationClear'); @@ -283,7 +279,6 @@ watch(activeId, async (newValue) => { activeConversationId.value = newValue; }); -// 定义 public 方法 defineExpose({ createConversation }); /** 初始化 */ @@ -298,7 +293,7 @@ onMounted(async () => { if (conversationList.value.length > 0 && conversationList.value[0]) { activeConversationId.value = conversationList.value[0].id; // 回调 onConversationClick - await emits('onConversationClick', conversationList.value[0]); + emits('onConversationClick', conversationList.value[0]); } } }); diff --git a/apps/web-antd/src/views/ai/chat/index/components/conversation/ConversationUpdateForm.vue b/apps/web-antd/src/views/ai/chat/index/modules/conversation/update-form.vue similarity index 100% rename from apps/web-antd/src/views/ai/chat/index/components/conversation/ConversationUpdateForm.vue rename to apps/web-antd/src/views/ai/chat/index/modules/conversation/update-form.vue diff --git a/apps/web-antd/src/views/ai/chat/index/components/message/MessageKnowledge.vue b/apps/web-antd/src/views/ai/chat/index/modules/message/knowledge.vue similarity index 100% rename from apps/web-antd/src/views/ai/chat/index/components/message/MessageKnowledge.vue rename to apps/web-antd/src/views/ai/chat/index/modules/message/knowledge.vue diff --git a/apps/web-antd/src/views/ai/chat/index/components/message/MessageListEmpty.vue b/apps/web-antd/src/views/ai/chat/index/modules/message/list-empty.vue similarity index 95% rename from apps/web-antd/src/views/ai/chat/index/components/message/MessageListEmpty.vue rename to apps/web-antd/src/views/ai/chat/index/modules/message/list-empty.vue index 9ccb028e3..b8ac0a3e4 100644 --- a/apps/web-antd/src/views/ai/chat/index/components/message/MessageListEmpty.vue +++ b/apps/web-antd/src/views/ai/chat/index/modules/message/list-empty.vue @@ -1,8 +1,7 @@ + + + diff --git a/apps/web-ele/src/views/ai/image/index/modules/card.vue b/apps/web-ele/src/views/ai/image/index/modules/card.vue new file mode 100644 index 000000000..dd9fd688e --- /dev/null +++ b/apps/web-ele/src/views/ai/image/index/modules/card.vue @@ -0,0 +1,135 @@ + + + diff --git a/apps/web-ele/src/views/ai/image/index/modules/common/index.vue b/apps/web-ele/src/views/ai/image/index/modules/common/index.vue new file mode 100644 index 000000000..5880dfb95 --- /dev/null +++ b/apps/web-ele/src/views/ai/image/index/modules/common/index.vue @@ -0,0 +1,233 @@ + + + diff --git a/apps/web-ele/src/views/ai/image/index/modules/dall3/index.vue b/apps/web-ele/src/views/ai/image/index/modules/dall3/index.vue new file mode 100644 index 000000000..d7700f869 --- /dev/null +++ b/apps/web-ele/src/views/ai/image/index/modules/dall3/index.vue @@ -0,0 +1,259 @@ + + + diff --git a/apps/web-ele/src/views/ai/image/index/modules/detail.vue b/apps/web-ele/src/views/ai/image/index/modules/detail.vue new file mode 100644 index 000000000..8f92a6c2a --- /dev/null +++ b/apps/web-ele/src/views/ai/image/index/modules/detail.vue @@ -0,0 +1,210 @@ + + + diff --git a/apps/web-ele/src/views/ai/image/index/modules/list.vue b/apps/web-ele/src/views/ai/image/index/modules/list.vue new file mode 100644 index 000000000..646622b52 --- /dev/null +++ b/apps/web-ele/src/views/ai/image/index/modules/list.vue @@ -0,0 +1,222 @@ + + + diff --git a/apps/web-ele/src/views/ai/image/index/modules/midjourney/index.vue b/apps/web-ele/src/views/ai/image/index/modules/midjourney/index.vue new file mode 100644 index 000000000..7e81facb5 --- /dev/null +++ b/apps/web-ele/src/views/ai/image/index/modules/midjourney/index.vue @@ -0,0 +1,257 @@ + + + diff --git a/apps/web-ele/src/views/ai/image/index/modules/stable-diffusion/index.vue b/apps/web-ele/src/views/ai/image/index/modules/stable-diffusion/index.vue new file mode 100644 index 000000000..6f7877d7c --- /dev/null +++ b/apps/web-ele/src/views/ai/image/index/modules/stable-diffusion/index.vue @@ -0,0 +1,312 @@ + + + diff --git a/apps/web-ele/src/views/ai/image/square/index.vue b/apps/web-ele/src/views/ai/image/square/index.vue new file mode 100644 index 000000000..fbbfcd55e --- /dev/null +++ b/apps/web-ele/src/views/ai/image/square/index.vue @@ -0,0 +1,91 @@ + + From 104be22d0d3c252fcbd6fb8c963b71ef68a3f1d3 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 15 Nov 2025 15:31:47 +0800 Subject: [PATCH 13/53] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90ai=E3=80=91image=20=E7=9A=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E8=AF=84=E5=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web-antd/src/views/ai/image/index/modules/card.vue | 1 + .../src/views/ai/image/index/modules/common/index.vue | 2 +- .../src/views/ai/image/index/modules/dall3/index.vue | 1 - .../src/views/ai/image/index/modules/detail.vue | 10 +++------- .../views/ai/image/index/modules/midjourney/index.vue | 1 - .../ai/image/index/modules/stable-diffusion/index.vue | 2 +- apps/web-antd/src/views/ai/image/square/index.vue | 2 ++ apps/web-ele/src/views/ai/image/index/index.vue | 6 +----- apps/web-ele/src/views/ai/image/index/modules/card.vue | 7 ++++--- .../src/views/ai/image/index/modules/common/index.vue | 4 +++- .../src/views/ai/image/index/modules/dall3/index.vue | 1 + .../src/views/ai/image/index/modules/detail.vue | 10 +++------- apps/web-ele/src/views/ai/image/square/index.vue | 1 - 13 files changed, 20 insertions(+), 28 deletions(-) diff --git a/apps/web-antd/src/views/ai/image/index/modules/card.vue b/apps/web-antd/src/views/ai/image/index/modules/card.vue index 70774472b..57b12e655 100644 --- a/apps/web-antd/src/views/ai/image/index/modules/card.vue +++ b/apps/web-antd/src/views/ai/image/index/modules/card.vue @@ -77,6 +77,7 @@ onMounted(async () => {
+
- - + diff --git a/apps/web-ele/src/views/erp/sale/return/index.vue b/apps/web-ele/src/views/erp/sale/return/index.vue index b62d479b1..5a76a96b3 100644 --- a/apps/web-ele/src/views/erp/sale/return/index.vue +++ b/apps/web-ele/src/views/erp/sale/return/index.vue @@ -196,7 +196,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: row.status === 10 ? '审批' : '反审批', type: 'primary', link: true, - icon: row.status === 10 ? ACTION_ICON.CHECK : ACTION_ICON.CLOSE, + icon: ACTION_ICON.AUDIT, auth: ['erp:sale-return:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, diff --git a/apps/web-ele/src/views/erp/sale/return/modules/sale-order-select.vue b/apps/web-ele/src/views/erp/sale/return/modules/sale-order-select.vue index 0b8628d78..05d4746cd 100644 --- a/apps/web-ele/src/views/erp/sale/return/modules/sale-order-select.vue +++ b/apps/web-ele/src/views/erp/sale/return/modules/sale-order-select.vue @@ -6,7 +6,7 @@ import { ref } from 'vue'; import { IconifyIcon } from '@vben/icons'; -import { ElInput, ElMessage } from 'element-plus'; +import { ElButton, ElDialog, ElInput, ElMessage } from 'element-plus'; import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { getSaleOrderPage } from '#/api/erp/sale/order'; @@ -107,17 +107,18 @@ function handleOk() { - - + From e9164912e527e7d22bd0a1cce8e225287743f7bb Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 20:02:53 +0800 Subject: [PATCH 39/53] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90erp=E3=80=91home=20=E7=9A=84=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=EF=BC=88100%=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/erp/statistics/purchase/index.ts | 16 +- .../src/api/erp/statistics/sale/index.ts | 12 +- apps/web-antd/src/views/erp/home/index.vue | 6 +- .../{SummaryCard.vue => summary-card.vue} | 0 ...ummaryChart.vue => time-summary-chart.vue} | 8 +- .../src/api/erp/statistics/purchase/index.ts | 31 ++++ .../src/api/erp/statistics/sale/index.ts | 31 ++++ apps/web-ele/src/views/erp/home/index.vue | 51 ++++++ .../views/erp/home/modules/summary-card.vue | 69 ++++++++ .../erp/home/modules/time-summary-chart.vue | 161 ++++++++++++++++++ 10 files changed, 364 insertions(+), 21 deletions(-) rename apps/web-antd/src/views/erp/home/modules/{SummaryCard.vue => summary-card.vue} (100%) rename apps/web-antd/src/views/erp/home/modules/{TimeSummaryChart.vue => time-summary-chart.vue} (93%) create mode 100644 apps/web-ele/src/api/erp/statistics/purchase/index.ts create mode 100644 apps/web-ele/src/api/erp/statistics/sale/index.ts create mode 100644 apps/web-ele/src/views/erp/home/index.vue create mode 100644 apps/web-ele/src/views/erp/home/modules/summary-card.vue create mode 100644 apps/web-ele/src/views/erp/home/modules/time-summary-chart.vue diff --git a/apps/web-antd/src/api/erp/statistics/purchase/index.ts b/apps/web-antd/src/api/erp/statistics/purchase/index.ts index 170b9c117..126b6f283 100644 --- a/apps/web-antd/src/api/erp/statistics/purchase/index.ts +++ b/apps/web-antd/src/api/erp/statistics/purchase/index.ts @@ -1,16 +1,16 @@ import { requestClient } from '#/api/request'; export namespace ErpPurchaseStatisticsApi { - /** ERP 采购全局统计 */ - export interface PurchaseSummary { + /** 采购全局统计 */ + export interface PurchaseSummaryRespVO { todayPrice: number; // 今日采购金额 yesterdayPrice: number; // 昨日采购金额 monthPrice: number; // 本月采购金额 yearPrice: number; // 今年采购金额 } - /** ERP 采购时间段统计 */ - export interface PurchaseTimeSummary { + /** 采购时间段统计 */ + export interface PurchaseTimeSummaryRespVO { time: string; // 时间 price: number; // 采购金额 } @@ -18,14 +18,14 @@ export namespace ErpPurchaseStatisticsApi { /** 获得采购统计 */ export function getPurchaseSummary() { - return requestClient.get( + return requestClient.get( '/erp/purchase-statistics/summary', ); } /** 获得采购时间段统计 */ export function getPurchaseTimeSummary() { - return requestClient.get( - '/erp/purchase-statistics/time-summary', - ); + return requestClient.get< + ErpPurchaseStatisticsApi.PurchaseTimeSummaryRespVO[] + >('/erp/purchase-statistics/time-summary'); } diff --git a/apps/web-antd/src/api/erp/statistics/sale/index.ts b/apps/web-antd/src/api/erp/statistics/sale/index.ts index c4c7986a8..209c1c938 100644 --- a/apps/web-antd/src/api/erp/statistics/sale/index.ts +++ b/apps/web-antd/src/api/erp/statistics/sale/index.ts @@ -1,16 +1,16 @@ import { requestClient } from '#/api/request'; export namespace ErpSaleStatisticsApi { - /** ERP 销售全局统计 */ - export interface SaleSummary { + /** 销售全局统计 */ + export interface SaleSummaryRespVO { todayPrice: number; // 今日销售金额 yesterdayPrice: number; // 昨日销售金额 monthPrice: number; // 本月销售金额 yearPrice: number; // 今年销售金额 } - /** ERP 销售时间段统计 */ - export interface SaleTimeSummary { + /** 销售时间段统计 */ + export interface SaleTimeSummaryRespVO { time: string; // 时间 price: number; // 销售金额 } @@ -18,14 +18,14 @@ export namespace ErpSaleStatisticsApi { /** 获得销售统计 */ export function getSaleSummary() { - return requestClient.get( + return requestClient.get( '/erp/sale-statistics/summary', ); } /** 获得销售时间段统计 */ export function getSaleTimeSummary() { - return requestClient.get( + return requestClient.get( '/erp/sale-statistics/time-summary', ); } diff --git a/apps/web-antd/src/views/erp/home/index.vue b/apps/web-antd/src/views/erp/home/index.vue index 7b9d86e26..efb49045b 100644 --- a/apps/web-antd/src/views/erp/home/index.vue +++ b/apps/web-antd/src/views/erp/home/index.vue @@ -5,10 +5,10 @@ import { DocAlert, Page } from '@vben/common-ui'; import { Col, Row, Spin } from 'ant-design-vue'; -import SummaryCard from './modules/SummaryCard.vue'; -import TimeSummaryChart from './modules/TimeSummaryChart.vue'; +import SummaryCard from './modules/summary-card.vue'; +import TimeSummaryChart from './modules/time-summary-chart.vue'; -/** ERP首页 */ +/** ERP 首页 */ defineOptions({ name: 'ErpHome' }); const loading = ref(false); // 加载中 diff --git a/apps/web-antd/src/views/erp/home/modules/SummaryCard.vue b/apps/web-antd/src/views/erp/home/modules/summary-card.vue similarity index 100% rename from apps/web-antd/src/views/erp/home/modules/SummaryCard.vue rename to apps/web-antd/src/views/erp/home/modules/summary-card.vue diff --git a/apps/web-antd/src/views/erp/home/modules/TimeSummaryChart.vue b/apps/web-antd/src/views/erp/home/modules/time-summary-chart.vue similarity index 93% rename from apps/web-antd/src/views/erp/home/modules/TimeSummaryChart.vue rename to apps/web-antd/src/views/erp/home/modules/time-summary-chart.vue index 9bdc96eed..ef15eaaf1 100644 --- a/apps/web-antd/src/views/erp/home/modules/TimeSummaryChart.vue +++ b/apps/web-antd/src/views/erp/home/modules/time-summary-chart.vue @@ -26,17 +26,17 @@ const props = withDefaults(defineProps(), { }); /** 销售统计数据 */ -const saleSummary = ref(); // 销售概况统计 -const saleTimeSummaryList = ref(); // 销售时段统计 +const saleSummary = ref(); // 销售概况统计 +const saleTimeSummaryList = ref(); // 销售时段统计 const getSaleStatistics = async () => { saleSummary.value = await getSaleSummary(); saleTimeSummaryList.value = await getSaleTimeSummary(); }; /** 采购统计数据 */ -const purchaseSummary = ref(); // 采购概况统计 +const purchaseSummary = ref(); // 采购概况统计 const purchaseTimeSummaryList = - ref(); // 采购时段统计 + ref(); // 采购时段统计 const getPurchaseStatistics = async () => { purchaseSummary.value = await getPurchaseSummary(); purchaseTimeSummaryList.value = await getPurchaseTimeSummary(); diff --git a/apps/web-ele/src/api/erp/statistics/purchase/index.ts b/apps/web-ele/src/api/erp/statistics/purchase/index.ts new file mode 100644 index 000000000..126b6f283 --- /dev/null +++ b/apps/web-ele/src/api/erp/statistics/purchase/index.ts @@ -0,0 +1,31 @@ +import { requestClient } from '#/api/request'; + +export namespace ErpPurchaseStatisticsApi { + /** 采购全局统计 */ + export interface PurchaseSummaryRespVO { + todayPrice: number; // 今日采购金额 + yesterdayPrice: number; // 昨日采购金额 + monthPrice: number; // 本月采购金额 + yearPrice: number; // 今年采购金额 + } + + /** 采购时间段统计 */ + export interface PurchaseTimeSummaryRespVO { + time: string; // 时间 + price: number; // 采购金额 + } +} + +/** 获得采购统计 */ +export function getPurchaseSummary() { + return requestClient.get( + '/erp/purchase-statistics/summary', + ); +} + +/** 获得采购时间段统计 */ +export function getPurchaseTimeSummary() { + return requestClient.get< + ErpPurchaseStatisticsApi.PurchaseTimeSummaryRespVO[] + >('/erp/purchase-statistics/time-summary'); +} diff --git a/apps/web-ele/src/api/erp/statistics/sale/index.ts b/apps/web-ele/src/api/erp/statistics/sale/index.ts new file mode 100644 index 000000000..209c1c938 --- /dev/null +++ b/apps/web-ele/src/api/erp/statistics/sale/index.ts @@ -0,0 +1,31 @@ +import { requestClient } from '#/api/request'; + +export namespace ErpSaleStatisticsApi { + /** 销售全局统计 */ + export interface SaleSummaryRespVO { + todayPrice: number; // 今日销售金额 + yesterdayPrice: number; // 昨日销售金额 + monthPrice: number; // 本月销售金额 + yearPrice: number; // 今年销售金额 + } + + /** 销售时间段统计 */ + export interface SaleTimeSummaryRespVO { + time: string; // 时间 + price: number; // 销售金额 + } +} + +/** 获得销售统计 */ +export function getSaleSummary() { + return requestClient.get( + '/erp/sale-statistics/summary', + ); +} + +/** 获得销售时间段统计 */ +export function getSaleTimeSummary() { + return requestClient.get( + '/erp/sale-statistics/time-summary', + ); +} diff --git a/apps/web-ele/src/views/erp/home/index.vue b/apps/web-ele/src/views/erp/home/index.vue new file mode 100644 index 000000000..9f6f2ea14 --- /dev/null +++ b/apps/web-ele/src/views/erp/home/index.vue @@ -0,0 +1,51 @@ + + + diff --git a/apps/web-ele/src/views/erp/home/modules/summary-card.vue b/apps/web-ele/src/views/erp/home/modules/summary-card.vue new file mode 100644 index 000000000..ff98e556a --- /dev/null +++ b/apps/web-ele/src/views/erp/home/modules/summary-card.vue @@ -0,0 +1,69 @@ + + + diff --git a/apps/web-ele/src/views/erp/home/modules/time-summary-chart.vue b/apps/web-ele/src/views/erp/home/modules/time-summary-chart.vue new file mode 100644 index 000000000..fe164eb29 --- /dev/null +++ b/apps/web-ele/src/views/erp/home/modules/time-summary-chart.vue @@ -0,0 +1,161 @@ + + + From 2973e0b70fc058b338f42f378dd9b5ec4739ad68 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 20:27:30 +0800 Subject: [PATCH 40/53] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90erp=E3=80=91purchase=20=E7=9A=84=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=EF=BC=8820%=EF=BC=89-=20supplier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/erp/purchase/supplier/index.vue | 1 - .../views/erp/purchase/in/modules/form.vue | 231 +++++++++++++++++ .../src/views/erp/purchase/supplier/data.ts | 234 ++++++++++++++++++ .../src/views/erp/purchase/supplier/index.vue | 153 ++++++++++++ .../erp/purchase/supplier/modules/form.vue | 90 +++++++ 5 files changed, 708 insertions(+), 1 deletion(-) create mode 100644 apps/web-ele/src/views/erp/purchase/in/modules/form.vue create mode 100644 apps/web-ele/src/views/erp/purchase/supplier/data.ts create mode 100644 apps/web-ele/src/views/erp/purchase/supplier/index.vue create mode 100644 apps/web-ele/src/views/erp/purchase/supplier/modules/form.vue diff --git a/apps/web-antd/src/views/erp/purchase/supplier/index.vue b/apps/web-antd/src/views/erp/purchase/supplier/index.vue index 64cb81aaf..e012568b8 100644 --- a/apps/web-antd/src/views/erp/purchase/supplier/index.vue +++ b/apps/web-antd/src/views/erp/purchase/supplier/index.vue @@ -124,7 +124,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ ]" /> -