diff --git a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/time-event-config/CycleConfig.vue b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/time-event-config/CycleConfig.vue index 493681f1f..5d35687d4 100644 --- a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/time-event-config/CycleConfig.vue +++ b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/time-event-config/CycleConfig.vue @@ -8,8 +8,10 @@ import { Input, InputNumber, Radio, + TabPane, Tabs, } from 'ant-design-vue'; +import dayjs from 'dayjs'; const props = defineProps({ value: { @@ -41,7 +43,7 @@ const cronFieldList = [ ]; const activeField = ref('second'); const cronMode = ref({ - second: 'appoint', + second: 'every', minute: 'every', hour: 'every', day: 'every', @@ -50,7 +52,7 @@ const cronMode = ref({ year: 'every', }); const cronAppoint = ref({ - second: ['00', '01'], + second: [], minute: [], hour: [], day: [], @@ -107,103 +109,156 @@ watch( const isoStr = ref(''); const repeat = ref(1); const isoDate = ref(''); +const durationUnits = [ + { key: 'Y', label: '年', presets: [1, 2, 3, 4] }, + { key: 'M', label: '月', presets: [1, 2, 3, 4] }, + { key: 'D', label: '天', presets: [1, 2, 3, 4] }, + { key: 'H', label: '时', presets: [4, 8, 12, 24] }, + { key: 'm', label: '分', presets: [5, 10, 30, 50] }, + { key: 'S', label: '秒', presets: [5, 10, 30, 50] }, +]; +const durationCustom = ref({ Y: '', M: '', D: '', H: '', m: '', S: '' }); const isoDuration = ref(''); -function setDuration(type, val) { - // 组装ISO 8601字符串 - let d = isoDuration.value; - if (d.includes(type)) { - d = d.replace(new RegExp(String.raw`\d+${type}`), val + type); - } else { - d += val + type; - } - isoDuration.value = d; + +function setDuration(key, val) { + durationCustom.value[key] = !val || Number.isNaN(val) ? '' : val; + updateDurationStr(); +} + +function updateDurationStr() { + let str = 'P'; + str += durationCustom.value.Y ? `${durationCustom.value.Y}Y` : ''; + str += durationCustom.value.M ? `${durationCustom.value.M}M` : ''; + str += durationCustom.value.D ? `${durationCustom.value.D}D` : ''; + str += + durationCustom.value.H || durationCustom.value.m || durationCustom.value.S + ? 'T' + : ''; + str += durationCustom.value.H ? `${durationCustom.value.H}H` : ''; + str += durationCustom.value.m ? `${durationCustom.value.m}M` : ''; + str += durationCustom.value.S ? `${durationCustom.value.S}S` : ''; + isoDuration.value = str === 'P' ? '' : str; updateIsoStr(); } + function updateIsoStr() { let str = `R${repeat.value}`; - if (isoDate.value) - str += `/${ + if (isoDate.value) { + const dateStr = typeof isoDate.value === 'string' ? isoDate.value - : new Date(isoDate.value).toISOString() - }`; + : isoDate.value.toISOString(); + str += `/${dateStr}`; + } if (isoDuration.value) str += `/${isoDuration.value}`; isoStr.value = str; if (tab.value === 'iso') emit('change', isoStr.value); } -watch([repeat, isoDate, isoDuration], updateIsoStr); +watch([repeat, isoDate], updateIsoStr); +watch(durationCustom, updateDurationStr, { deep: true }); watch( () => props.value, (val) => { if (!val) return; - if (tab.value === 'cron') cronStr.value = val; - if (tab.value === 'iso') isoStr.value = val; + // 自动检测格式:以R开头的是ISO 8601格式,否则是CRON表达式 + if (val.startsWith('R')) { + tab.value = 'iso'; + isoStr.value = val; + // 解析ISO格式:R{repeat}/{date}/{duration} + const parts = val.split('/'); + if (parts[0]) { + const repeatMatch = parts[0].match(/^R(\d+)$/); + if (repeatMatch) repeat.value = Number.parseInt(repeatMatch[1], 10); + } + // 解析date部分(ISO 8601日期时间格式) + const datePart = parts.find( + (p) => p.includes('T') && !p.startsWith('P') && !p.startsWith('R'), + ); + if (datePart) { + isoDate.value = dayjs(datePart); + } + // 解析duration部分 + const durationPart = parts.find((p) => p.startsWith('P')); + if (durationPart) { + const match = durationPart.match( + /^P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$/, + ); + if (match) { + durationCustom.value.Y = match[1] || ''; + durationCustom.value.M = match[2] || ''; + durationCustom.value.D = match[3] || ''; + durationCustom.value.H = match[4] || ''; + durationCustom.value.m = match[5] || ''; + durationCustom.value.S = match[6] || ''; + isoDuration.value = durationPart; + } + } + } else { + tab.value = 'cron'; + cronStr.value = val; + } }, { immediate: true }, ); diff --git a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/time-event-config/DurationConfig.vue b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/time-event-config/DurationConfig.vue index 42ae2c816..61026cb99 100644 --- a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/time-event-config/DurationConfig.vue +++ b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/penal/time-event-config/DurationConfig.vue @@ -68,14 +68,10 @@ watch(