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/PropertiesPanel.vue | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 312 insertions(+), 0 deletions(-)
diff --git a/src/components/bpmnProcessDesigner/package/penal/PropertiesPanel.vue b/src/components/bpmnProcessDesigner/package/penal/PropertiesPanel.vue
new file mode 100644
index 0000000..a87698f
--- /dev/null
+++ b/src/components/bpmnProcessDesigner/package/penal/PropertiesPanel.vue
@@ -0,0 +1,312 @@
+<template>
+ <div class="process-panel__container" :style="{ width: `${width}px`, maxHeight: '600px' }">
+ <el-collapse v-model="activeTab" v-if="isReady">
+ <el-collapse-item name="base">
+ <!-- class="panel-tab__title" -->
+ <template #title>
+ <Icon icon="ep:info-filled" />
+ 甯歌</template
+ >
+ <ElementBaseInfo
+ :id-edit-disabled="idEditDisabled"
+ :business-object="elementBusinessObject"
+ :type="elementType"
+ :model="model"
+ />
+ </el-collapse-item>
+ <el-collapse-item name="condition" v-if="elementType === 'Process'" key="message">
+ <template #title><Icon icon="ep:comment" />娑堟伅涓庝俊鍙�</template>
+ <signal-and-massage />
+ </el-collapse-item>
+ <el-collapse-item name="condition" v-if="conditionFormVisible" key="condition">
+ <template #title><Icon icon="ep:promotion" />娴佽浆鏉′欢</template>
+ <flow-condition :business-object="elementBusinessObject" :type="elementType" />
+ </el-collapse-item>
+ <el-collapse-item name="condition" v-if="formVisible" key="form">
+ <template #title><Icon icon="ep:list" />琛ㄥ崟</template>
+ <element-form :id="elementId" :type="elementType" />
+ </el-collapse-item>
+ <el-collapse-item name="task" v-if="isTaskCollapseItemShow(elementType)" key="task">
+ <template #title
+ ><Icon icon="ep:checked" />{{ getTaskCollapseItemName(elementType) }}</template
+ >
+ <element-task :id="elementId" :type="elementType" />
+ </el-collapse-item>
+ <el-collapse-item
+ name="multiInstance"
+ v-if="elementType.indexOf('Task') !== -1"
+ key="multiInstance"
+ >
+ <template #title><Icon icon="ep:help-filled" />澶氫汉瀹℃壒鏂瑰紡</template>
+ <element-multi-instance
+ :id="elementId"
+ :business-object="elementBusinessObject"
+ :type="elementType"
+ />
+ </el-collapse-item>
+ <el-collapse-item name="listeners" key="listeners">
+ <template #title><Icon icon="ep:bell-filled" />鎵ц鐩戝惉鍣�</template>
+ <element-listeners :id="elementId" :type="elementType" />
+ </el-collapse-item>
+ <el-collapse-item name="taskListeners" v-if="elementType === 'UserTask'" key="taskListeners">
+ <template #title><Icon icon="ep:bell-filled" />浠诲姟鐩戝惉鍣�</template>
+ <user-task-listeners :id="elementId" :type="elementType" />
+ </el-collapse-item>
+ <el-collapse-item name="extensions" key="extensions">
+ <template #title><Icon icon="ep:circle-plus-filled" />鎵╁睍灞炴��</template>
+ <element-properties :id="elementId" :type="elementType" />
+ </el-collapse-item>
+ <el-collapse-item name="other" key="other">
+ <template #title><Icon icon="ep:promotion" />鍏朵粬</template>
+ <element-other-config :id="elementId" />
+ </el-collapse-item>
+ <el-collapse-item name="customConfig" key="customConfig">
+ <template #title><Icon icon="ep:tools" />鑷畾涔夐厤缃�</template>
+ <element-custom-config
+ :id="elementId"
+ :type="elementType"
+ :business-object="elementBusinessObject"
+ />
+ </el-collapse-item>
+ <!-- 鏂板鐨勬椂闂翠簨浠堕厤缃」 -->
+ <el-collapse-item v-if="elementType === 'IntermediateCatchEvent'" name="timeEvent">
+ <template #title><Icon icon="ep:timer" />鏃堕棿浜嬩欢</template>
+ <!-- 鐩稿叧 issue锛歨ttps://gitee.com/yudaocode/yudao-ui-admin-vue3/issues/ICNRW2 -->
+ <TimeEventConfig :businessObject="elementBusinessObject" :key="elementId" />
+ </el-collapse-item>
+ </el-collapse>
+ </div>
+</template>
+<script lang="ts" setup>
+import ElementBaseInfo from './base/ElementBaseInfo.vue'
+import ElementOtherConfig from './other/ElementOtherConfig.vue'
+import ElementTask from './task/ElementTask.vue'
+import ElementMultiInstance from './multi-instance/ElementMultiInstance.vue'
+import FlowCondition from './flow-condition/FlowCondition.vue'
+import SignalAndMassage from './signal-message/SignalAndMessage.vue'
+import ElementListeners from './listeners/ElementListeners.vue'
+import ElementProperties from './properties/ElementProperties.vue'
+// import ElementForm from './form/ElementForm.vue'
+import UserTaskListeners from './listeners/UserTaskListeners.vue'
+import { getTaskCollapseItemName, isTaskCollapseItemShow } from './task/data'
+import TimeEventConfig from './time-event-config/TimeEventConfig.vue'
+import { ref, watch, onMounted } from 'vue'
+
+defineOptions({ name: 'MyPropertiesPanel' })
+
+/**
+ * 渚ц竟鏍�
+ * @Author MiyueFE
+ * @Home https://github.com/miyuesc
+ * @Date 2021骞�3鏈�31鏃�18:57:51
+ */
+const props = defineProps({
+ bpmnModeler: {
+ type: Object,
+ default: () => {}
+ },
+ prefix: {
+ type: String,
+ default: 'camunda'
+ },
+ width: {
+ type: Number,
+ default: 480
+ },
+ idEditDisabled: {
+ type: Boolean,
+ default: false
+ },
+ model: Object // 娴佺▼妯″瀷鐨勬暟鎹�
+})
+
+const activeTab = ref('base')
+const elementId = ref('')
+const elementType = ref('')
+const elementBusinessObject = ref<any>({}) // 鍏冪礌 businessObject 闀滃儚锛屾彁渚涚粰闇�瑕佸仛鍒ゆ柇鐨勭粍浠朵娇鐢�
+const conditionFormVisible = ref(false) // 娴佽浆鏉′欢璁剧疆
+const formVisible = ref(false) // 琛ㄥ崟閰嶇疆
+const bpmnElement = ref()
+const isReady = ref(false)
+
+const type = ref('time')
+const condition = ref('')
+provide('prefix', props.prefix)
+provide('width', props.width)
+
+// 鍒濆鍖� bpmnInstances
+const initBpmnInstances = () => {
+ if (!props.bpmnModeler) return false
+ try {
+ const instances = {
+ modeler: props.bpmnModeler,
+ modeling: props.bpmnModeler.get('modeling'),
+ moddle: props.bpmnModeler.get('moddle'),
+ eventBus: props.bpmnModeler.get('eventBus'),
+ bpmnFactory: props.bpmnModeler.get('bpmnFactory'),
+ elementFactory: props.bpmnModeler.get('elementFactory'),
+ elementRegistry: props.bpmnModeler.get('elementRegistry'),
+ replace: props.bpmnModeler.get('replace'),
+ selection: props.bpmnModeler.get('selection')
+ }
+
+ // 妫�鏌ユ墍鏈夊疄渚嬫槸鍚﹂兘瀛樺湪
+ const allInstancesExist = Object.values(instances).every((instance) => instance)
+ if (allInstancesExist) {
+ const w = window as any
+ w.bpmnInstances = instances
+ return true
+ }
+ return false
+ } catch (error) {
+ console.error('鍒濆鍖� bpmnInstances 澶辫触:', error)
+ return false
+ }
+}
+
+const bpmnInstances = () => (window as any)?.bpmnInstances
+
+// 鐩戝惉 props.bpmnModeler 鐒跺悗 initModels
+const unwatchBpmn = watch(
+ () => props.bpmnModeler,
+ async () => {
+ // 閬垮厤鍔犺浇鏃� 娴佺▼鍥� 骞舵湭鍔犺浇瀹屾垚
+ if (!props.bpmnModeler) {
+ console.log('缂哄皯props.bpmnModeler')
+ return
+ }
+
+ try {
+ // 绛夊緟 modeler 鍒濆鍖栧畬鎴�
+ await nextTick()
+ if (initBpmnInstances()) {
+ isReady.value = true
+ await nextTick()
+ getActiveElement()
+ } else {
+ console.error('modeler 瀹炰緥鏈畬鍏ㄥ垵濮嬪寲')
+ }
+ } catch (error) {
+ console.error('鍒濆鍖栧け璐�:', error)
+ }
+ },
+ {
+ immediate: true
+ }
+)
+
+const getActiveElement = () => {
+ if (!isReady.value || !props.bpmnModeler) return
+
+ // 鍒濆绗竴涓�変腑鍏冪礌 bpmn:Process
+ initFormOnChanged(null)
+ props.bpmnModeler.on('import.done', (e) => {
+ console.log(e, 'eeeee')
+ initFormOnChanged(null)
+ })
+ // 鐩戝惉閫夋嫨浜嬩欢锛屼慨鏀瑰綋鍓嶆縺娲荤殑鍏冪礌浠ュ強琛ㄥ崟
+ props.bpmnModeler.on('selection.changed', ({ newSelection }) => {
+ initFormOnChanged(newSelection[0] || null)
+ })
+ props.bpmnModeler.on('element.changed', ({ element }) => {
+ // 淇濊瘉 淇敼 "榛樿娴佽浆璺緞" 绫讳技闇�瑕佷慨鏀瑰涓厓绱犵殑浜嬩欢鍙戠敓鐨勬椂鍊欙紝鏇存柊琛ㄥ崟鐨勫厓绱犱笌鍘熼�変腑鍏冪礌涓嶄竴鑷淬��
+ if (element && element.id === elementId.value) {
+ initFormOnChanged(element)
+ }
+ })
+}
+
+// 鍒濆鍖栨暟鎹�
+const initFormOnChanged = (element) => {
+ if (!isReady.value || !bpmnInstances()) return
+
+ let activatedElement = element
+ if (!activatedElement) {
+ activatedElement =
+ bpmnInstances().elementRegistry.find((el) => el.type === 'bpmn:Process') ??
+ bpmnInstances().elementRegistry.find((el) => el.type === 'bpmn:Collaboration')
+ }
+ if (!activatedElement) return
+
+ try {
+ console.log(`
+ ----------
+ select element changed:
+ id: ${activatedElement.id}
+ type: ${activatedElement.businessObject.$type}
+ ----------
+ `)
+ console.log('businessObject: ', activatedElement.businessObject)
+ bpmnInstances().bpmnElement = activatedElement
+ bpmnElement.value = activatedElement
+ elementId.value = activatedElement.id
+ elementType.value = activatedElement.type.split(':')[1] || ''
+ elementBusinessObject.value = JSON.parse(JSON.stringify(activatedElement.businessObject))
+ conditionFormVisible.value = !!(
+ elementType.value === 'SequenceFlow' &&
+ activatedElement.source &&
+ activatedElement.source.type.indexOf('StartEvent') === -1
+ )
+ formVisible.value = elementType.value === 'UserTask' || elementType.value === 'StartEvent'
+ } catch (error) {
+ console.error('鍒濆鍖栬〃鍗曟暟鎹け璐�:', error)
+ }
+}
+
+onBeforeUnmount(() => {
+ const w = window as any
+ w.bpmnInstances = null
+ isReady.value = false
+})
+
+watch(
+ () => elementId.value,
+ () => {
+ activeTab.value = 'base'
+ }
+)
+
+function updateNode() {
+ const moddle = window.bpmnInstances?.moddle
+ const modeling = window.bpmnInstances?.modeling
+ const elementRegistry = window.bpmnInstances?.elementRegistry
+ if (!moddle || !modeling || !elementRegistry) return
+
+ const element = elementRegistry.get(props.businessObject.id)
+ if (!element) return
+
+ let timerDef = moddle.create('bpmn:TimerEventDefinition', {})
+ if (type.value === 'time') {
+ timerDef.timeDate = moddle.create('bpmn:FormalExpression', { body: condition.value })
+ } else if (type.value === 'duration') {
+ timerDef.timeDuration = moddle.create('bpmn:FormalExpression', { body: condition.value })
+ } else if (type.value === 'cycle') {
+ timerDef.timeCycle = moddle.create('bpmn:FormalExpression', { body: condition.value })
+ }
+
+ modeling.updateModdleProperties(element, element.businessObject, {
+ eventDefinitions: [timerDef]
+ })
+}
+
+// 鍒濆鍖栧拰鐩戝惉
+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)
+watch(() => props.businessObject, syncFromBusinessObject, { deep: true })
+</script>
--
Gitblit v1.8.0