提交 | 用户 | 时间
820397 1 <template>
H 2   <div class="panel-tab__content">
3     <el-table :data="elementListenersList" size="small" border>
4       <el-table-column label="序号" width="50px" type="index" />
5       <el-table-column
6         label="事件类型"
7         min-width="80px"
8         show-overflow-tooltip
9         :formatter="(row) => listenerEventTypeObject[row.event]"
10       />
11       <el-table-column label="事件id" min-width="80px" prop="id" show-overflow-tooltip />
12       <el-table-column
13         label="监听器类型"
14         min-width="80px"
15         show-overflow-tooltip
16         :formatter="(row) => listenerTypeObject[row.listenerType]"
17       />
18       <el-table-column label="操作" width="90px">
19         <template #default="scope">
20           <el-button size="small" link @click="openListenerForm(scope.row, scope.$index)"
21             >编辑</el-button
22           >
23           <el-divider direction="vertical" />
24           <el-button
25             size="small"
26             link
27             style="color: #ff4d4f"
28             @click="removeListener(scope.row, scope.$index)"
29             >移除</el-button
30           >
31         </template>
32       </el-table-column>
33     </el-table>
34     <div class="element-drawer__button">
35       <XButton
36         size="small"
37         type="primary"
38         preIcon="ep:plus"
39         title="添加监听器"
40         @click="openListenerForm(null)"
41       />
42       <XButton
43         type="success"
44         preIcon="ep:select"
45         title="选择监听器"
46         size="small"
47         @click="openProcessListenerDialog"
48       />
49     </div>
50
51     <!-- 监听器 编辑/创建 部分 -->
52     <el-drawer
53       v-model="listenerFormModelVisible"
54       title="任务监听器"
55       :size="`${width}px`"
56       append-to-body
57       destroy-on-close
58     >
59       <el-form size="small" :model="listenerForm" label-width="96px" ref="listenerFormRef">
60         <el-form-item
61           label="事件类型"
62           prop="event"
63           :rules="{ required: true, trigger: ['blur', 'change'] }"
64         >
65           <el-select v-model="listenerForm.event">
66             <el-option
67               v-for="i in Object.keys(listenerEventTypeObject)"
68               :key="i"
69               :label="listenerEventTypeObject[i]"
70               :value="i"
71             />
72           </el-select>
73         </el-form-item>
74         <el-form-item
75           label="监听器ID"
76           prop="id"
77           :rules="{ required: true, trigger: ['blur', 'change'] }"
78         >
79           <el-input v-model="listenerForm.id" clearable />
80         </el-form-item>
81         <el-form-item
82           label="监听器类型"
83           prop="listenerType"
84           :rules="{ required: true, trigger: ['blur', 'change'] }"
85         >
86           <el-select v-model="listenerForm.listenerType">
87             <el-option
88               v-for="i in Object.keys(listenerTypeObject)"
89               :key="i"
90               :label="listenerTypeObject[i]"
91               :value="i"
92             />
93           </el-select>
94         </el-form-item>
95         <el-form-item
96           v-if="listenerForm.listenerType === 'classListener'"
97           label="Java类"
98           prop="class"
99           key="listener-class"
100           :rules="{ required: true, trigger: ['blur', 'change'] }"
101         >
102           <el-input v-model="listenerForm.class" clearable />
103         </el-form-item>
104         <el-form-item
105           v-if="listenerForm.listenerType === 'expressionListener'"
106           label="表达式"
107           prop="expression"
108           key="listener-expression"
109           :rules="{ required: true, trigger: ['blur', 'change'] }"
110         >
111           <el-input v-model="listenerForm.expression" clearable />
112         </el-form-item>
113         <el-form-item
114           v-if="listenerForm.listenerType === 'delegateExpressionListener'"
115           label="代理表达式"
116           prop="delegateExpression"
117           key="listener-delegate"
118           :rules="{ required: true, trigger: ['blur', 'change'] }"
119         >
120           <el-input v-model="listenerForm.delegateExpression" clearable />
121         </el-form-item>
122         <template v-if="listenerForm.listenerType === 'scriptListener'">
123           <el-form-item
124             label="脚本格式"
125             prop="scriptFormat"
126             key="listener-script-format"
127             :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本格式' }"
128           >
129             <el-input v-model="listenerForm.scriptFormat" clearable />
130           </el-form-item>
131           <el-form-item
132             label="脚本类型"
133             prop="scriptType"
134             key="listener-script-type"
135             :rules="{ required: true, trigger: ['blur', 'change'], message: '请选择脚本类型' }"
136           >
137             <el-select v-model="listenerForm.scriptType">
138               <el-option label="内联脚本" value="inlineScript" />
139               <el-option label="外部脚本" value="externalScript" />
140             </el-select>
141           </el-form-item>
142           <el-form-item
143             v-if="listenerForm.scriptType === 'inlineScript'"
144             label="脚本内容"
145             prop="value"
146             key="listener-script"
147             :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本内容' }"
148           >
149             <el-input v-model="listenerForm.value" clearable />
150           </el-form-item>
151           <el-form-item
152             v-if="listenerForm.scriptType === 'externalScript'"
153             label="资源地址"
154             prop="resource"
155             key="listener-resource"
156             :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写资源地址' }"
157           >
158             <el-input v-model="listenerForm.resource" clearable />
159           </el-form-item>
160         </template>
161
162         <template v-if="listenerForm.event === 'timeout'">
163           <el-form-item label="定时器类型" prop="eventDefinitionType" key="eventDefinitionType">
164             <el-select v-model="listenerForm.eventDefinitionType">
165               <el-option label="日期" value="date" />
166               <el-option label="持续时长" value="duration" />
167               <el-option label="循环" value="cycle" />
168               <el-option label="无" value="null" />
169             </el-select>
170           </el-form-item>
171           <el-form-item
172             v-if="!!listenerForm.eventDefinitionType && listenerForm.eventDefinitionType !== 'null'"
173             label="定时器"
174             prop="eventTimeDefinitions"
175             key="eventTimeDefinitions"
176             :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写定时器配置' }"
177           >
178             <el-input v-model="listenerForm.eventTimeDefinitions" clearable />
179           </el-form-item>
180         </template>
181       </el-form>
182
183       <el-divider />
184       <p class="listener-filed__title">
185         <span><Icon icon="ep:menu" />注入字段:</span>
186         <el-button size="small" type="primary" @click="openListenerFieldForm(null)"
187           >添加字段</el-button
188         >
189       </p>
190       <el-table
191         :data="fieldsListOfListener"
192         size="small"
193         max-height="240"
194         fit
195         border
196         style="flex: none"
197       >
198         <el-table-column label="序号" width="50px" type="index" />
199         <el-table-column label="字段名称" min-width="100px" prop="name" />
200         <el-table-column
201           label="字段类型"
202           min-width="80px"
203           show-overflow-tooltip
204           :formatter="(row) => fieldTypeObject[row.fieldType]"
205         />
206         <el-table-column
207           label="字段值/表达式"
208           min-width="100px"
209           show-overflow-tooltip
210           :formatter="(row) => row.string || row.expression"
211         />
212         <el-table-column label="操作" width="100px">
213           <template #default="scope">
214             <el-button size="small" link @click="openListenerFieldForm(scope.row, scope.$index)"
215               >编辑</el-button
216             >
217             <el-divider direction="vertical" />
218             <el-button
219               size="small"
220               link
221               style="color: #ff4d4f"
222               @click="removeListenerField(scope.row, scope.$index)"
223               >移除</el-button
224             >
225           </template>
226         </el-table-column>
227       </el-table>
228
229       <div class="element-drawer__button">
230         <el-button size="small" @click="listenerFormModelVisible = false">取 消</el-button>
231         <el-button size="small" type="primary" @click="saveListenerConfig">保 存</el-button>
232       </div>
233     </el-drawer>
234
235     <!-- 注入西段 编辑/创建 部分 -->
236     <el-dialog
237       title="字段配置"
238       v-model="listenerFieldFormModelVisible"
239       width="600px"
240       append-to-body
241       destroy-on-close
242     >
243       <el-form
244         :model="listenerFieldForm"
245         size="small"
246         label-width="96px"
247         ref="listenerFieldFormRef"
248         style="height: 136px"
249       >
250         <el-form-item
251           label="字段名称:"
252           prop="name"
253           :rules="{ required: true, trigger: ['blur', 'change'] }"
254         >
255           <el-input v-model="listenerFieldForm.name" clearable />
256         </el-form-item>
257         <el-form-item
258           label="字段类型:"
259           prop="fieldType"
260           :rules="{ required: true, trigger: ['blur', 'change'] }"
261         >
262           <el-select v-model="listenerFieldForm.fieldType">
263             <el-option
264               v-for="i in Object.keys(fieldTypeObject)"
265               :key="i"
266               :label="fieldTypeObject[i]"
267               :value="i"
268             />
269           </el-select>
270         </el-form-item>
271         <el-form-item
272           v-if="listenerFieldForm.fieldType === 'string'"
273           label="字段值:"
274           prop="string"
275           key="field-string"
276           :rules="{ required: true, trigger: ['blur', 'change'] }"
277         >
278           <el-input v-model="listenerFieldForm.string" clearable />
279         </el-form-item>
280         <el-form-item
281           v-if="listenerFieldForm.fieldType === 'expression'"
282           label="表达式:"
283           prop="expression"
284           key="field-expression"
285           :rules="{ required: true, trigger: ['blur', 'change'] }"
286         >
287           <el-input v-model="listenerFieldForm.expression" clearable />
288         </el-form-item>
289       </el-form>
290       <template #footer>
291         <el-button size="small" @click="listenerFieldFormModelVisible = false">取 消</el-button>
292         <el-button size="small" type="primary" @click="saveListenerFiled">确 定</el-button>
293       </template>
294     </el-dialog>
295   </div>
296
297   <!-- 选择弹窗 -->
298   <ProcessListenerDialog ref="processListenerDialogRef" @select="selectProcessListener" />
299 </template>
300 <script lang="ts" setup>
301 import { ElMessageBox } from 'element-plus'
302 import { createListenerObject, updateElementExtensions } from '../../utils'
303 import {
304   initListenerForm,
305   initListenerType,
306   eventType,
307   listenerType,
308   fieldType,
309   initListenerForm2
310 } from './utilSelf'
311 import ProcessListenerDialog from '@/components/bpmnProcessDesigner/package/penal/listeners/ProcessListenerDialog.vue'
312
313 defineOptions({ name: 'UserTaskListeners' })
314
315 const props = defineProps({
316   id: String,
317   type: String
318 })
319 const prefix = inject('prefix')
320 const width = inject('width')
321 const elementListenersList = ref<any[]>([])
322 const listenerEventTypeObject = ref(eventType)
323 const listenerTypeObject = ref(listenerType)
324 const listenerFormModelVisible = ref(false)
325 const listenerForm = ref<any>({})
326 const fieldTypeObject = ref(fieldType)
327 const fieldsListOfListener = ref<any[]>([])
328 const listenerFieldFormModelVisible = ref(false) // 监听器 注入字段表单弹窗 显示状态
329 const editingListenerIndex = ref(-1) // 监听器所在下标,-1 为新增
330 const editingListenerFieldIndex = ref(-1) // 字段所在下标,-1 为新增
331 const listenerFieldForm = ref<any>({}) // 监听器 注入字段 详情表单
332 const bpmnElement = ref()
333 const bpmnElementListeners = ref()
334 const otherExtensionList = ref()
335 const listenerFormRef = ref()
336 const listenerFieldFormRef = ref()
337 const bpmnInstances = () => (window as any)?.bpmnInstances
338
339 const resetListenersList = () => {
340   bpmnElement.value = bpmnInstances().bpmnElement
341   otherExtensionList.value = []
342   bpmnElementListeners.value =
343     bpmnElement.value.businessObject?.extensionElements?.values.filter(
344       (ex) => ex.$type === `${prefix}:TaskListener`
345     ) ?? []
9259c2 346   console.log(bpmnElementListeners.value.map)
820397 347   elementListenersList.value = bpmnElementListeners.value.map((listener) =>
H 348     initListenerType(listener)
349   )
350 }
351 const openListenerForm = (listener, index?) => {
352   if (listener) {
353     listenerForm.value = initListenerForm(listener)
354     editingListenerIndex.value = index
355   } else {
356     listenerForm.value = {}
357     editingListenerIndex.value = -1 // 标记为新增
358   }
359   if (listener && listener.fields) {
360     fieldsListOfListener.value = listener.fields.map((field) => ({
361       ...field,
362       fieldType: field.string ? 'string' : 'expression'
363     }))
364   } else {
365     fieldsListOfListener.value = []
366     listenerForm.value['fields'] = []
367   }
368   // 打开侧边栏并清楚验证状态
369   listenerFormModelVisible.value = true
370   nextTick(() => {
371     if (listenerFormRef.value) listenerFormRef.value.clearValidate()
372   })
373 }
374 // 移除监听器
375 const removeListener = (listener, index?) => {
376   console.log(listener, 'listener')
377   ElMessageBox.confirm('确认移除该监听器吗?', '提示', {
378     confirmButtonText: '确 认',
379     cancelButtonText: '取 消'
380   })
381     .then(() => {
382       bpmnElementListeners.value.splice(index, 1)
383       elementListenersList.value.splice(index, 1)
384       updateElementExtensions(
385         bpmnElement.value,
386         otherExtensionList.value.concat(bpmnElementListeners.value)
387       )
388     })
389     .catch(() => console.info('操作取消'))
390 }
391 // 保存监听器
392 const saveListenerConfig = async () => {
393   let validateStatus = await listenerFormRef.value.validate()
394   if (!validateStatus) return // 验证不通过直接返回
395   const listenerObject = createListenerObject(listenerForm.value, true, prefix)
396   if (editingListenerIndex.value === -1) {
397     bpmnElementListeners.value.push(listenerObject)
398     elementListenersList.value.push(listenerForm.value)
399   } else {
400     bpmnElementListeners.value.splice(editingListenerIndex.value, 1, listenerObject)
401     elementListenersList.value.splice(editingListenerIndex.value, 1, listenerForm.value)
402   }
403   // 保存其他配置
404   otherExtensionList.value =
405     bpmnElement.value.businessObject?.extensionElements?.values?.filter(
406       (ex) => ex.$type !== `${prefix}:TaskListener`
407     ) ?? []
408   updateElementExtensions(
409     bpmnElement.value,
410     otherExtensionList.value.concat(bpmnElementListeners.value)
411   )
412   // 4. 隐藏侧边栏
413   listenerFormModelVisible.value = false
414   listenerForm.value = {}
415 }
416 // 打开监听器字段编辑弹窗
417 const openListenerFieldForm = (field, index?) => {
418   listenerFieldForm.value = field ? JSON.parse(JSON.stringify(field)) : {}
419   editingListenerFieldIndex.value = field ? index : -1
420   listenerFieldFormModelVisible.value = true
421   nextTick(() => {
422     if (listenerFieldFormRef.value) listenerFieldFormRef.value.clearValidate()
423   })
424 }
425 // 保存监听器注入字段
426 const saveListenerFiled = async () => {
427   let validateStatus = await listenerFieldFormRef.value.validate()
428   if (!validateStatus) return // 验证不通过直接返回
429   if (editingListenerFieldIndex.value === -1) {
430     fieldsListOfListener.value.push(listenerFieldForm.value)
431     listenerForm.value.fields.push(listenerFieldForm.value)
432   } else {
433     fieldsListOfListener.value.splice(editingListenerFieldIndex.value, 1, listenerFieldForm.value)
434     listenerForm.value.fields.splice(editingListenerFieldIndex.value, 1, listenerFieldForm.value)
435   }
436   listenerFieldFormModelVisible.value = false
437   nextTick(() => {
438     listenerFieldForm.value = {}
439   })
440 }
441 // 移除监听器字段
442 const removeListenerField = (field, index) => {
443   console.log(field, 'field')
444   ElMessageBox.confirm('确认移除该字段吗?', '提示', {
445     confirmButtonText: '确 认',
446     cancelButtonText: '取 消'
447   })
448     .then(() => {
449       fieldsListOfListener.value.splice(index, 1)
450       listenerForm.value.fields.splice(index, 1)
451     })
452     .catch(() => console.info('操作取消'))
453 }
454
455 // 打开监听器弹窗
456 const processListenerDialogRef = ref()
457 const openProcessListenerDialog = async () => {
458   processListenerDialogRef.value.open('task')
459 }
460 const selectProcessListener = (listener) => {
461   const listenerForm = initListenerForm2(listener)
462   const listenerObject = createListenerObject(listenerForm, true, prefix)
463   bpmnElementListeners.value.push(listenerObject)
464   elementListenersList.value.push(listenerForm)
465
466   // 保存其他配置
467   otherExtensionList.value =
468     bpmnElement.value.businessObject?.extensionElements?.values?.filter(
469       (ex) => ex.$type !== `${prefix}:TaskListener`
470     ) ?? []
471   updateElementExtensions(
472     bpmnElement.value,
473     otherExtensionList.value.concat(bpmnElementListeners.value)
474   )
475 }
476
477 watch(
478   () => props.id,
479   (val) => {
480     val &&
481       val.length &&
482       nextTick(() => {
483         resetListenersList()
484       })
485   },
486   { immediate: true }
487 )
488 </script>