From 041e3f6e2d054a55367da0d08d99341f3442dbb5 Mon Sep 17 00:00:00 2001 From: XuZhiqiang Date: Wed, 17 Jun 2026 11:25:07 +0800 Subject: [PATCH 01/15] =?UTF-8?q?fix(@vben/web-antdv-next):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20Tree=20=E9=80=89=E4=B8=AD=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=E6=97=A7=20dataRef=20=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E5=A4=B1=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/mes/md/item/type/components/tree.vue | 13 +++++++++++-- .../views/system/dept/components/tree-select.vue | 8 ++++++-- .../src/views/system/user/modules/dept-tree.vue | 8 ++++++-- .../views/wms/md/item/category/components/tree.vue | 13 +++++++++++-- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/apps/web-antdv-next/src/views/mes/md/item/type/components/tree.vue b/apps/web-antdv-next/src/views/mes/md/item/type/components/tree.vue index 347e87b6a..acb3ad22b 100644 --- a/apps/web-antdv-next/src/views/mes/md/item/type/components/tree.vue +++ b/apps/web-antdv-next/src/views/mes/md/item/type/components/tree.vue @@ -54,8 +54,17 @@ function handleSearch(value: string) { } /** 处理节点点击:支持点击同一节点取消选中 */ -function handleSelect(_selectedKeys: any[], info: any) { - const row = info.node.dataRef as MesMdItemTypeApi.ItemType; +function handleSelect(selectedNodeKeys: any[], info: any) { + const selectedKey = selectedNodeKeys[0] ?? info.node?.id ?? info.node?.key; + const row = itemTypeList.value.find( + (item) => String(item.id) === String(selectedKey), + ); + if (!row) { + currentNodeId.value = undefined; + selectedKeys.value = []; + emit('nodeClick', undefined); + return; + } if (currentNodeId.value === row.id) { currentNodeId.value = undefined; selectedKeys.value = []; diff --git a/apps/web-antdv-next/src/views/system/dept/components/tree-select.vue b/apps/web-antdv-next/src/views/system/dept/components/tree-select.vue index cf66a0733..7054d3c82 100644 --- a/apps/web-antdv-next/src/views/system/dept/components/tree-select.vue +++ b/apps/web-antdv-next/src/views/system/dept/components/tree-select.vue @@ -38,8 +38,12 @@ function handleSearch(e: any) { } /** 选中部门:点击已选中的节点时取消选中 */ -function handleSelect(_selectedKeys: any[], info: any) { - emit('select', info.selected ? info.node.dataRef : undefined); +function handleSelect(selectedNodeKeys: any[], info: any) { + const selectedKey = selectedNodeKeys[0]; + const dept = info.selected + ? deptList.value.find((item) => String(item.id) === String(selectedKey)) + : undefined; + emit('select', dept); } /** 重置选中状态(供外部重置按钮调用) */ diff --git a/apps/web-antdv-next/src/views/system/user/modules/dept-tree.vue b/apps/web-antdv-next/src/views/system/user/modules/dept-tree.vue index beea3f314..48ffe69c4 100644 --- a/apps/web-antdv-next/src/views/system/user/modules/dept-tree.vue +++ b/apps/web-antdv-next/src/views/system/user/modules/dept-tree.vue @@ -32,8 +32,12 @@ function handleSearch(e: any) { } /** 选中部门 */ -function handleSelect(_selectedKeys: any[], info: any) { - emit('select', info.node.dataRef); +function handleSelect(selectedNodeKeys: any[], info: any) { + const selectedKey = selectedNodeKeys[0] ?? info.node?.id ?? info.node?.key; + const dept = info.selected + ? deptList.value.find((item) => String(item.id) === String(selectedKey)) + : undefined; + emit('select', dept); } /** 初始化 */ diff --git a/apps/web-antdv-next/src/views/wms/md/item/category/components/tree.vue b/apps/web-antdv-next/src/views/wms/md/item/category/components/tree.vue index 7954aea91..e682d58c9 100644 --- a/apps/web-antdv-next/src/views/wms/md/item/category/components/tree.vue +++ b/apps/web-antdv-next/src/views/wms/md/item/category/components/tree.vue @@ -55,8 +55,17 @@ function handleSearch(value: string) { } /** 处理节点点击:支持点击同一节点取消选中 */ -function handleSelect(_selectedKeys: any[], info: any) { - const row = info.node.dataRef as WmsItemCategoryApi.ItemCategory; +function handleSelect(selectedNodeKeys: any[], info: any) { + const selectedKey = selectedNodeKeys[0] ?? info.node?.id ?? info.node?.key; + const row = categoryList.value.find( + (item) => String(item.id) === String(selectedKey), + ); + if (!row) { + currentNodeId.value = undefined; + selectedKeys.value = []; + emit('nodeClick', undefined); + return; + } if (currentNodeId.value === row.id) { currentNodeId.value = undefined; selectedKeys.value = []; From 6951bd68a12d8473ca419ff1ef41f4f227e59358 Mon Sep 17 00:00:00 2001 From: XuZhiqiang Date: Wed, 17 Jun 2026 13:24:57 +0800 Subject: [PATCH 02/15] =?UTF-8?q?feat(@vben/web-antdv-next):=20BPM?= =?UTF-8?q?=E6=8B=92=E7=BB=9D=E5=8F=AF=E4=BB=A5=E6=B7=BB=E5=8A=A0=E9=99=84?= =?UTF-8?q?=E4=BB=B6=E4=B8=8A=E4=BC=A0=E5=8A=9F=E8=83=BD=E8=87=B3=E5=AE=A1?= =?UTF-8?q?=E6=89=B9=E8=A1=A8=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/bpm/processInstance/index.ts | 1 + .../detail/modules/operation-button.vue | 80 ++++++++++++++++++- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/apps/web-antdv-next/src/api/bpm/processInstance/index.ts b/apps/web-antdv-next/src/api/bpm/processInstance/index.ts index 7ee5421f8..f8442c35c 100644 --- a/apps/web-antdv-next/src/api/bpm/processInstance/index.ts +++ b/apps/web-antdv-next/src/api/bpm/processInstance/index.ts @@ -83,6 +83,7 @@ export namespace BpmProcessInstanceApi { reason: string; signPicUrl: string; status: number; + attachments?: string[]; } /** 抄送流程实例 */ diff --git a/apps/web-antdv-next/src/views/bpm/processInstance/detail/modules/operation-button.vue b/apps/web-antdv-next/src/views/bpm/processInstance/detail/modules/operation-button.vue index 423cd8daf..8afd72618 100644 --- a/apps/web-antdv-next/src/views/bpm/processInstance/detail/modules/operation-button.vue +++ b/apps/web-antdv-next/src/views/bpm/processInstance/detail/modules/operation-button.vue @@ -55,6 +55,7 @@ import { transferTask, } from '#/api/bpm/task'; import { setConfAndFields2 } from '#/components/form-create'; +import { FileUpload } from '#/components/upload'; import { $t } from '#/locales'; import Signature from './signature.vue'; @@ -120,6 +121,7 @@ const approveReasonForm: any = reactive({ reason: '', signPicUrl: '', nextAssignees: {}, + attachments: [], }); const approveReasonRule: Record = computed(() => { return { @@ -140,7 +142,8 @@ const approveReasonRule: Record = computed(() => { }); const rejectFormRef = ref(); -const rejectReasonForm = reactive({ +const rejectReasonForm = reactive<{ attachments: string[]; reason: string }>({ + attachments: [], reason: '', }); // 拒绝表单 const rejectReasonRule: any = computed(() => { @@ -290,6 +293,14 @@ function closePopover(type: string, formRef: any | FormInstance) { if (formRef) { formRef.resetFields(); } + if (type === 'approve') { + approveReasonForm.reason = ''; + approveReasonForm.attachments = []; + approveReasonForm.signPicUrl = ''; + } else if (type === 'reject') { + rejectReasonForm.reason = ''; + rejectReasonForm.attachments = []; + } if (popOverVisible.value[type]) popOverVisible.value[type] = false; nextAssigneesActivityNode.value = []; // 清理 Timeline 组件中的自定义审批人数据 @@ -401,6 +412,7 @@ async function handleAudit(pass: boolean, formRef: FormInstance | undefined) { const data = { id: runningTask.value.id, reason: approveReasonForm.reason, + attachments: approveReasonForm.attachments, variables, // 审批通过, 把修改的字段值赋于流程实例变量 nextAssignees: approveReasonForm.nextAssignees, // 下个自选节点选择的审批人信息 } as any; @@ -414,6 +426,9 @@ async function handleAudit(pass: boolean, formRef: FormInstance | undefined) { await formCreateApi.validate(); } await approveTask(data); + approveReasonForm.reason = ''; + approveReasonForm.attachments = []; + approveReasonForm.signPicUrl = ''; popOverVisible.value.approve = false; nextAssigneesActivityNode.value = []; // 清理 Timeline 组件中的自定义审批人数据 @@ -425,9 +440,12 @@ async function handleAudit(pass: boolean, formRef: FormInstance | undefined) { // 审批不通过数据 const data = { id: runningTask.value.id, + attachments: rejectReasonForm.attachments, reason: rejectReasonForm.reason, }; await rejectTask(data); + rejectReasonForm.reason = ''; + rejectReasonForm.attachments = []; popOverVisible.value.reject = false; message.success('审批不通过成功'); } @@ -748,6 +766,38 @@ function handleSignFinish(url: string) { approveFormRef.value?.validateFields(['signPicUrl']); } +/** 附件图片预览 */ +const imagePreviewOpen = ref(false); +const imagePreviewUrl = ref(''); + +/** 判断文件是否为图片类型 */ +function isImageUrl(url: string) { + return /\.(bmp|gif|jpe?g|png|svg|webp)$/i.test(url); +} + +/** 处理文件预览 */ +function handleFilePreview(file: any) { + if (!file?.url && !file?.response) { + message.warning('文件地址不存在,无法预览'); + return; + } + const url = file.url || file?.response?.url || file?.response; + if (!url) { + message.warning('文件地址不存在,无法预览'); + return; + } + if (isImageUrl(url)) { + imagePreviewUrl.value = url; + imagePreviewOpen.value = true; + } else { + window.open(url, '_blank'); + } +} + +function handleImagePreviewOpenChange(open: boolean) { + imagePreviewOpen.value = open; +} + /** 处理弹窗可见性 */ function handlePopoverVisible(visible: boolean) { if (!visible) { @@ -843,6 +893,15 @@ defineExpose({ loadTodoTask }); :rows="4" /> + + + From 2fc5575c304a3646e4e83b04a407baefe8e1beec Mon Sep 17 00:00:00 2001 From: XuZhiqiang Date: Wed, 17 Jun 2026 21:28:10 +0800 Subject: [PATCH 08/15] =?UTF-8?q?fix(web-antdv-next):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=20DateRangePicker=20=E5=85=B1=E4=BA=AB=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E7=9A=84=E4=BA=8C=E5=85=83=E7=BB=84=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/utils/rangePickerProps.ts | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/apps/web-antdv-next/src/utils/rangePickerProps.ts b/apps/web-antdv-next/src/utils/rangePickerProps.ts index 2ba4be294..df52a2dc1 100644 --- a/apps/web-antdv-next/src/utils/rangePickerProps.ts +++ b/apps/web-antdv-next/src/utils/rangePickerProps.ts @@ -1,7 +1,16 @@ +import type { Dayjs } from 'dayjs'; + import dayjs from 'dayjs'; import { $t } from '#/locales'; +type DateRangeTuple = [Dayjs, Dayjs]; +type StringRangeTuple = [string, string]; + +function dateRange(start: Dayjs, end: Dayjs): DateRangeTuple { + return [start, end]; +} + /** 时间段选择器拓展 */ export function getRangePickerDefaultProps() { return { @@ -13,55 +22,55 @@ export function getRangePickerDefaultProps() { placeholder: [ $t('utils.rangePicker.beginTime'), $t('utils.rangePicker.endTime'), - ], + ] as StringRangeTuple, // 快捷时间范围 presets: [ { label: $t('utils.rangePicker.today'), - value: [dayjs().startOf('day'), dayjs().endOf('day')], + value: dateRange(dayjs().startOf('day'), dayjs().endOf('day')), }, { label: $t('utils.rangePicker.last7Days'), - value: [ + value: dateRange( dayjs().subtract(7, 'day').startOf('day'), dayjs().endOf('day'), - ], + ), }, { label: $t('utils.rangePicker.last30Days'), - value: [ + value: dateRange( dayjs().subtract(30, 'day').startOf('day'), dayjs().endOf('day'), - ], + ), }, { label: $t('utils.rangePicker.yesterday'), - value: [ + value: dateRange( dayjs().subtract(1, 'day').startOf('day'), dayjs().subtract(1, 'day').endOf('day'), - ], + ), }, { label: $t('utils.rangePicker.thisWeek'), - value: [dayjs().startOf('week'), dayjs().endOf('day')], + value: dateRange(dayjs().startOf('week'), dayjs().endOf('day')), }, { label: $t('utils.rangePicker.thisMonth'), - value: [dayjs().startOf('month'), dayjs().endOf('day')], + value: dateRange(dayjs().startOf('month'), dayjs().endOf('day')), }, { label: $t('utils.rangePicker.lastWeek'), - value: [ + value: dateRange( dayjs().subtract(1, 'week').startOf('day'), dayjs().endOf('day'), - ], + ), }, ], showTime: { - defaultValue: [ + defaultValue: dateRange( dayjs('00:00:00', 'HH:mm:ss'), dayjs('23:59:59', 'HH:mm:ss'), - ], + ), format: 'HH:mm:ss', }, }; From f152217c3cf13ae0fb1fded2d8a8fd3eae8178ef Mon Sep 17 00:00:00 2001 From: XuZhiqiang Date: Thu, 18 Jun 2026 14:21:12 +0800 Subject: [PATCH 09/15] fix(web-antdv-next): normalize date picker timestamp handling Add DatePicker and RangePicker adapter wrappers for numeric timestamp values, route direct value-format="x" usages through the adapter, and keep ShortcutDateRangePicker values as Dayjs. --- .../src/adapter/component/date-picker.ts | 86 +++++++++++++++++++ .../src/adapter/component/index.ts | 13 +-- .../shortcut-date-range-picker.vue | 1 - .../demo/general/demo01/modules/form.vue | 2 +- .../demo/general/demo03/erp/modules/form.vue | 2 +- .../general/demo03/inner/modules/form.vue | 2 +- .../general/demo03/normal/modules/form.vue | 2 +- 7 files changed, 94 insertions(+), 14 deletions(-) create mode 100644 apps/web-antdv-next/src/adapter/component/date-picker.ts diff --git a/apps/web-antdv-next/src/adapter/component/date-picker.ts b/apps/web-antdv-next/src/adapter/component/date-picker.ts new file mode 100644 index 000000000..2428cd4fb --- /dev/null +++ b/apps/web-antdv-next/src/adapter/component/date-picker.ts @@ -0,0 +1,86 @@ +import type { Component } from 'vue'; + +import type { Recordable } from '@vben/types'; + +import { defineAsyncComponent, defineComponent, h, ref } from 'vue'; + +const RawDatePicker = defineAsyncComponent( + () => import('antdv-next/dist/date-picker/index'), +); +const RawRangePicker = defineAsyncComponent(() => + import('antdv-next/dist/date-picker/index').then( + (res) => res.DateRangePicker, + ), +); + +const TIMESTAMP_VALUE_FORMATS = new Set(['x', 'X']); + +function isTimestampValueFormat(valueFormat: unknown) { + return ( + typeof valueFormat === 'string' && TIMESTAMP_VALUE_FORMATS.has(valueFormat) + ); +} + +function normalizeTimestampPickerValue(value: any, valueFormat: unknown): any { + if (!isTimestampValueFormat(valueFormat)) { + return value; + } + if (Array.isArray(value)) { + return value.map((item) => normalizeTimestampPickerValue(item, valueFormat)); + } + return typeof value === 'number' ? String(value) : value; +} + +function withTimestampValueFormat( + component: Component, + name: 'DatePicker' | 'RangePicker', +) { + return defineComponent({ + name, + inheritAttrs: false, + setup(_, { attrs, expose, slots }) { + const innerRef = ref(); + expose( + new Proxy( + {}, + { + get: (_target, key) => innerRef.value?.[key], + has: (_target, key) => key in (innerRef.value || {}), + }, + ), + ); + + return () => { + const pickerAttrs: Recordable = { ...attrs }; + if ( + 'value-format' in pickerAttrs && + !Reflect.has(pickerAttrs, 'valueFormat') + ) { + pickerAttrs.valueFormat = pickerAttrs['value-format']; + } + const valueFormat = pickerAttrs.valueFormat; + + for (const key of [ + 'value', + 'defaultValue', + 'pickerValue', + 'defaultPickerValue', + ]) { + if (Reflect.has(pickerAttrs, key)) { + pickerAttrs[key] = normalizeTimestampPickerValue( + pickerAttrs[key], + valueFormat, + ); + } + } + + return h(component, { ...pickerAttrs, ref: innerRef }, slots); + }; + }, + }); +} + +const DatePicker = withTimestampValueFormat(RawDatePicker, 'DatePicker'); +const RangePicker = withTimestampValueFormat(RawRangePicker, 'RangePicker'); + +export { DatePicker, RangePicker }; diff --git a/apps/web-antdv-next/src/adapter/component/index.ts b/apps/web-antdv-next/src/adapter/component/index.ts index 9a0897d5b..846473793 100644 --- a/apps/web-antdv-next/src/adapter/component/index.ts +++ b/apps/web-antdv-next/src/adapter/component/index.ts @@ -75,6 +75,9 @@ import { message, Modal, notification } from 'antdv-next'; import { uploadFile as uploadFileApi } from '#/api/infra/file'; import { Tinymce as RichTextarea } from '#/components/tinymce'; import { FileUpload, ImageUpload } from '#/components/upload'; + +import { DatePicker, RangePicker } from './date-picker'; + type AdapterUploadProps = UploadProps & { aspectRatio?: string; crop?: boolean; @@ -97,9 +100,6 @@ const Checkbox = defineAsyncComponent( const CheckboxGroup = defineAsyncComponent(() => import('antdv-next/dist/checkbox/index').then((res) => res.CheckboxGroup), ); -const DatePicker = defineAsyncComponent( - () => import('antdv-next/dist/date-picker/index'), -); const Divider = defineAsyncComponent( () => import('antdv-next/dist/divider/index'), ); @@ -117,11 +117,6 @@ const Radio = defineAsyncComponent(() => import('antdv-next/dist/radio/index')); const RadioGroup = defineAsyncComponent(() => import('antdv-next/dist/radio/index').then((res) => res.RadioGroup), ); -const RangePicker = defineAsyncComponent(() => - import('antdv-next/dist/date-picker/index').then( - (res) => res.DateRangePicker, - ), -); const Rate = defineAsyncComponent(() => import('antdv-next/dist/rate/index')); const Select = defineAsyncComponent( () => import('antdv-next/dist/select/index'), @@ -794,4 +789,4 @@ async function initComponentAdapter() { }); } -export { initComponentAdapter }; +export { DatePicker, initComponentAdapter, RangePicker }; diff --git a/apps/web-antdv-next/src/components/shortcut-date-range-picker/shortcut-date-range-picker.vue b/apps/web-antdv-next/src/components/shortcut-date-range-picker/shortcut-date-range-picker.vue index cb27a8e00..a6ec00a83 100644 --- a/apps/web-antdv-next/src/components/shortcut-date-range-picker/shortcut-date-range-picker.vue +++ b/apps/web-antdv-next/src/components/shortcut-date-range-picker/shortcut-date-range-picker.vue @@ -91,7 +91,6 @@ onMounted(() => { Date: Thu, 18 Jun 2026 15:05:08 +0800 Subject: [PATCH 10/15] =?UTF-8?q?fix(@vben/web-antdv-next):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20CollapsePanel=20=E7=BB=84=E4=BB=B6=E5=AF=BC?= =?UTF-8?q?=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bpmn-process-designer/package/penal/PropertiesPanel.vue | 4 +--- .../src/views/bpm/model/modules/category-draggable-model.vue | 1 + .../components/diy-editor/components/component-library.vue | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/web-antdv-next/src/views/bpm/components/bpmn-process-designer/package/penal/PropertiesPanel.vue b/apps/web-antdv-next/src/views/bpm/components/bpmn-process-designer/package/penal/PropertiesPanel.vue index a5c122d6e..10eb17e8e 100644 --- a/apps/web-antdv-next/src/views/bpm/components/bpmn-process-designer/package/penal/PropertiesPanel.vue +++ b/apps/web-antdv-next/src/views/bpm/components/bpmn-process-designer/package/penal/PropertiesPanel.vue @@ -4,7 +4,7 @@ import { nextTick, onBeforeUnmount, onMounted, provide, ref, watch } from 'vue'; import { IconifyIcon } from '@vben/icons'; import { cloneDeep } from '@vben/utils'; -import { Collapse } from 'antdv-next'; +import { Collapse, CollapsePanel } from 'antdv-next'; import ElementCustomConfig from '#/views/bpm/components/bpmn-process-designer/package/penal/custom-config/ElementCustomConfig.vue'; import ElementForm from '#/views/bpm/components/bpmn-process-designer/package/penal/form/ElementForm.vue'; @@ -57,8 +57,6 @@ const props = defineProps({ }, // 流程模型的数据 }); -const CollapsePanel = CollapsePanel; - const activeTab = ref('base'); const elementId = ref(''); const elementType = ref(''); diff --git a/apps/web-antdv-next/src/views/bpm/model/modules/category-draggable-model.vue b/apps/web-antdv-next/src/views/bpm/model/modules/category-draggable-model.vue index e8212d750..173cbf80e 100644 --- a/apps/web-antdv-next/src/views/bpm/model/modules/category-draggable-model.vue +++ b/apps/web-antdv-next/src/views/bpm/model/modules/category-draggable-model.vue @@ -18,6 +18,7 @@ import { Button, Card, Collapse, + CollapsePanel, Dropdown, Menu, MenuItem, diff --git a/apps/web-antdv-next/src/views/mall/promotion/components/diy-editor/components/component-library.vue b/apps/web-antdv-next/src/views/mall/promotion/components/diy-editor/components/component-library.vue index 514c8468b..f84367526 100644 --- a/apps/web-antdv-next/src/views/mall/promotion/components/diy-editor/components/component-library.vue +++ b/apps/web-antdv-next/src/views/mall/promotion/components/diy-editor/components/component-library.vue @@ -6,7 +6,7 @@ import { ref, watch } from 'vue'; import { IconifyIcon } from '@vben/icons'; import { cloneDeep } from '@vben/utils'; -import { Collapse } from 'antdv-next'; +import { Collapse, CollapsePanel } from 'antdv-next'; import draggable from 'vuedraggable'; import { componentConfigs } from './mobile/index'; From af681338c7e0d0ec4a1fa468671a18e28f4ef7a5 Mon Sep 17 00:00:00 2001 From: XuZhiqiang Date: Thu, 18 Jun 2026 16:01:05 +0800 Subject: [PATCH 11/15] =?UTF-8?q?fix(@vben/web-antdv-next):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20SelectOption=E3=80=81RadioButton=E3=80=81RadioGroup?= =?UTF-8?q?=20=E5=92=8C=20FormItem=20=E7=BB=84=E4=BB=B6=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/cron-tab/cron-tab.vue | 2 ++ .../src/components/map/src/map-dialog.vue | 2 +- .../views/ai/image/index/modules/common/index.vue | 9 ++++++++- .../ai/image/index/modules/midjourney/index.vue | 10 +++++++++- .../index/modules/stable-diffusion/index.vue | 1 + .../document/form/modules/split-step.vue | 1 + .../document/form/modules/upload-step.vue | 2 +- .../src/views/ai/music/index/mode/desc.vue | 2 +- .../src/views/ai/music/index/mode/index.vue | 2 +- .../src/views/ai/music/index/mode/lyric.vue | 10 +++++++++- .../views/ai/workflow/form/modules/basic-info.vue | 9 ++++++++- .../ai/workflow/form/modules/workflow-design.vue | 2 +- .../components/UserTaskCustomConfig.vue | 1 + .../penal/flow-condition/FlowCondition.vue | 9 ++++++++- .../package/penal/form/ElementForm.vue | 2 +- .../penal/multi-instance/ElementMultiInstance.vue | 1 + .../penal/time-event-config/CycleConfig.vue | 1 + .../views/bpm/model/form/modules/basic-info.vue | 15 ++++++--------- .../views/infra/codegen/modules/column-info.vue | 2 +- .../src/views/infra/demo/general/demo01/index.vue | 2 ++ .../infra/demo/general/demo01/modules/form.vue | 8 +------- .../src/views/infra/demo/general/demo02/index.vue | 9 ++++++++- .../infra/demo/general/demo02/modules/form.vue | 2 +- .../views/infra/demo/general/demo03/erp/index.vue | 2 ++ .../demo03/erp/modules/demo03-course-form.vue | 2 +- .../demo03/erp/modules/demo03-course-list.vue | 1 + .../demo03/erp/modules/demo03-grade-form.vue | 2 +- .../demo03/erp/modules/demo03-grade-list.vue | 1 + .../demo/general/demo03/erp/modules/form.vue | 8 +------- .../infra/demo/general/demo03/inner/index.vue | 2 ++ .../demo03/inner/modules/demo03-grade-form.vue | 2 +- .../demo/general/demo03/inner/modules/form.vue | 1 + .../infra/demo/general/demo03/normal/index.vue | 2 ++ .../demo03/normal/modules/demo03-grade-form.vue | 2 +- .../demo/general/demo03/normal/modules/form.vue | 1 + .../src/views/infra/webSocket/index.vue | 1 + .../spu/form/modules/product-attributes.vue | 2 +- .../promotion/diy/template/decorate/index.vue | 2 +- .../wx-account-select/wx-account-select.vue | 2 +- .../src/views/mp/material/modules/UploadVideo.vue | 1 + .../src/views/mp/menu/modules/editor.vue | 11 ++++++++++- 41 files changed, 104 insertions(+), 45 deletions(-) diff --git a/apps/web-antdv-next/src/components/cron-tab/cron-tab.vue b/apps/web-antdv-next/src/components/cron-tab/cron-tab.vue index d1b123585..ad11e9d25 100644 --- a/apps/web-antdv-next/src/components/cron-tab/cron-tab.vue +++ b/apps/web-antdv-next/src/components/cron-tab/cron-tab.vue @@ -8,6 +8,7 @@ import { computed, onMounted, reactive, ref, watch } from 'vue'; import { Button, Form, + FormItem, Input, InputNumber, message, @@ -15,6 +16,7 @@ import { RadioButton, RadioGroup, Select, + SelectOption, TabPane, Tabs, } from 'antdv-next'; diff --git a/apps/web-antdv-next/src/components/map/src/map-dialog.vue b/apps/web-antdv-next/src/components/map/src/map-dialog.vue index ecc626d00..e9b0640db 100644 --- a/apps/web-antdv-next/src/components/map/src/map-dialog.vue +++ b/apps/web-antdv-next/src/components/map/src/map-dialog.vue @@ -4,7 +4,7 @@ import { nextTick, reactive, ref } from 'vue'; import { useVbenModal } from '@vben/common-ui'; -import { Button, Form, Input, Select, Space } from 'antdv-next'; +import { Button, Form, FormItem, Input, Select, Space } from 'antdv-next'; import { loadBaiduMapSdk } from './utils'; diff --git a/apps/web-antdv-next/src/views/ai/image/index/modules/common/index.vue b/apps/web-antdv-next/src/views/ai/image/index/modules/common/index.vue index 87fe56fd4..2ac784268 100644 --- a/apps/web-antdv-next/src/views/ai/image/index/modules/common/index.vue +++ b/apps/web-antdv-next/src/views/ai/image/index/modules/common/index.vue @@ -12,7 +12,14 @@ import { OtherPlatformEnum, } from '@vben/constants'; -import { Button, InputNumber, Select, Space, TextArea } from 'antdv-next'; +import { + Button, + InputNumber, + Select, + SelectOption, + Space, + TextArea, +} from 'antdv-next'; import { drawImage } from '#/api/ai/image'; diff --git a/apps/web-antdv-next/src/views/ai/image/index/modules/midjourney/index.vue b/apps/web-antdv-next/src/views/ai/image/index/modules/midjourney/index.vue index 99e2bdfce..783b5f5a3 100644 --- a/apps/web-antdv-next/src/views/ai/image/index/modules/midjourney/index.vue +++ b/apps/web-antdv-next/src/views/ai/image/index/modules/midjourney/index.vue @@ -17,7 +17,15 @@ import { NijiVersionList, } from '@vben/constants'; -import { Button, Image, message, Select, Space, TextArea } from 'antdv-next'; +import { + Button, + Image, + message, + Select, + SelectOption, + Space, + TextArea, +} from 'antdv-next'; import { midjourneyImagine } from '#/api/ai/image'; import { ImageUpload } from '#/components/upload'; diff --git a/apps/web-antdv-next/src/views/ai/image/index/modules/stable-diffusion/index.vue b/apps/web-antdv-next/src/views/ai/image/index/modules/stable-diffusion/index.vue index 7842491fe..451fc907e 100644 --- a/apps/web-antdv-next/src/views/ai/image/index/modules/stable-diffusion/index.vue +++ b/apps/web-antdv-next/src/views/ai/image/index/modules/stable-diffusion/index.vue @@ -19,6 +19,7 @@ import { InputNumber, message, Select, + SelectOption, Space, TextArea, } from 'antdv-next'; diff --git a/apps/web-antdv-next/src/views/ai/knowledge/document/form/modules/split-step.vue b/apps/web-antdv-next/src/views/ai/knowledge/document/form/modules/split-step.vue index 2899a2a38..1c808a6da 100644 --- a/apps/web-antdv-next/src/views/ai/knowledge/document/form/modules/split-step.vue +++ b/apps/web-antdv-next/src/views/ai/knowledge/document/form/modules/split-step.vue @@ -10,6 +10,7 @@ import { Dropdown, Empty, Form, + FormItem, InputNumber, Menu, MenuItem, diff --git a/apps/web-antdv-next/src/views/ai/knowledge/document/form/modules/upload-step.vue b/apps/web-antdv-next/src/views/ai/knowledge/document/form/modules/upload-step.vue index 1454188bc..0be24ee36 100644 --- a/apps/web-antdv-next/src/views/ai/knowledge/document/form/modules/upload-step.vue +++ b/apps/web-antdv-next/src/views/ai/knowledge/document/form/modules/upload-step.vue @@ -10,7 +10,7 @@ import { computed, getCurrentInstance, inject, onMounted, ref } from 'vue'; import { IconifyIcon } from '@vben/icons'; import { generateAcceptedFileTypes } from '@vben/utils'; -import { Button, Form, message, UploadDragger } from 'antdv-next'; +import { Button, Form, FormItem, message, UploadDragger } from 'antdv-next'; import { useUpload } from '#/components/upload/use-upload'; type UploadRequestOption = any; diff --git a/apps/web-antdv-next/src/views/ai/music/index/mode/desc.vue b/apps/web-antdv-next/src/views/ai/music/index/mode/desc.vue index c0d493c5e..a3bf14ca1 100644 --- a/apps/web-antdv-next/src/views/ai/music/index/mode/desc.vue +++ b/apps/web-antdv-next/src/views/ai/music/index/mode/desc.vue @@ -1,7 +1,7 @@ diff --git a/apps/web-antdv-next/src/views/iot/thingmodel/modules/data-specs/number.vue b/apps/web-antdv-next/src/views/iot/thingmodel/modules/data-specs/number.vue index 5a4fd286d..14405da6c 100644 --- a/apps/web-antdv-next/src/views/iot/thingmodel/modules/data-specs/number.vue +++ b/apps/web-antdv-next/src/views/iot/thingmodel/modules/data-specs/number.vue @@ -36,53 +36,46 @@ function unitChange(unitSpecs: any) { } /** 校验最小值 */ -function validateMin(_rule: any, _value: any, callback: any) { +function validateMin(_rule: any, _value: any) { const min = Number(dataSpecs.value.min); const max = Number(dataSpecs.value.max); if (Number.isNaN(min)) { - callback(new Error('请输入有效的数值')); - return; + return Promise.reject(new Error('请输入有效的数值')); } if (!Number.isNaN(max) && min >= max) { - callback(new Error('最小值必须小于最大值')); - return; + return Promise.reject(new Error('最小值必须小于最大值')); } - callback(); + return Promise.resolve(); } /** 校验最大值 */ -function validateMax(_rule: any, _value: any, callback: any) { +function validateMax(_rule: any, _value: any) { const min = Number(dataSpecs.value.min); const max = Number(dataSpecs.value.max); if (Number.isNaN(max)) { - callback(new Error('请输入有效的数值')); - return; + return Promise.reject(new Error('请输入有效的数值')); } if (!Number.isNaN(min) && max <= min) { - callback(new Error('最大值必须大于最小值')); - return; + return Promise.reject(new Error('最大值必须大于最小值')); } - callback(); + return Promise.resolve(); } /** 校验步长 */ -function validateStep(_rule: any, _value: any, callback: any) { +function validateStep(_rule: any, _value: any) { const step = Number(dataSpecs.value.step); if (Number.isNaN(step)) { - callback(new Error('请输入有效的数值')); - return; + return Promise.reject(new Error('请输入有效的数值')); } if (step <= 0) { - callback(new Error('步长必须大于 0')); - return; + return Promise.reject(new Error('步长必须大于 0')); } const min = Number(dataSpecs.value.min); const max = Number(dataSpecs.value.max); if (!Number.isNaN(min) && !Number.isNaN(max) && step > max - min) { - callback(new Error('步长不能大于最大值与最小值的差值')); - return; + return Promise.reject(new Error('步长不能大于最大值与最小值的差值')); } - callback(); + return Promise.resolve(); } diff --git a/apps/web-antdv-next/src/views/iot/thingmodel/modules/data-specs/struct.vue b/apps/web-antdv-next/src/views/iot/thingmodel/modules/data-specs/struct.vue index 280a3a105..c62a42856 100644 --- a/apps/web-antdv-next/src/views/iot/thingmodel/modules/data-specs/struct.vue +++ b/apps/web-antdv-next/src/views/iot/thingmodel/modules/data-specs/struct.vue @@ -33,12 +33,11 @@ const structFormRef = ref(); const formData = ref(buildEmptyFormData()); /** 校验结构体属性对象非空 */ -function validateStructSpecsList(_rule: any, _value: any, callback: any) { +function validateStructSpecsList(_rule: any, _value: any) { if (isEmpty(dataSpecsList.value)) { - callback(new Error('请至少添加一个结构体属性对象')); - return; + return Promise.reject(new Error('请至少添加一个结构体属性对象')); } - callback(); + return Promise.resolve(); } const [Modal, modalApi] = useVbenModal({ From 456a91dfc27d42737ca4a34d8e40de3fee54a10b Mon Sep 17 00:00:00 2001 From: XuZhiqiang Date: Thu, 18 Jun 2026 23:16:30 +0800 Subject: [PATCH 14/15] refactor(@vben/web-antdv-next): migrate plain SelectOption usages to options API Replace simple label/value SelectOption children with Select options across BPM, IoT, AI, MP, Mall, codegen, and demo pages. Keep custom option markup cases unchanged. --- .../src/components/cron-tab/cron-tab.vue | 162 ++++++----------- .../ai/image/index/modules/common/index.vue | 33 +--- .../image/index/modules/midjourney/index.vue | 21 +-- .../index/modules/stable-diffusion/index.vue | 38 +--- .../src/views/ai/music/index/mode/desc.vue | 17 +- .../src/views/ai/music/index/mode/lyric.vue | 25 +-- .../ai/workflow/form/modules/basic-info.vue | 25 +-- .../workflow/form/modules/workflow-design.vue | 29 +-- .../components/BoundaryEventTimer.vue | 13 +- .../components/UserTaskCustomConfig.vue | 25 +-- .../penal/flow-condition/FlowCondition.vue | 45 ++--- .../package/penal/form/ElementForm.vue | 14 +- .../penal/listeners/ElementListeners.vue | 50 +++--- .../penal/listeners/ListenerFieldModal.vue | 20 +-- .../penal/listeners/UserTaskListeners.vue | 72 ++++---- .../multi-instance/ElementMultiInstance.vue | 16 +- .../task/task-components/CallActivity.vue | 14 +- .../task/task-components/ReceiveTask.vue | 18 +- .../penal/task/task-components/ScriptTask.vue | 20 +-- .../penal/task/task-components/UserTask.vue | 111 ++++-------- .../child-process-node-config.vue | 146 ++++++--------- .../nodes-config/copy-task-node-config.vue | 120 +++++-------- .../nodes-config/delay-timer-node-config.vue | 15 +- .../nodes-config/modules/condition.vue | 15 +- .../modules/http-request-param-setting.vue | 82 ++++----- .../modules/http-request-setting.vue | 34 ++-- .../nodes-config/router-node-config.vue | 12 +- .../nodes-config/trigger-node-config.vue | 43 ++--- .../nodes-config/user-task-node-config.vue | 167 +++++++----------- .../bpm/model/form/modules/basic-info.vue | 12 +- .../detail/modules/operation-button.vue | 83 +++------ .../infra/codegen/modules/column-info.vue | 56 ++---- .../views/infra/demo/general/demo01/index.vue | 19 +- .../infra/demo/general/demo03/erp/index.vue | 19 +- .../infra/demo/general/demo03/inner/index.vue | 19 +- .../demo/general/demo03/normal/index.vue | 19 +- .../device/device/detail/modules/message.vue | 23 +-- .../detail/modules/thing-model-event.vue | 25 +-- .../detail/modules/thing-model-service.vue | 25 +-- .../src/views/iot/device/device/index.vue | 68 ++----- .../data/sink/config/http-config-form.vue | 30 ++-- .../rule/data/sink/config/tcp-config-form.vue | 21 +-- .../sink/config/websocket-config-form.vue | 13 +- .../rule/scene/form/configs/alert-config.vue | 13 +- .../scene/form/configs/condition-config.vue | 35 +--- .../configs/main-condition-inner-config.vue | 46 ++--- .../rule/scene/form/inputs/value-input.vue | 21 +-- .../scene/form/sections/action-section.vue | 21 +-- .../thingmodel/modules/data-specs/number.vue | 18 +- .../views/iot/thingmodel/modules/property.vue | 26 +-- .../spu/form/modules/product-attributes.vue | 14 +- .../wx-account-select/wx-account-select.vue | 10 +- .../src/views/mp/menu/modules/editor.vue | 23 +-- 53 files changed, 713 insertions(+), 1348 deletions(-) diff --git a/apps/web-antdv-next/src/components/cron-tab/cron-tab.vue b/apps/web-antdv-next/src/components/cron-tab/cron-tab.vue index ad11e9d25..ab9366e30 100644 --- a/apps/web-antdv-next/src/components/cron-tab/cron-tab.vue +++ b/apps/web-antdv-next/src/components/cron-tab/cron-tab.vue @@ -16,7 +16,6 @@ import { RadioButton, RadioGroup, Select, - SelectOption, TabPane, Tabs, } from 'antdv-next'; @@ -419,22 +418,21 @@ function inputChange() { @input="inputChange" > @@ -498,14 +496,10 @@ function inputChange() { v-model:value="cronValue.second.appoint" mode="multiple" style="width: 100%" - > - - + :options=" + data.second.map((item) => ({ label: item, value: item })) + " + /> @@ -562,14 +556,10 @@ function inputChange() { v-model:value="cronValue.minute.appoint" mode="multiple" style="width: 100%" - > - - + :options=" + data.minute.map((item) => ({ label: item, value: item })) + " + /> @@ -626,14 +616,10 @@ function inputChange() { v-model:value="cronValue.hour.appoint" mode="multiple" style="width: 100%" - > - - + :options=" + data.hour.map((item) => ({ label: item, value: item })) + " + /> @@ -692,14 +678,10 @@ function inputChange() { v-model:value="cronValue.day.appoint" mode="multiple" style="width: 100%" - > - - + :options=" + data.day.map((item) => ({ label: item, value: item })) + " + /> @@ -756,14 +738,10 @@ function inputChange() { v-model:value="cronValue.month.appoint" mode="multiple" style="width: 100%" - > - - + :options=" + data.month.map((item) => ({ label: item, value: item })) + " + /> @@ -787,23 +765,15 @@ function inputChange() { - + - - + - - + + :options="data.week" + /> - + + :options=" + data.year.map((item) => ({ label: item, value: item })) + " + /> diff --git a/apps/web-antdv-next/src/views/ai/image/index/modules/common/index.vue b/apps/web-antdv-next/src/views/ai/image/index/modules/common/index.vue index 2ac784268..f614f2b9a 100644 --- a/apps/web-antdv-next/src/views/ai/image/index/modules/common/index.vue +++ b/apps/web-antdv-next/src/views/ai/image/index/modules/common/index.vue @@ -12,14 +12,7 @@ import { OtherPlatformEnum, } from '@vben/constants'; -import { - Button, - InputNumber, - Select, - SelectOption, - Space, - TextArea, -} from 'antdv-next'; +import { Button, InputNumber, Select, Space, TextArea } from 'antdv-next'; import { drawImage } from '#/api/ai/image'; @@ -154,15 +147,9 @@ defineExpose({ settingValues }); size="large" class="!w-80" @change="handlerPlatformChange" - > - - {{ item.name }} - - + :options="OtherPlatformEnum" + :field-names="{ label: 'name', value: 'key' }" + /> @@ -176,15 +163,9 @@ defineExpose({ settingValues }); placeholder="Select" size="large" class="!w-80" - > - - {{ item.name }} - - + :options="platformModels" + :field-names="{ label: 'name', value: 'id' }" + /> diff --git a/apps/web-antdv-next/src/views/ai/image/index/modules/midjourney/index.vue b/apps/web-antdv-next/src/views/ai/image/index/modules/midjourney/index.vue index 783b5f5a3..3544a991b 100644 --- a/apps/web-antdv-next/src/views/ai/image/index/modules/midjourney/index.vue +++ b/apps/web-antdv-next/src/views/ai/image/index/modules/midjourney/index.vue @@ -17,15 +17,7 @@ import { NijiVersionList, } from '@vben/constants'; -import { - Button, - Image, - message, - Select, - SelectOption, - Space, - TextArea, -} from 'antdv-next'; +import { Button, Image, message, Select, Space, TextArea } from 'antdv-next'; import { midjourneyImagine } from '#/api/ai/image'; import { ImageUpload } from '#/components/upload'; @@ -222,15 +214,8 @@ defineExpose({ settingValues }); class="!w-80" allow-clear placeholder="请选择版本" - > - - {{ item.label }} - - + :options="versionList" + /> diff --git a/apps/web-antdv-next/src/views/ai/image/index/modules/stable-diffusion/index.vue b/apps/web-antdv-next/src/views/ai/image/index/modules/stable-diffusion/index.vue index 451fc907e..32c4626a8 100644 --- a/apps/web-antdv-next/src/views/ai/image/index/modules/stable-diffusion/index.vue +++ b/apps/web-antdv-next/src/views/ai/image/index/modules/stable-diffusion/index.vue @@ -19,7 +19,6 @@ import { InputNumber, message, Select, - SelectOption, Space, TextArea, } from 'antdv-next'; @@ -169,15 +168,9 @@ defineExpose({ settingValues }); placeholder="Select" size="large" class="!w-80" - > - - {{ item.name }} - - + :options="StableDiffusionSamplers" + :field-names="{ label: 'name', value: 'key' }" + /> @@ -190,15 +183,9 @@ defineExpose({ settingValues }); placeholder="Select" size="large" class="!w-80" - > - - {{ item.name }} - - + :options="StableDiffusionClipGuidancePresets" + :field-names="{ label: 'name', value: 'key' }" + /> @@ -211,16 +198,9 @@ defineExpose({ settingValues }); placeholder="Select" size="large" class="!w-80" - > - - {{ item.name }} - - + :options="StableDiffusionStylePresets" + :field-names="{ label: 'name', value: 'key' }" + /> diff --git a/apps/web-antdv-next/src/views/ai/music/index/mode/desc.vue b/apps/web-antdv-next/src/views/ai/music/index/mode/desc.vue index a3bf14ca1..ad9f039ff 100644 --- a/apps/web-antdv-next/src/views/ai/music/index/mode/desc.vue +++ b/apps/web-antdv-next/src/views/ai/music/index/mode/desc.vue @@ -1,7 +1,7 @@