diff --git a/apps/web-antd/src/router/routes/modules/crm.ts b/apps/web-antd/src/router/routes/modules/crm.ts index 19cdcd65..9936204d 100644 --- a/apps/web-antd/src/router/routes/modules/crm.ts +++ b/apps/web-antd/src/router/routes/modules/crm.ts @@ -73,7 +73,7 @@ const routes: RouteRecordRaw[] = [ title: '联系人详情', activePath: '/crm/contact', }, - component: () => import('#/views/crm/contact/modules/detail.vue'), + component: () => import('#/views/crm/contact/detail/index.vue'), }, { path: 'product/detail/:id', diff --git a/apps/web-antd/src/views/crm/clue/data.ts b/apps/web-antd/src/views/crm/clue/data.ts index efbdfcc1..fd8a1e5b 100644 --- a/apps/web-antd/src/views/crm/clue/data.ts +++ b/apps/web-antd/src/views/crm/clue/data.ts @@ -26,6 +26,9 @@ export function useFormSchema(): VbenFormSchema[] { label: '线索名称', component: 'Input', rules: 'required', + componentProps: { + placeholder: '请输入线索名称', + }, }, { fieldName: 'source', @@ -33,6 +36,7 @@ export function useFormSchema(): VbenFormSchema[] { component: 'Select', componentProps: { options: getDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE, 'number'), + placeholder: '请选择客户来源', }, rules: 'required', }, @@ -40,6 +44,9 @@ export function useFormSchema(): VbenFormSchema[] { fieldName: 'mobile', label: '手机', component: 'Input', + componentProps: { + placeholder: '请输入手机号', + }, }, { fieldName: 'ownerUserId', @@ -50,6 +57,7 @@ export function useFormSchema(): VbenFormSchema[] { labelField: 'nickname', valueField: 'id', allowClear: true, + placeholder: '请选择负责人', }, defaultValue: userStore.userInfo?.id, rules: 'required', @@ -58,21 +66,33 @@ export function useFormSchema(): VbenFormSchema[] { fieldName: 'telephone', label: '电话', component: 'Input', + componentProps: { + placeholder: '请输入电话', + }, }, { fieldName: 'email', label: '邮箱', component: 'Input', + componentProps: { + placeholder: '请输入邮箱', + }, }, { fieldName: 'wechat', label: '微信', component: 'Input', + componentProps: { + placeholder: '请输入微信', + }, }, { fieldName: 'qq', label: 'QQ', component: 'Input', + componentProps: { + placeholder: '请输入 QQ', + }, }, { fieldName: 'industryId', @@ -80,6 +100,7 @@ export function useFormSchema(): VbenFormSchema[] { component: 'Select', componentProps: { options: getDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY, 'number'), + placeholder: '请选择客户行业', }, }, { @@ -88,6 +109,7 @@ export function useFormSchema(): VbenFormSchema[] { component: 'Select', componentProps: { options: getDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL, 'number'), + placeholder: '请选择客户级别', }, }, { @@ -97,12 +119,16 @@ export function useFormSchema(): VbenFormSchema[] { componentProps: { api: () => getAreaTree(), fieldNames: { label: 'name', value: 'id', children: 'children' }, + placeholder: '请选择地址', }, }, { fieldName: 'detailAddress', label: '详细地址', component: 'Input', + componentProps: { + placeholder: '请输入详细地址', + }, }, { fieldName: 'contactNextTime', @@ -112,12 +138,16 @@ export function useFormSchema(): VbenFormSchema[] { showTime: true, format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'x', + placeholder: '请选择下次联系时间', }, }, { fieldName: 'remark', label: '备注', component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + }, }, ]; } @@ -129,6 +159,10 @@ export function useGridFormSchema(): VbenFormSchema[] { fieldName: 'name', label: '线索名称', component: 'Input', + componentProps: { + placeholder: '请输入线索名称', + allowClear: true, + }, }, { fieldName: 'transformStatus', @@ -139,6 +173,8 @@ export function useGridFormSchema(): VbenFormSchema[] { { label: '未转化', value: false }, { label: '已转化', value: true }, ], + placeholder: '请选择转化状态', + allowClear: true, }, defaultValue: false, }, @@ -146,11 +182,19 @@ export function useGridFormSchema(): VbenFormSchema[] { fieldName: 'mobile', label: '手机号', component: 'Input', + componentProps: { + placeholder: '请输入手机号', + allowClear: true, + }, }, { fieldName: 'telephone', label: '电话', component: 'Input', + componentProps: { + placeholder: '请输入电话', + allowClear: true, + }, }, { fieldName: 'createTime', @@ -159,6 +203,7 @@ export function useGridFormSchema(): VbenFormSchema[] { componentProps: { ...getRangePickerDefaultProps(), allowClear: true, + placeholder: ['开始日期', '结束日期'], }, }, ]; diff --git a/apps/web-antd/src/views/crm/contact/data.ts b/apps/web-antd/src/views/crm/contact/data.ts index 788730e1..a1fe70f2 100644 --- a/apps/web-antd/src/views/crm/contact/data.ts +++ b/apps/web-antd/src/views/crm/contact/data.ts @@ -27,17 +27,22 @@ export function useFormSchema(): VbenFormSchema[] { label: '联系人姓名', component: 'Input', rules: 'required', + componentProps: { + placeholder: '请输入联系人姓名', + }, }, { fieldName: 'ownerUserId', label: '负责人', component: 'ApiSelect', + rules: 'required', componentProps: { api: () => getSimpleUserList(), fieldNames: { label: 'nickname', value: 'id', }, + placeholder: '请选择负责人', }, defaultValue: userStore.userInfo?.id, }, @@ -45,51 +50,75 @@ export function useFormSchema(): VbenFormSchema[] { fieldName: 'customerId', label: '客户名称', component: 'ApiSelect', + rules: 'required', componentProps: { api: () => getCustomerSimpleList(), fieldNames: { label: 'name', value: 'id', }, + placeholder: '请选择客户', }, }, { fieldName: 'mobile', label: '手机', component: 'Input', + componentProps: { + placeholder: '请输入手机号', + }, }, { fieldName: 'telephone', label: '电话', component: 'Input', + componentProps: { + placeholder: '请输入电话', + }, }, { fieldName: 'email', label: '邮箱', component: 'Input', + componentProps: { + placeholder: '请输入邮箱', + }, }, { fieldName: 'wechat', label: '微信', component: 'Input', + componentProps: { + placeholder: '请输入微信', + }, }, { fieldName: 'qq', label: 'QQ', component: 'Input', + componentProps: { + placeholder: '请输入QQ', + }, }, { fieldName: 'post', label: '职位', component: 'Input', + componentProps: { + placeholder: '请输入职位', + }, }, { fieldName: 'master', label: '关键决策人', - component: 'Select', + component: 'RadioGroup', componentProps: { options: getDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING, 'boolean'), + placeholder: '请选择是否关键决策人', + buttonStyle: 'solid', + optionType: 'button', }, + defaultValue: false, }, { fieldName: 'sex', @@ -97,6 +126,7 @@ export function useFormSchema(): VbenFormSchema[] { component: 'Select', componentProps: { options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX, 'number'), + placeholder: '请选择性别', }, }, { @@ -109,6 +139,7 @@ export function useFormSchema(): VbenFormSchema[] { label: 'name', value: 'id', }, + placeholder: '请选择直属上级', }, }, { @@ -118,12 +149,16 @@ export function useFormSchema(): VbenFormSchema[] { componentProps: { api: () => getAreaTree(), fieldNames: { label: 'name', value: 'id', children: 'children' }, + placeholder: '请选择地址', }, }, { fieldName: 'detailAddress', label: '详细地址', component: 'Input', + componentProps: { + placeholder: '请输入详细地址', + }, }, { fieldName: 'contactNextTime', @@ -133,12 +168,16 @@ export function useFormSchema(): VbenFormSchema[] { showTime: true, format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'x', + placeholder: '请选择下次联系时间', }, }, { fieldName: 'remark', label: '备注', component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + }, }, ]; } @@ -147,7 +186,7 @@ export function useFormSchema(): VbenFormSchema[] { export function useGridFormSchema(): VbenFormSchema[] { return [ { - fieldName: 'name', + fieldName: 'customerId', label: '客户', component: 'ApiSelect', componentProps: { @@ -156,32 +195,54 @@ export function useGridFormSchema(): VbenFormSchema[] { label: 'name', value: 'id', }, + placeholder: '请选择客户', + allowClear: true, }, }, { fieldName: 'name', label: '姓名', component: 'Input', + componentProps: { + placeholder: '请输入联系人姓名', + allowClear: true, + }, }, { fieldName: 'mobile', label: '手机号', component: 'Input', + componentProps: { + placeholder: '请输入手机号', + allowClear: true, + }, }, { fieldName: 'telephone', label: '电话', component: 'Input', + componentProps: { + placeholder: '请输入电话', + allowClear: true, + }, }, { fieldName: 'wechat', label: '微信', component: 'Input', + componentProps: { + placeholder: '请输入微信', + allowClear: true, + }, }, { fieldName: 'email', label: '电子邮箱', component: 'Input', + componentProps: { + placeholder: '请输入电子邮箱', + allowClear: true, + }, }, ]; } @@ -203,15 +264,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { minWidth: 240, slots: { default: 'customerName' }, }, - { - field: 'sex', - title: '性别', - minWidth: 120, - cellRender: { - name: 'CellDict', - props: { type: DICT_TYPE.SYSTEM_USER_SEX }, - }, - }, { field: 'mobile', title: '手机', @@ -220,12 +272,12 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { { field: 'telephone', title: '电话', - minWidth: 120, + minWidth: 130, }, { field: 'email', title: '邮箱', - minWidth: 120, + minWidth: 180, }, { field: 'post', @@ -233,10 +285,15 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { minWidth: 120, }, { - field: 'detailAddress', + field: 'areaName', title: '地址', minWidth: 120, }, + { + field: 'detailAddress', + title: '详细地址', + minWidth: 180, + }, { field: 'master', title: '关键决策人', @@ -252,6 +309,32 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { minWidth: 120, slots: { default: 'parentId' }, }, + { + field: 'contactNextTime', + title: '下次联系时间', + formatter: 'formatDateTime', + minWidth: 180, + }, + { + field: 'sex', + title: '性别', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.SYSTEM_USER_SEX }, + }, + }, + { + field: 'remark', + title: '备注', + minWidth: 200, + }, + { + field: 'contactLastTime', + title: '最后跟进时间', + formatter: 'formatDateTime', + minWidth: 180, + }, { field: 'ownerUserName', title: '负责人', @@ -263,16 +346,11 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { minWidth: 120, }, { - field: 'contactNextTime', - title: '下次联系时间', + field: 'updateTime', + title: '更新时间', formatter: 'formatDateTime', minWidth: 180, }, - { - field: 'remark', - title: '备注', - minWidth: 200, - }, { field: 'createTime', title: '创建时间', @@ -280,10 +358,9 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { minWidth: 180, }, { - field: 'updateTime', - title: '更新时间', - formatter: 'formatDateTime', - minWidth: 180, + field: 'creatorName', + title: '创建人', + minWidth: 120, }, { title: '操作', diff --git a/apps/web-antd/src/views/crm/contact/modules/detail-data.ts b/apps/web-antd/src/views/crm/contact/detail/data.ts similarity index 100% rename from apps/web-antd/src/views/crm/contact/modules/detail-data.ts rename to apps/web-antd/src/views/crm/contact/detail/data.ts diff --git a/apps/web-antd/src/views/crm/contact/modules/detail.vue b/apps/web-antd/src/views/crm/contact/detail/index.vue similarity index 98% rename from apps/web-antd/src/views/crm/contact/modules/detail.vue rename to apps/web-antd/src/views/crm/contact/detail/index.vue index 48c4febe..c758b923 100644 --- a/apps/web-antd/src/views/crm/contact/modules/detail.vue +++ b/apps/web-antd/src/views/crm/contact/detail/index.vue @@ -20,7 +20,7 @@ import { ContactDetailsInfo, ContactForm } from '#/views/crm/contact'; import { FollowUp } from '#/views/crm/followup'; import { PermissionList, TransferForm } from '#/views/crm/permission'; -import { useDetailSchema } from './detail-data'; +import { useDetailSchema } from './data'; const loading = ref(false); diff --git a/apps/web-antd/src/views/crm/contact/modules/detail-info.vue b/apps/web-antd/src/views/crm/contact/detail/modules/detail-info.vue similarity index 94% rename from apps/web-antd/src/views/crm/contact/modules/detail-info.vue rename to apps/web-antd/src/views/crm/contact/detail/modules/detail-info.vue index e9b8c1ac..b47c6da3 100644 --- a/apps/web-antd/src/views/crm/contact/modules/detail-info.vue +++ b/apps/web-antd/src/views/crm/contact/detail/modules/detail-info.vue @@ -6,7 +6,7 @@ import { Divider } from 'ant-design-vue'; import { useDescription } from '#/components/description'; import { useFollowUpDetailSchema } from '#/views/crm/followup/data'; -import { useDetailBaseSchema } from './detail-data'; +import { useDetailBaseSchema } from '../data'; defineProps<{ contact: CrmContactApi.Contact; // 联系人信息 diff --git a/apps/web-antd/src/views/crm/contact/modules/detail-list.vue b/apps/web-antd/src/views/crm/contact/detail/modules/detail-list.vue similarity index 97% rename from apps/web-antd/src/views/crm/contact/modules/detail-list.vue rename to apps/web-antd/src/views/crm/contact/detail/modules/detail-list.vue index a9254670..24b1ad21 100644 --- a/apps/web-antd/src/views/crm/contact/modules/detail-list.vue +++ b/apps/web-antd/src/views/crm/contact/detail/modules/detail-list.vue @@ -19,9 +19,9 @@ import { import { BizTypeEnum } from '#/api/crm/permission'; import { $t } from '#/locales'; -import { useDetailListColumns } from './detail-data'; -import ListModal from './detail-list-modal.vue'; -import Form from './form.vue'; +import ListModal from '../../modules/detail-list-modal.vue'; +import Form from '../../modules/form.vue'; +import { useDetailListColumns } from '../data'; const props = defineProps<{ bizId: number; // 业务编号 diff --git a/apps/web-antd/src/views/crm/contact/index.ts b/apps/web-antd/src/views/crm/contact/index.ts index e19127cf..16ce8d9d 100644 --- a/apps/web-antd/src/views/crm/contact/index.ts +++ b/apps/web-antd/src/views/crm/contact/index.ts @@ -1,17 +1,13 @@ import { defineAsyncComponent } from 'vue'; export const ContactDetailsInfo = defineAsyncComponent( - () => import('./modules/detail-info.vue'), + () => import('./detail/modules/detail-info.vue'), ); export const ContactForm = defineAsyncComponent( () => import('./modules/form.vue'), ); -export const ContactDetails = defineAsyncComponent( - () => import('./modules/detail.vue'), -); - export const ContactDetailsList = defineAsyncComponent( - () => import('./modules/detail-list.vue'), + () => import('./detail/modules/detail-list.vue'), ); diff --git a/apps/web-antd/src/views/crm/contact/index.vue b/apps/web-antd/src/views/crm/contact/index.vue index de13da97..de6d1b8a 100644 --- a/apps/web-antd/src/views/crm/contact/index.vue +++ b/apps/web-antd/src/views/crm/contact/index.vue @@ -30,13 +30,17 @@ const [FormModal, formModalApi] = useVbenModal({ }); /** 刷新表格 */ -function onRefresh() { +function handleRefresh() { gridApi.query(); } /** 导出表格 */ async function handleExport() { - const data = await exportContact(await gridApi.formApi.getValues()); + const formValues = await gridApi.formApi.getValues(); + const data = await exportContact({ + sceneType: sceneType.value, + ...formValues, + }); downloadFileFromBlobPart({ fileName: '联系人.xls', source: data }); } @@ -58,10 +62,8 @@ async function handleDelete(row: CrmContactApi.Contact) { }); try { await deleteContact(row.id as number); - message.success({ - content: $t('ui.actionMessage.deleteSuccess', [row.name]), - }); - onRefresh(); + message.success($t('ui.actionMessage.deleteSuccess', [row.name])); + handleRefresh(); } finally { hideLoading(); } @@ -77,6 +79,12 @@ function handleCustomerDetail(row: CrmContactApi.Contact) { push({ name: 'CrmCustomerDetail', params: { id: row.customerId } }); } +/** 处理场景类型的切换 */ +function handleChangeSceneType(key: number | string) { + sceneType.value = key.toString(); + gridApi.query(); +} + const [Grid, gridApi] = useVbenVxeGrid({ formOptions: { schema: useGridFormSchema(), @@ -99,6 +107,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, rowConfig: { keyField: 'id', + isHover: true, }, toolbarConfig: { refresh: true, @@ -106,11 +115,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, } as VxeTableGridOptions, }); - -function onChangeSceneType(key: number | string) { - sceneType.value = key.toString(); - gridApi.query(); -} - + + diff --git a/apps/web-antd/src/views/crm/contact/modules/detail-list-modal.vue b/apps/web-antd/src/views/crm/contact/modules/detail-list-modal.vue index 0fdcc605..5c39073f 100644 --- a/apps/web-antd/src/views/crm/contact/modules/detail-list-modal.vue +++ b/apps/web-antd/src/views/crm/contact/modules/detail-list-modal.vue @@ -1,4 +1,5 @@ + + + diff --git a/apps/web-ele/src/components/cron-tab/index.ts b/apps/web-ele/src/components/cron-tab/index.ts new file mode 100644 index 00000000..8f4baae5 --- /dev/null +++ b/apps/web-ele/src/components/cron-tab/index.ts @@ -0,0 +1 @@ +export { default as CronTab } from './cron-tab.vue'; diff --git a/apps/web-ele/src/components/upload/file-upload.vue b/apps/web-ele/src/components/upload/file-upload.vue index 39b6d529..43bee52d 100644 --- a/apps/web-ele/src/components/upload/file-upload.vue +++ b/apps/web-ele/src/components/upload/file-upload.vue @@ -1,261 +1,282 @@ - + diff --git a/apps/web-ele/src/components/upload/use-upload.ts b/apps/web-ele/src/components/upload/use-upload.ts index 52f723be..2f46f9e9 100644 --- a/apps/web-ele/src/components/upload/use-upload.ts +++ b/apps/web-ele/src/components/upload/use-upload.ts @@ -79,17 +79,17 @@ export function useUploadType({ } // TODO @芋艿:目前保持和 admin-vue3 一致,后续可能重构 -export const useUpload = (directory?: string) => { +export function useUpload(directory?: string) { // 后端上传地址 const uploadUrl = getUploadUrl(); // 是否使用前端直连上传 const isClientUpload = UPLOAD_TYPE.CLIENT === import.meta.env.VITE_UPLOAD_TYPE; // 重写ElUpload上传方法 - const httpRequest = async ( + async function httpRequest( file: File, onUploadProgress?: AxiosProgressEvent, - ) => { + ) { // 模式一:前端上传 if (isClientUpload) { // 1.1 生成文件名称 @@ -113,20 +113,20 @@ export const useUpload = (directory?: string) => { // 模式二:后端上传 return uploadFile({ file, directory }, onUploadProgress); } - }; + } return { uploadUrl, httpRequest, }; -}; +} /** * 获得上传 URL */ -export const getUploadUrl = (): string => { +export function getUploadUrl(): string { return `${apiURL}/infra/file/upload`; -}; +} /** * 创建文件信息 @@ -134,7 +134,10 @@ export const getUploadUrl = (): string => { * @param vo 文件预签名信息 * @param file 文件 */ -function createFile0(vo: InfraFileApi.FilePresignedUrlRespVO, file: File) { +function createFile0( + vo: InfraFileApi.FilePresignedUrlRespVO, + file: File, +): InfraFileApi.File { const fileVO = { configId: vo.configId, url: vo.url, @@ -148,10 +151,18 @@ function createFile0(vo: InfraFileApi.FilePresignedUrlRespVO, file: File) { } /** - * 生成文件名称 + * 生成文件名称(使用算法SHA256) * * @param file 要上传的文件 */ async function generateFileName(file: File) { + // // 读取文件内容 + // const data = await file.arrayBuffer(); + // const wordArray = CryptoJS.lib.WordArray.create(data); + // // 计算SHA256 + // const sha256 = CryptoJS.SHA256(wordArray).toString(); + // // 拼接后缀 + // const ext = file.name.slice(Math.max(0, file.name.lastIndexOf('.'))); + // return `${sha256}${ext}`; return file.name; } diff --git a/apps/web-ele/src/views/infra/codegen/modules/preview-code.vue b/apps/web-ele/src/views/infra/codegen/modules/preview-code.vue index de4486fc..f9e3df64 100644 --- a/apps/web-ele/src/views/infra/codegen/modules/preview-code.vue +++ b/apps/web-ele/src/views/infra/codegen/modules/preview-code.vue @@ -7,7 +7,7 @@ import type { InfraCodegenApi } from '#/api/infra/codegen'; import { ref } from 'vue'; import { useVbenModal } from '@vben/common-ui'; -import { Copy } from '@vben/icons'; +import { IconifyIcon } from '@vben/icons'; import { useClipboard } from '@vueuse/core'; import { ElMessage, ElTabPane, ElTabs, ElTree } from 'element-plus'; @@ -291,8 +291,7 @@ const [Modal, modalApi] = useVbenModal({ diff --git a/apps/web-ele/src/views/infra/file/data.ts b/apps/web-ele/src/views/infra/file/data.ts index 56d58313..3e97d47f 100644 --- a/apps/web-ele/src/views/infra/file/data.ts +++ b/apps/web-ele/src/views/infra/file/data.ts @@ -9,7 +9,7 @@ export function useFormSchema(): VbenFormSchema[] { { fieldName: 'file', label: '文件上传', - component: 'Upload', + component: 'FileUpload', componentProps: { placeholder: '请选择要上传的文件', }, diff --git a/apps/web-ele/src/views/infra/file/modules/form.vue b/apps/web-ele/src/views/infra/file/modules/form.vue index 558c8ae4..1135c4ad 100644 --- a/apps/web-ele/src/views/infra/file/modules/form.vue +++ b/apps/web-ele/src/views/infra/file/modules/form.vue @@ -1,19 +1,19 @@ diff --git a/apps/web-ele/src/views/infra/job/data.ts b/apps/web-ele/src/views/infra/job/data.ts index 78b3b187..e2acb01a 100644 --- a/apps/web-ele/src/views/infra/job/data.ts +++ b/apps/web-ele/src/views/infra/job/data.ts @@ -3,7 +3,7 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { InfraJobApi } from '#/api/infra/job'; import type { DescriptionItemSchema } from '#/components/description'; -import { h } from 'vue'; +import { h, markRaw } from 'vue'; import { DICT_TYPE } from '@vben/constants'; import { getDictOptions } from '@vben/hooks'; @@ -11,6 +11,7 @@ import { formatDateTime } from '@vben/utils'; import { ElTimeline, ElTimelineItem } from 'element-plus'; +import { CronTab } from '#/components/cron-tab'; import { DictTag } from '#/components/dict-tag'; /** 新增/修改的表单 */ @@ -57,12 +58,11 @@ export function useFormSchema(): VbenFormSchema[] { { fieldName: 'cronExpression', label: 'CRON 表达式', - component: 'Input', + component: markRaw(CronTab), componentProps: { placeholder: '请输入 CRON 表达式', }, rules: 'required', - // TODO @芋艿:未来支持动态的 CRON 表达式选择 }, { fieldName: 'retryCount', @@ -71,6 +71,8 @@ export function useFormSchema(): VbenFormSchema[] { componentProps: { placeholder: '请输入重试次数。设置为 0 时,不进行重试', min: 0, + controlsPosition: 'right', + class: '!w-full', }, rules: 'required', }, @@ -81,6 +83,8 @@ export function useFormSchema(): VbenFormSchema[] { componentProps: { placeholder: '请输入重试间隔,单位:毫秒。设置为 0 时,无需间隔', min: 0, + controlsPosition: 'right', + class: '!w-full', }, rules: 'required', }, @@ -91,6 +95,8 @@ export function useFormSchema(): VbenFormSchema[] { componentProps: { placeholder: '请输入监控超时时间,单位:毫秒', min: 0, + controlsPosition: 'right', + class: '!w-full', }, }, ];