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/listeners/UserTaskListeners.vue | 510 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 510 insertions(+), 0 deletions(-)
diff --git a/src/components/bpmnProcessDesigner/package/penal/listeners/UserTaskListeners.vue b/src/components/bpmnProcessDesigner/package/penal/listeners/UserTaskListeners.vue
new file mode 100644
index 0000000..cea9f1b
--- /dev/null
+++ b/src/components/bpmnProcessDesigner/package/penal/listeners/UserTaskListeners.vue
@@ -0,0 +1,510 @@
+<template>
+ <div class="panel-tab__content">
+ <el-table :data="elementListenersList" size="small" border>
+ <el-table-column label="搴忓彿" width="50px" type="index" />
+ <el-table-column
+ label="浜嬩欢绫诲瀷"
+ min-width="80px"
+ show-overflow-tooltip
+ :formatter="(row) => listenerEventTypeObject[row.event]"
+ />
+ <el-table-column label="浜嬩欢id" min-width="80px" prop="id" show-overflow-tooltip />
+ <el-table-column
+ label="鐩戝惉鍣ㄧ被鍨�"
+ min-width="80px"
+ show-overflow-tooltip
+ :formatter="(row) => listenerTypeObject[row.listenerType]"
+ />
+ <el-table-column label="鎿嶄綔" width="90px">
+ <template #default="scope">
+ <el-button size="small" link @click="openListenerForm(scope.row, scope.$index)"
+ >缂栬緫</el-button
+ >
+ <el-divider direction="vertical" />
+ <el-button
+ size="small"
+ link
+ style="color: #ff4d4f"
+ @click="removeListener(scope.row, scope.$index)"
+ >绉婚櫎</el-button
+ >
+ </template>
+ </el-table-column>
+ </el-table>
+ <div class="element-drawer__button">
+ <XButton
+ size="small"
+ type="primary"
+ preIcon="ep:plus"
+ title="娣诲姞鐩戝惉鍣�"
+ @click="openListenerForm(null)"
+ />
+ <XButton
+ type="success"
+ preIcon="ep:select"
+ title="閫夋嫨鐩戝惉鍣�"
+ size="small"
+ @click="openProcessListenerDialog"
+ />
+ </div>
+
+ <!-- 鐩戝惉鍣� 缂栬緫/鍒涘缓 閮ㄥ垎 -->
+ <el-drawer
+ v-model="listenerFormModelVisible"
+ title="浠诲姟鐩戝惉鍣�"
+ :size="`${width}px`"
+ append-to-body
+ destroy-on-close
+ >
+ <el-form size="small" :model="listenerForm" label-width="96px" ref="listenerFormRef">
+ <el-form-item
+ label="浜嬩欢绫诲瀷"
+ prop="event"
+ :rules="{ required: true, trigger: ['blur', 'change'] }"
+ >
+ <el-select v-model="listenerForm.event">
+ <el-option
+ v-for="i in Object.keys(listenerEventTypeObject)"
+ :key="i"
+ :label="listenerEventTypeObject[i]"
+ :value="i"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item
+ label="鐩戝惉鍣↖D"
+ prop="id"
+ :rules="{ required: true, trigger: ['blur', 'change'] }"
+ >
+ <el-input v-model="listenerForm.id" clearable />
+ </el-form-item>
+ <el-form-item
+ label="鐩戝惉鍣ㄧ被鍨�"
+ prop="listenerType"
+ :rules="{ required: true, trigger: ['blur', 'change'] }"
+ >
+ <el-select v-model="listenerForm.listenerType">
+ <el-option
+ v-for="i in Object.keys(listenerTypeObject)"
+ :key="i"
+ :label="listenerTypeObject[i]"
+ :value="i"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item
+ v-if="listenerForm.listenerType === 'classListener'"
+ label="Java绫�"
+ prop="class"
+ key="listener-class"
+ :rules="{ required: true, trigger: ['blur', 'change'] }"
+ >
+ <el-input v-model="listenerForm.class" clearable />
+ </el-form-item>
+ <el-form-item
+ v-if="listenerForm.listenerType === 'expressionListener'"
+ label="琛ㄨ揪寮�"
+ prop="expression"
+ key="listener-expression"
+ :rules="{ required: true, trigger: ['blur', 'change'] }"
+ >
+ <el-input v-model="listenerForm.expression" clearable />
+ </el-form-item>
+ <el-form-item
+ v-if="listenerForm.listenerType === 'delegateExpressionListener'"
+ label="浠g悊琛ㄨ揪寮�"
+ prop="delegateExpression"
+ key="listener-delegate"
+ :rules="{ required: true, trigger: ['blur', 'change'] }"
+ >
+ <el-input v-model="listenerForm.delegateExpression" clearable />
+ </el-form-item>
+ <template v-if="listenerForm.listenerType === 'scriptListener'">
+ <el-form-item
+ label="鑴氭湰鏍煎紡"
+ prop="scriptFormat"
+ key="listener-script-format"
+ :rules="{ required: true, trigger: ['blur', 'change'], message: '璇峰~鍐欒剼鏈牸寮�' }"
+ >
+ <el-input v-model="listenerForm.scriptFormat" clearable />
+ </el-form-item>
+ <el-form-item
+ label="鑴氭湰绫诲瀷"
+ prop="scriptType"
+ key="listener-script-type"
+ :rules="{ required: true, trigger: ['blur', 'change'], message: '璇烽�夋嫨鑴氭湰绫诲瀷' }"
+ >
+ <el-select v-model="listenerForm.scriptType">
+ <el-option label="鍐呰仈鑴氭湰" value="inlineScript" />
+ <el-option label="澶栭儴鑴氭湰" value="externalScript" />
+ </el-select>
+ </el-form-item>
+ <el-form-item
+ v-if="listenerForm.scriptType === 'inlineScript'"
+ label="鑴氭湰鍐呭"
+ prop="value"
+ key="listener-script"
+ :rules="{ required: true, trigger: ['blur', 'change'], message: '璇峰~鍐欒剼鏈唴瀹�' }"
+ >
+ <el-input v-model="listenerForm.value" clearable />
+ </el-form-item>
+ <el-form-item
+ v-if="listenerForm.scriptType === 'externalScript'"
+ label="璧勬簮鍦板潃"
+ prop="resource"
+ key="listener-resource"
+ :rules="{ required: true, trigger: ['blur', 'change'], message: '璇峰~鍐欒祫婧愬湴鍧�' }"
+ >
+ <el-input v-model="listenerForm.resource" clearable />
+ </el-form-item>
+ </template>
+
+ <template v-if="listenerForm.event === 'timeout'">
+ <el-form-item label="瀹氭椂鍣ㄧ被鍨�" prop="eventDefinitionType" key="eventDefinitionType">
+ <el-select v-model="listenerForm.eventDefinitionType">
+ <el-option label="鏃ユ湡" value="date" />
+ <el-option label="鎸佺画鏃堕暱" value="duration" />
+ <el-option label="寰幆" value="cycle" />
+ <el-option label="鏃�" value="null" />
+ </el-select>
+ </el-form-item>
+ <el-form-item
+ v-if="!!listenerForm.eventDefinitionType && listenerForm.eventDefinitionType !== 'null'"
+ label="瀹氭椂鍣�"
+ prop="eventTimeDefinitions"
+ key="eventTimeDefinitions"
+ :rules="{ required: true, trigger: ['blur', 'change'], message: '璇峰~鍐欏畾鏃跺櫒閰嶇疆' }"
+ >
+ <el-input v-model="listenerForm.eventTimeDefinitions" clearable />
+ </el-form-item>
+ </template>
+ </el-form>
+
+ <el-divider />
+ <p class="listener-filed__title">
+ <span><Icon icon="ep:menu" />娉ㄥ叆瀛楁锛�</span>
+ <el-button size="small" type="primary" @click="openListenerFieldForm(null)"
+ >娣诲姞瀛楁</el-button
+ >
+ </p>
+ <el-table
+ :data="fieldsListOfListener"
+ size="small"
+ max-height="240"
+ fit
+ border
+ style="flex: none"
+ >
+ <el-table-column label="搴忓彿" width="50px" type="index" />
+ <el-table-column label="瀛楁鍚嶇О" min-width="100px" prop="name" />
+ <el-table-column
+ label="瀛楁绫诲瀷"
+ min-width="80px"
+ show-overflow-tooltip
+ :formatter="(row) => fieldTypeObject[row.fieldType]"
+ />
+ <el-table-column
+ label="瀛楁鍊�/琛ㄨ揪寮�"
+ min-width="100px"
+ show-overflow-tooltip
+ :formatter="(row) => row.string || row.expression"
+ />
+ <el-table-column label="鎿嶄綔" width="100px">
+ <template #default="scope">
+ <el-button size="small" link @click="openListenerFieldForm(scope.row, scope.$index)"
+ >缂栬緫</el-button
+ >
+ <el-divider direction="vertical" />
+ <el-button
+ size="small"
+ link
+ style="color: #ff4d4f"
+ @click="removeListenerField(scope.row, scope.$index)"
+ >绉婚櫎</el-button
+ >
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <div class="element-drawer__button">
+ <el-button size="small" @click="listenerFormModelVisible = false">鍙� 娑�</el-button>
+ <el-button size="small" type="primary" @click="saveListenerConfig">淇� 瀛�</el-button>
+ </div>
+ </el-drawer>
+
+ <!-- 娉ㄥ叆瑗挎 缂栬緫/鍒涘缓 閮ㄥ垎 -->
+ <el-dialog
+ title="瀛楁閰嶇疆"
+ v-model="listenerFieldFormModelVisible"
+ width="600px"
+ append-to-body
+ destroy-on-close
+ >
+ <el-form
+ :model="listenerFieldForm"
+ size="small"
+ label-width="96px"
+ ref="listenerFieldFormRef"
+ style="height: 136px"
+ >
+ <el-form-item
+ label="瀛楁鍚嶇О锛�"
+ prop="name"
+ :rules="{ required: true, trigger: ['blur', 'change'] }"
+ >
+ <el-input v-model="listenerFieldForm.name" clearable />
+ </el-form-item>
+ <el-form-item
+ label="瀛楁绫诲瀷锛�"
+ prop="fieldType"
+ :rules="{ required: true, trigger: ['blur', 'change'] }"
+ >
+ <el-select v-model="listenerFieldForm.fieldType">
+ <el-option
+ v-for="i in Object.keys(fieldTypeObject)"
+ :key="i"
+ :label="fieldTypeObject[i]"
+ :value="i"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item
+ v-if="listenerFieldForm.fieldType === 'string'"
+ label="瀛楁鍊硷細"
+ prop="string"
+ key="field-string"
+ :rules="{ required: true, trigger: ['blur', 'change'] }"
+ >
+ <el-input v-model="listenerFieldForm.string" clearable />
+ </el-form-item>
+ <el-form-item
+ v-if="listenerFieldForm.fieldType === 'expression'"
+ label="琛ㄨ揪寮忥細"
+ prop="expression"
+ key="field-expression"
+ :rules="{ required: true, trigger: ['blur', 'change'] }"
+ >
+ <el-input v-model="listenerFieldForm.expression" clearable />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <el-button size="small" @click="listenerFieldFormModelVisible = false">鍙� 娑�</el-button>
+ <el-button size="small" type="primary" @click="saveListenerFiled">纭� 瀹�</el-button>
+ </template>
+ </el-dialog>
+ </div>
+
+ <!-- 閫夋嫨寮圭獥 -->
+ <ProcessListenerDialog ref="processListenerDialogRef" @select="selectProcessListener" />
+</template>
+<script lang="ts" setup>
+import { ElMessageBox } from 'element-plus'
+import { createListenerObject, updateElementExtensions } from '../../utils'
+import {
+ initListenerForm,
+ initListenerType,
+ eventType,
+ listenerType,
+ fieldType,
+ initListenerForm2
+} from './utilSelf'
+import ProcessListenerDialog from '@/components/bpmnProcessDesigner/package/penal/listeners/ProcessListenerDialog.vue'
+
+defineOptions({ name: 'UserTaskListeners' })
+
+const props = defineProps({
+ id: String,
+ type: String
+})
+const prefix = inject('prefix')
+const width = inject('width')
+const elementListenersList = ref<any[]>([])
+const listenerEventTypeObject = ref(eventType)
+const listenerTypeObject = ref(listenerType)
+const listenerFormModelVisible = ref(false)
+const listenerForm = ref<any>({})
+const fieldTypeObject = ref(fieldType)
+const fieldsListOfListener = ref<any[]>([])
+const listenerFieldFormModelVisible = ref(false) // 鐩戝惉鍣� 娉ㄥ叆瀛楁琛ㄥ崟寮圭獥 鏄剧ず鐘舵��
+const editingListenerIndex = ref(-1) // 鐩戝惉鍣ㄦ墍鍦ㄤ笅鏍囷紝-1 涓烘柊澧�
+const editingListenerFieldIndex = ref(-1) // 瀛楁鎵�鍦ㄤ笅鏍囷紝-1 涓烘柊澧�
+const listenerFieldForm = ref<any>({}) // 鐩戝惉鍣� 娉ㄥ叆瀛楁 璇︽儏琛ㄥ崟
+const bpmnElementListeners = ref()
+const otherExtensionList = ref()
+const listenerFormRef = ref()
+const listenerFieldFormRef = ref()
+const bpmnInstances = () => (window as any)?.bpmnInstances
+
+const resetListenersList = () => {
+ const instances = bpmnInstances()
+ if (!instances || !instances.bpmnElement) return
+
+ // 鐩存帴浣跨敤鍘熷BPMN鍏冪礌锛岄伩鍏峍ue鍝嶅簲寮忎唬鐞嗛棶棰�
+ const bpmnElement = instances.bpmnElement
+ const businessObject = bpmnElement.businessObject
+
+ console.log(bpmnElement, 'bpmnElement - resetListenersList')
+
+ otherExtensionList.value =
+ businessObject?.extensionElements?.values?.filter(
+ (ex) => ex.$type !== `${prefix}:TaskListener`
+ ) ?? [] // 淇濈暀闈炵洃鍚櫒绫诲瀷鐨勬墿灞曞睘鎬э紝閬垮厤绉婚櫎鐩戝惉鍣ㄦ椂娓呯┖鍏朵粬閰嶇疆锛堝瀹℃壒浜虹瓑锛夈�傜浉鍏虫渚嬶細https://gitee.com/yudaocode/yudao-ui-admin-vue3/issues/ICMSYC
+ bpmnElementListeners.value =
+ businessObject?.extensionElements?.values?.filter(
+ (ex) => ex.$type === `${prefix}:TaskListener`
+ ) ?? []
+ elementListenersList.value = bpmnElementListeners.value.map((listener) =>
+ initListenerType(listener)
+ )
+}
+const openListenerForm = (listener, index?) => {
+ if (listener) {
+ listenerForm.value = initListenerForm(listener)
+ editingListenerIndex.value = index
+ } else {
+ listenerForm.value = {}
+ editingListenerIndex.value = -1 // 鏍囪涓烘柊澧�
+ }
+ if (listener && listener.fields) {
+ fieldsListOfListener.value = listener.fields.map((field) => ({
+ ...field,
+ fieldType: field.string ? 'string' : 'expression'
+ }))
+ } else {
+ fieldsListOfListener.value = []
+ listenerForm.value['fields'] = []
+ }
+ // 鎵撳紑渚ц竟鏍忓苟娓呮楠岃瘉鐘舵��
+ listenerFormModelVisible.value = true
+ nextTick(() => {
+ if (listenerFormRef.value) listenerFormRef.value.clearValidate()
+ })
+}
+// 绉婚櫎鐩戝惉鍣�
+const removeListener = (listener, index?) => {
+ console.log(listener, 'listener')
+ ElMessageBox.confirm('纭绉婚櫎璇ョ洃鍚櫒鍚楋紵', '鎻愮ず', {
+ confirmButtonText: '纭� 璁�',
+ cancelButtonText: '鍙� 娑�'
+ })
+ .then(() => {
+ const instances = bpmnInstances()
+ if (!instances || !instances.bpmnElement) return
+
+ bpmnElementListeners.value.splice(index, 1)
+ elementListenersList.value.splice(index, 1)
+ updateElementExtensions(
+ instances.bpmnElement,
+ otherExtensionList.value.concat(bpmnElementListeners.value)
+ )
+ })
+ .catch(() => console.info('鎿嶄綔鍙栨秷'))
+}
+// 淇濆瓨鐩戝惉鍣�
+const saveListenerConfig = async () => {
+ let validateStatus = await listenerFormRef.value.validate()
+ if (!validateStatus) return // 楠岃瘉涓嶉�氳繃鐩存帴杩斿洖
+
+ const instances = bpmnInstances()
+ if (!instances || !instances.bpmnElement) return
+
+ const bpmnElement = instances.bpmnElement
+ const listenerObject = createListenerObject(listenerForm.value, true, prefix)
+
+ if (editingListenerIndex.value === -1) {
+ bpmnElementListeners.value.push(listenerObject)
+ elementListenersList.value.push(listenerForm.value)
+ } else {
+ bpmnElementListeners.value.splice(editingListenerIndex.value, 1, listenerObject)
+ elementListenersList.value.splice(editingListenerIndex.value, 1, listenerForm.value)
+ }
+ // 淇濆瓨鍏朵粬閰嶇疆
+ otherExtensionList.value =
+ bpmnElement.businessObject?.extensionElements?.values?.filter(
+ (ex) => ex.$type !== `${prefix}:TaskListener`
+ ) ?? []
+ updateElementExtensions(
+ bpmnElement,
+ otherExtensionList.value.concat(bpmnElementListeners.value)
+ )
+ // 4. 闅愯棌渚ц竟鏍�
+ listenerFormModelVisible.value = false
+ listenerForm.value = {}
+}
+// 鎵撳紑鐩戝惉鍣ㄥ瓧娈电紪杈戝脊绐�
+const openListenerFieldForm = (field, index?) => {
+ listenerFieldForm.value = field ? JSON.parse(JSON.stringify(field)) : {}
+ editingListenerFieldIndex.value = field ? index : -1
+ listenerFieldFormModelVisible.value = true
+ nextTick(() => {
+ if (listenerFieldFormRef.value) listenerFieldFormRef.value.clearValidate()
+ })
+}
+// 淇濆瓨鐩戝惉鍣ㄦ敞鍏ュ瓧娈�
+const saveListenerFiled = async () => {
+ let validateStatus = await listenerFieldFormRef.value.validate()
+ if (!validateStatus) return // 楠岃瘉涓嶉�氳繃鐩存帴杩斿洖
+ if (editingListenerFieldIndex.value === -1) {
+ fieldsListOfListener.value.push(listenerFieldForm.value)
+ listenerForm.value.fields.push(listenerFieldForm.value)
+ } else {
+ fieldsListOfListener.value.splice(editingListenerFieldIndex.value, 1, listenerFieldForm.value)
+ listenerForm.value.fields.splice(editingListenerFieldIndex.value, 1, listenerFieldForm.value)
+ }
+ listenerFieldFormModelVisible.value = false
+ nextTick(() => {
+ listenerFieldForm.value = {}
+ })
+}
+// 绉婚櫎鐩戝惉鍣ㄥ瓧娈�
+const removeListenerField = (field, index) => {
+ console.log(field, 'field')
+ ElMessageBox.confirm('纭绉婚櫎璇ュ瓧娈靛悧锛�', '鎻愮ず', {
+ confirmButtonText: '纭� 璁�',
+ cancelButtonText: '鍙� 娑�'
+ })
+ .then(() => {
+ fieldsListOfListener.value.splice(index, 1)
+ listenerForm.value.fields.splice(index, 1)
+ })
+ .catch(() => console.info('鎿嶄綔鍙栨秷'))
+}
+
+// 鎵撳紑鐩戝惉鍣ㄥ脊绐�
+const processListenerDialogRef = ref()
+const openProcessListenerDialog = async () => {
+ processListenerDialogRef.value.open('task')
+}
+const selectProcessListener = (listener) => {
+ const instances = bpmnInstances()
+ if (!instances || !instances.bpmnElement) return
+
+ const bpmnElement = instances.bpmnElement
+ const listenerForm = initListenerForm2(listener)
+ const listenerObject = createListenerObject(listenerForm, true, prefix)
+ bpmnElementListeners.value.push(listenerObject)
+ elementListenersList.value.push(listenerForm)
+
+ // 淇濆瓨鍏朵粬閰嶇疆
+ otherExtensionList.value =
+ bpmnElement.businessObject?.extensionElements?.values?.filter(
+ (ex) => ex.$type !== `${prefix}:TaskListener`
+ ) ?? []
+ updateElementExtensions(
+ bpmnElement,
+ otherExtensionList.value.concat(bpmnElementListeners.value)
+ )
+}
+
+watch(
+ () => props.id,
+ (val) => {
+ val &&
+ val.length &&
+ nextTick(() => {
+ resetListenersList()
+ })
+ },
+ { immediate: true }
+)
+</script>
--
Gitblit v1.8.0