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