diff --git a/apps/web-antd/src/views/ai/model/apiKey/data.ts b/apps/web-antd/src/views/ai/model/apiKey/data.ts index cd78bfe38..47b36d59f 100644 --- a/apps/web-antd/src/views/ai/model/apiKey/data.ts +++ b/apps/web-antd/src/views/ai/model/apiKey/data.ts @@ -5,6 +5,7 @@ import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; import { getDictOptions } from '@vben/hooks'; import { z } from '#/adapter/form'; + /** 新增/修改的表单 */ export function useFormSchema(): VbenFormSchema[] { return [ @@ -25,24 +26,33 @@ export function useFormSchema(): VbenFormSchema[] { options: getDictOptions(DICT_TYPE.AI_PLATFORM, 'string'), allowClear: true, }, - rules: z.string().min(1, { message: '请输入平台' }), + rules: 'required', }, { component: 'Input', fieldName: 'name', label: '名称', rules: 'required', + componentProps: { + placeholder: '请输入名称', + }, }, { component: 'Input', fieldName: 'apiKey', label: '密钥', rules: 'required', + componentProps: { + placeholder: '请输入密钥', + }, }, { component: 'Input', fieldName: 'url', label: '自定义 API URL', + componentProps: { + placeholder: '请输入自定义 API URL', + }, }, { fieldName: 'status', @@ -65,6 +75,10 @@ export function useGridFormSchema(): VbenFormSchema[] { fieldName: 'name', label: '名称', component: 'Input', + componentProps: { + placeholder: '请输入名称', + allowClear: true, + }, }, { fieldName: 'platform', @@ -72,6 +86,7 @@ export function useGridFormSchema(): VbenFormSchema[] { component: 'Select', componentProps: { allowClear: true, + placeholder: '请选择平台', options: getDictOptions(DICT_TYPE.AI_PLATFORM, 'string'), }, }, @@ -81,6 +96,7 @@ export function useGridFormSchema(): VbenFormSchema[] { component: 'Select', componentProps: { allowClear: true, + placeholder: '请选择状态', options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), }, }, @@ -97,18 +113,22 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { name: 'CellDict', props: { type: DICT_TYPE.AI_PLATFORM }, }, + minWidth: 100, }, { field: 'name', title: '名称', + minWidth: 120, }, { field: 'apiKey', title: '密钥', + minWidth: 140, }, { field: 'url', title: '自定义 API URL', + minWidth: 180, }, { field: 'status', @@ -117,6 +137,7 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, }, + minWidth: 80, }, { title: '操作', diff --git a/apps/web-antd/src/views/ai/model/apiKey/index.vue b/apps/web-antd/src/views/ai/model/apiKey/index.vue index aab147869..10d751dda 100644 --- a/apps/web-antd/src/views/ai/model/apiKey/index.vue +++ b/apps/web-antd/src/views/ai/model/apiKey/index.vue @@ -41,9 +41,7 @@ async function handleDelete(row: AiModelApiKeyApi.ApiKey) { }); try { await deleteApiKey(row.id as number); - message.success({ - content: $t('ui.actionMessage.deleteSuccess', [row.name]), - }); + message.success($t('ui.actionMessage.deleteSuccess', [row.name])); handleRefresh(); } finally { hideLoading(); @@ -71,6 +69,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, rowConfig: { keyField: 'id', + isHover: true, }, toolbarConfig: { refresh: true, diff --git a/apps/web-antd/src/views/ai/model/apiKey/modules/form.vue b/apps/web-antd/src/views/ai/model/apiKey/modules/form.vue index 85985ae83..21f21f305 100644 --- a/apps/web-antd/src/views/ai/model/apiKey/modules/form.vue +++ b/apps/web-antd/src/views/ai/model/apiKey/modules/form.vue @@ -27,7 +27,7 @@ const [Form, formApi] = useVbenForm({ class: 'w-full', }, formItemClass: 'col-span-2', - labelWidth: 100, + labelWidth: 120, }, layout: 'horizontal', schema: useFormSchema(), @@ -76,7 +76,7 @@ const [Modal, modalApi] = useVbenModal({ diff --git a/apps/web-antd/src/views/ai/model/chatRole/data.ts b/apps/web-antd/src/views/ai/model/chatRole/data.ts index 668fe8254..eb800c247 100644 --- a/apps/web-antd/src/views/ai/model/chatRole/data.ts +++ b/apps/web-antd/src/views/ai/model/chatRole/data.ts @@ -8,6 +8,7 @@ import { z } from '#/adapter/form'; import { getSimpleKnowledgeList } from '#/api/ai/knowledge/knowledge'; import { getModelSimpleList } from '#/api/ai/model/model'; import { getToolSimpleList } from '#/api/ai/model/tool'; + /** 新增/修改的表单 */ export function useFormSchema(): VbenFormSchema[] { return [ @@ -32,6 +33,9 @@ export function useFormSchema(): VbenFormSchema[] { fieldName: 'name', label: '角色名称', rules: 'required', + componentProps: { + placeholder: '请输入角色名称', + }, }, { component: 'ImageUpload', @@ -62,6 +66,9 @@ export function useFormSchema(): VbenFormSchema[] { fieldName: 'category', label: '角色类别', rules: 'required', + componentProps: { + placeholder: '请输入角色类别', + }, dependencies: { triggerFields: ['formType'], show: (values) => { @@ -113,6 +120,17 @@ export function useFormSchema(): VbenFormSchema[] { allowClear: true, }, }, + { + fieldName: 'mcpClientNames', + label: '引用 MCP', + component: 'Select', + componentProps: { + placeholder: '请选择 MCP', + options: getDictOptions(DICT_TYPE.AI_MCP_CLIENT_NAME, 'string'), + mode: 'multiple', + allowClear: true, + }, + }, { fieldName: 'publicStatus', label: '是否公开', @@ -254,6 +272,16 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { : `引用${cellValue.length}个`; }, }, + { + title: 'MCP', + field: 'mcpClientNames', + minWidth: 100, + formatter: ({ cellValue }) => { + return !cellValue || cellValue.length === 0 + ? '-' + : `引用${cellValue.length}个`; + }, + }, { field: 'publicStatus', title: '是否公开', diff --git a/apps/web-antd/src/views/ai/model/chatRole/index.vue b/apps/web-antd/src/views/ai/model/chatRole/index.vue index a0441b94d..0423e4668 100644 --- a/apps/web-antd/src/views/ai/model/chatRole/index.vue +++ b/apps/web-antd/src/views/ai/model/chatRole/index.vue @@ -41,9 +41,7 @@ async function handleDelete(row: AiModelChatRoleApi.ChatRole) { }); try { await deleteChatRole(row.id as number); - message.success({ - content: $t('ui.actionMessage.deleteSuccess', [row.name]), - }); + message.success($t('ui.actionMessage.deleteSuccess', [row.name])); handleRefresh(); } finally { hideLoading(); @@ -71,6 +69,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, rowConfig: { keyField: 'id', + isHover: true, }, toolbarConfig: { refresh: true, diff --git a/apps/web-antd/src/views/ai/model/chatRole/modules/form.vue b/apps/web-antd/src/views/ai/model/chatRole/modules/form.vue index f1d3ee481..8388f9740 100644 --- a/apps/web-antd/src/views/ai/model/chatRole/modules/form.vue +++ b/apps/web-antd/src/views/ai/model/chatRole/modules/form.vue @@ -82,7 +82,7 @@ const [Modal, modalApi] = useVbenModal({ diff --git a/apps/web-antd/src/views/ai/model/model/data.ts b/apps/web-antd/src/views/ai/model/model/data.ts index cec6ae67e..67117bddf 100644 --- a/apps/web-antd/src/views/ai/model/model/data.ts +++ b/apps/web-antd/src/views/ai/model/model/data.ts @@ -35,7 +35,7 @@ export function useFormSchema(): VbenFormSchema[] { options: getDictOptions(DICT_TYPE.AI_PLATFORM, 'string'), allowClear: true, }, - rules: z.string().min(1, { message: '请输入平台' }), + rules: 'required', }, { fieldName: 'type', @@ -56,7 +56,7 @@ export function useFormSchema(): VbenFormSchema[] { label: 'API 秘钥', component: 'ApiSelect', componentProps: { - placeholder: '请选择API 秘钥', + placeholder: '请选择 API 秘钥', api: getApiKeySimpleList, labelField: 'name', valueField: 'id', @@ -69,12 +69,18 @@ export function useFormSchema(): VbenFormSchema[] { fieldName: 'name', label: '模型名字', rules: 'required', + componentProps: { + placeholder: '请输入模型名字', + }, }, { component: 'Input', fieldName: 'model', label: '模型标识', rules: 'required', + componentProps: { + placeholder: '请输入模型标识', + }, }, { fieldName: 'sort', @@ -161,16 +167,28 @@ export function useGridFormSchema(): VbenFormSchema[] { fieldName: 'name', label: '模型名字', component: 'Input', + componentProps: { + placeholder: '请输入模型名字', + allowClear: true, + }, }, { fieldName: 'model', label: '模型标识', component: 'Input', + componentProps: { + placeholder: '请输入模型标识', + allowClear: true, + }, }, { fieldName: 'platform', label: '模型平台', component: 'Input', + componentProps: { + placeholder: '请输入模型平台', + allowClear: true, + }, }, ]; } @@ -233,7 +251,7 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'temperature', title: '温度参数', - minWidth: 80, + minWidth: 100, }, { title: '回复数 Token 数', @@ -243,7 +261,7 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { title: '上下文数量', field: 'maxContexts', - minWidth: 100, + minWidth: 120, }, { title: '操作', diff --git a/apps/web-antd/src/views/ai/model/model/index.vue b/apps/web-antd/src/views/ai/model/model/index.vue index 546362ca7..dc1bbc8da 100644 --- a/apps/web-antd/src/views/ai/model/model/index.vue +++ b/apps/web-antd/src/views/ai/model/model/index.vue @@ -41,9 +41,7 @@ async function handleDelete(row: AiModelModelApi.Model) { }); try { await deleteModel(row.id as number); - message.success({ - content: $t('ui.actionMessage.deleteSuccess', [row.name]), - }); + message.success($t('ui.actionMessage.deleteSuccess', [row.name])); handleRefresh(); } finally { hideLoading(); @@ -71,6 +69,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, rowConfig: { keyField: 'id', + isHover: true, }, toolbarConfig: { refresh: true, diff --git a/apps/web-antd/src/views/ai/model/model/modules/form.vue b/apps/web-antd/src/views/ai/model/model/modules/form.vue index 4baaf3b2b..1f5f9a8f1 100644 --- a/apps/web-antd/src/views/ai/model/model/modules/form.vue +++ b/apps/web-antd/src/views/ai/model/model/modules/form.vue @@ -77,7 +77,7 @@ const [Modal, modalApi] = useVbenModal({ diff --git a/apps/web-antd/src/views/ai/model/tool/data.ts b/apps/web-antd/src/views/ai/model/tool/data.ts index 1dd51850b..0c9f020f5 100644 --- a/apps/web-antd/src/views/ai/model/tool/data.ts +++ b/apps/web-antd/src/views/ai/model/tool/data.ts @@ -22,6 +22,9 @@ export function useFormSchema(): VbenFormSchema[] { fieldName: 'name', label: '工具名称', rules: 'required', + componentProps: { + placeholder: '请输入工具名称', + }, }, { component: 'Textarea', @@ -52,6 +55,10 @@ export function useGridFormSchema(): VbenFormSchema[] { fieldName: 'name', label: '工具名称', component: 'Input', + componentProps: { + placeholder: '请输入工具名称', + allowClear: true, + }, }, { fieldName: 'status', @@ -60,6 +67,7 @@ export function useGridFormSchema(): VbenFormSchema[] { componentProps: { allowClear: true, options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + placeholder: '请选择状态', }, }, { @@ -80,14 +88,17 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'id', title: '工具编号', + minWidth: 100, }, { field: 'name', title: '工具名称', + minWidth: 120, }, { field: 'description', title: '工具描述', + minWidth: 140, }, { field: 'status', @@ -96,6 +107,7 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { name: 'CellDict', props: { type: DICT_TYPE.COMMON_STATUS }, }, + minWidth: 80, }, { field: 'createTime', diff --git a/apps/web-antd/src/views/ai/model/tool/index.vue b/apps/web-antd/src/views/ai/model/tool/index.vue index 7521222f6..52e772264 100644 --- a/apps/web-antd/src/views/ai/model/tool/index.vue +++ b/apps/web-antd/src/views/ai/model/tool/index.vue @@ -41,9 +41,7 @@ async function handleDelete(row: AiModelToolApi.Tool) { }); try { await deleteTool(row.id as number); - message.success({ - content: $t('ui.actionMessage.deleteSuccess', [row.name]), - }); + message.success($t('ui.actionMessage.deleteSuccess', [row.name])); handleRefresh(); } finally { hideLoading(); @@ -71,6 +69,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, rowConfig: { keyField: 'id', + isHover: true, }, toolbarConfig: { refresh: true, diff --git a/apps/web-antd/src/views/ai/model/tool/modules/form.vue b/apps/web-antd/src/views/ai/model/tool/modules/form.vue index eeb720d13..3e3c90e78 100644 --- a/apps/web-antd/src/views/ai/model/tool/modules/form.vue +++ b/apps/web-antd/src/views/ai/model/tool/modules/form.vue @@ -76,7 +76,7 @@ const [Modal, modalApi] = useVbenModal({ diff --git a/packages/constants/src/dict-enum.ts b/packages/constants/src/dict-enum.ts index 7ced37eb7..c2ffca955 100644 --- a/packages/constants/src/dict-enum.ts +++ b/packages/constants/src/dict-enum.ts @@ -143,6 +143,7 @@ const AI_DICT = { AI_WRITE_LENGTH: 'ai_write_length', // AI 写作长度 AI_WRITE_TONE: 'ai_write_tone', // AI 写作语气 AI_WRITE_TYPE: 'ai_write_type', // AI 写作类型 + AI_MCP_CLIENT_NAME: 'ai_mcp_client_name', // AI MCP Client 名字 } as const; /** ========== IOT - 物联网模块 ========== */