From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目
---
src/components/bpmnProcessDesigner/package/penal/time-event-config/TimeEventConfig.vue | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 312 insertions(+), 0 deletions(-)
diff --git a/src/components/bpmnProcessDesigner/package/penal/time-event-config/TimeEventConfig.vue b/src/components/bpmnProcessDesigner/package/penal/time-event-config/TimeEventConfig.vue
new file mode 100644
index 0000000..3ec31f9
--- /dev/null
+++ b/src/components/bpmnProcessDesigner/package/penal/time-event-config/TimeEventConfig.vue
@@ -0,0 +1,312 @@
+<template>
+ <div class="panel-tab__content">
+ <div style="margin-top: 10px">
+ <span>绫诲瀷锛�</span>
+ <el-button-group>
+ <el-button size="mini" :type="type === 'time' ? 'primary' : ''" @click="setType('time')"
+ >鏃堕棿</el-button
+ >
+ <el-button
+ size="mini"
+ :type="type === 'duration' ? 'primary' : ''"
+ @click="setType('duration')"
+ >鎸佺画</el-button
+ >
+ <el-button size="mini" :type="type === 'cycle' ? 'primary' : ''" @click="setType('cycle')"
+ >寰幆</el-button
+ >
+ </el-button-group>
+ <el-icon v-if="valid" color="green" style="margin-left: 8px"><CircleCheckFilled /></el-icon>
+ </div>
+ <div style="margin-top: 10px; display: flex; align-items: center">
+ <span>鏉′欢锛�</span>
+ <el-input
+ v-model="condition"
+ :placeholder="placeholder"
+ style="width: calc(100% - 100px)"
+ :readonly="type !== 'duration' && type !== 'cycle'"
+ @focus="handleInputFocus"
+ @blur="updateNode"
+ >
+ <template #suffix>
+ <el-tooltip v-if="!valid" content="鏍煎紡閿欒" placement="top">
+ <el-icon color="orange"><WarningFilled /></el-icon>
+ </el-tooltip>
+ <el-tooltip :content="helpText" placement="top">
+ <el-icon color="#409EFF" style="cursor: pointer" @click="showHelp = true"
+ ><QuestionFilled
+ /></el-icon>
+ </el-tooltip>
+ <el-button
+ v-if="type === 'time'"
+ @click="showDatePicker = true"
+ style="margin-left: 4px"
+ circle
+ size="small"
+ >
+ <Icon icon="ep:calendar" />
+ </el-button>
+ <el-button
+ v-if="type === 'duration'"
+ @click="showDurationDialog = true"
+ style="margin-left: 4px"
+ circle
+ size="small"
+ >
+ <Icon icon="ep:timer" />
+ </el-button>
+ <el-button
+ v-if="type === 'cycle'"
+ @click="showCycleDialog = true"
+ style="margin-left: 4px"
+ circle
+ size="small"
+ >
+ <Icon icon="ep:setting" />
+ </el-button>
+ </template>
+ </el-input>
+ </div>
+ <!-- 鏃堕棿閫夋嫨鍣� -->
+ <el-dialog
+ v-model="showDatePicker"
+ title="閫夋嫨鏃堕棿"
+ width="400px"
+ @close="showDatePicker = false"
+ >
+ <el-date-picker
+ v-model="dateValue"
+ type="datetime"
+ placeholder="閫夋嫨鏃ユ湡鏃堕棿"
+ style="width: 100%"
+ @change="onDateChange"
+ />
+ <template #footer>
+ <el-button @click="showDatePicker = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="onDateConfirm">纭畾</el-button>
+ </template>
+ </el-dialog>
+ <!-- 鎸佺画鏃堕暱閫夋嫨鍣� -->
+ <el-dialog
+ v-model="showDurationDialog"
+ title="鏃堕棿閰嶇疆"
+ width="600px"
+ @close="showDurationDialog = false"
+ >
+ <DurationConfig :value="condition" @change="onDurationChange" />
+ <template #footer>
+ <el-button @click="showDurationDialog = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="onDurationConfirm">纭畾</el-button>
+ </template>
+ </el-dialog>
+ <!-- 寰幆閰嶇疆鍣� -->
+ <el-dialog
+ v-model="showCycleDialog"
+ title="鏃堕棿閰嶇疆"
+ width="800px"
+ @close="showCycleDialog = false"
+ >
+ <CycleConfig :value="condition" @change="onCycleChange" />
+ <template #footer>
+ <el-button @click="showCycleDialog = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="onCycleConfirm">纭畾</el-button>
+ </template>
+ </el-dialog>
+ <!-- 甯姪璇存槑 -->
+ <el-dialog v-model="showHelp" title="鏍煎紡璇存槑" width="600px" @close="showHelp = false">
+ <div v-html="helpHtml"></div>
+ <template #footer>
+ <el-button @click="showHelp = false">鍏抽棴</el-button>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, computed, watch, onMounted } from 'vue'
+import { CircleCheckFilled, WarningFilled, QuestionFilled } from '@element-plus/icons-vue'
+import DurationConfig from './DurationConfig.vue'
+import CycleConfig from './CycleConfig.vue'
+import { createListenerObject, updateElementExtensions } from '../../utils'
+const bpmnInstances = () => (window as any).bpmnInstances
+const props = defineProps({ businessObject: Object })
+const type = ref('time')
+const condition = ref('')
+const valid = ref(true)
+const showDatePicker = ref(false)
+const showDurationDialog = ref(false)
+const showCycleDialog = ref(false)
+const showHelp = ref(false)
+const dateValue = ref(null)
+const bpmnElement = ref(null)
+
+const placeholder = computed(() => {
+ if (type.value === 'time') return '璇疯緭鍏ユ椂闂�'
+ if (type.value === 'duration') return '璇疯緭鍏ユ寔缁椂闀�'
+ if (type.value === 'cycle') return '璇疯緭鍏ュ惊鐜〃杈惧紡'
+ return ''
+})
+const helpText = computed(() => {
+ if (type.value === 'time') return '閫夋嫨鍏蜂綋鏃堕棿'
+ if (type.value === 'duration') return 'ISO 8601鏍煎紡锛屽PT1H'
+ if (type.value === 'cycle') return 'CRON琛ㄨ揪寮忔垨ISO 8601鍛ㄦ湡'
+ return ''
+})
+const helpHtml = computed(() => {
+ if (type.value === 'duration') {
+ return `鎸囧畾瀹氭椂鍣ㄤ箣鍓嶈绛夊緟澶氶暱鏃堕棿銆係琛ㄧず绉掞紝M琛ㄧず鍒嗭紝D琛ㄧず澶╋紱P琛ㄧず鏃堕棿娈碉紝T琛ㄧず绮剧‘鍒版椂闂寸殑鏃堕棿娈点��<br>
+ 鏃堕棿鏍煎紡渚濈劧涓篒SO 8601鏍煎紡锛屼竴骞翠袱涓湀涓夊ぉ鍥涘皬鏃朵簲鍒嗗叚绉掑唴锛屽彲浠ュ啓鎴怭1Y2M3DT4H5M6S銆�<br>
+ P鏄紑濮嬫爣璁帮紝T鏄椂闂村拰鏃ユ湡鍒嗗壊鏍囪锛屾病鏈夋棩鏈熷彧鏈夋椂闂碩鏄笉鑳界渷鍘荤殑锛屾瘮濡�1灏忔椂鎵ц涓�娆″簲鍐欐垚PT1H銆俙
+ }
+ if (type.value === 'cycle') {
+ return `鏀寔CRON琛ㄨ揪寮忥紙濡�0 0/30 * * * ?锛夋垨ISO 8601鍛ㄦ湡锛堝R3/PT10M锛夈�俙
+ }
+ return ''
+})
+
+// 鍒濆鍖栧拰鐩戝惉
+function syncFromBusinessObject() {
+ if (props.businessObject) {
+ const timerDef = (props.businessObject.eventDefinitions || [])[0]
+ if (timerDef) {
+ if (timerDef.timeDate) {
+ type.value = 'time'
+ condition.value = timerDef.timeDate.body
+ } else if (timerDef.timeDuration) {
+ type.value = 'duration'
+ condition.value = timerDef.timeDuration.body
+ } else if (timerDef.timeCycle) {
+ type.value = 'cycle'
+ condition.value = timerDef.timeCycle.body
+ }
+ }
+ }
+}
+onMounted(syncFromBusinessObject)
+
+// 鍒囨崲绫诲瀷
+function setType(t) {
+ type.value = t
+ condition.value = ''
+ updateNode()
+}
+
+// 杈撳叆鏍¢獙
+watch([type, condition], () => {
+ valid.value = validate()
+ // updateNode() // 鍙互娉ㄩ噴鎺夛紝閬垮厤棰戠箒瑙﹀彂
+})
+
+function validate() {
+ if (type.value === 'time') {
+ return !!condition.value && !isNaN(Date.parse(condition.value))
+ }
+ if (type.value === 'duration') {
+ return /^P.*$/.test(condition.value)
+ }
+ if (type.value === 'cycle') {
+ return /^([0-9*\/?, ]+|R\d*\/P.*)$/.test(condition.value)
+ }
+ return true
+}
+
+// 閫夋嫨鏃堕棿
+function onDateChange(val) {
+ dateValue.value = val
+}
+function onDateConfirm() {
+ if (dateValue.value) {
+ condition.value = new Date(dateValue.value).toISOString()
+ showDatePicker.value = false
+ updateNode()
+ }
+}
+
+// 鎸佺画鏃堕暱
+function onDurationChange(val) {
+ condition.value = val
+}
+function onDurationConfirm() {
+ showDurationDialog.value = false
+ updateNode()
+}
+
+// 寰幆
+function onCycleChange(val) {
+ condition.value = val
+}
+function onCycleConfirm() {
+ showCycleDialog.value = false
+ updateNode()
+}
+
+// 杈撳叆妗嗚仛鐒︽椂寮圭獥锛堝彲閫夛級
+function handleInputFocus() {
+ if (type.value === 'time') showDatePicker.value = true
+ if (type.value === 'duration') showDurationDialog.value = true
+ if (type.value === 'cycle') showCycleDialog.value = true
+}
+
+// 鍚屾鍒拌妭鐐�
+function updateNode() {
+ const moddle = window.bpmnInstances?.moddle
+ const modeling = window.bpmnInstances?.modeling
+ const elementRegistry = window.bpmnInstances?.elementRegistry
+ if (!moddle || !modeling || !elementRegistry) return
+
+ // 鑾峰彇鍏冪礌
+ if (!props.businessObject || !props.businessObject.id) return
+ const element = elementRegistry.get(props.businessObject.id)
+ if (!element) return
+
+ // 1. 澶嶇敤鍘熸湁 timerDef锛屾垨鏂板缓
+ let timerDef =
+ element.businessObject.eventDefinitions && element.businessObject.eventDefinitions[0]
+ if (!timerDef) {
+ timerDef = bpmnInstances().bpmnFactory.create('bpmn:TimerEventDefinition', {})
+ modeling.updateProperties(element, {
+ eventDefinitions: [timerDef]
+ })
+ }
+
+ // 2. 娓呯┖鍘熸湁
+ delete timerDef.timeDate
+ delete timerDef.timeDuration
+ delete timerDef.timeCycle
+
+ // 3. 璁剧疆鏂扮殑
+ if (type.value === 'time' && condition.value) {
+ timerDef.timeDate = bpmnInstances().bpmnFactory.create('bpmn:FormalExpression', {
+ body: condition.value
+ })
+ } else if (type.value === 'duration' && condition.value) {
+ timerDef.timeDuration = bpmnInstances().bpmnFactory.create('bpmn:FormalExpression', {
+ body: condition.value
+ })
+ } else if (type.value === 'cycle' && condition.value) {
+ timerDef.timeCycle = bpmnInstances().bpmnFactory.create('bpmn:FormalExpression', {
+ body: condition.value
+ })
+ }
+
+ bpmnInstances().modeling.updateProperties(toRaw(element), {
+ eventDefinitions: [timerDef]
+ })
+}
+
+watch(
+ () => props.businessObject,
+ (val) => {
+ if (val) {
+ nextTick(() => {
+ syncFromBusinessObject()
+ })
+ }
+ },
+ { immediate: true }
+)
+</script>
+
+<style scoped>
+/* 鐩稿叧鏍峰紡 */
+</style>
--
Gitblit v1.8.0