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 - 物联网模块 ========== */