dengzedong
5 天以前 f9b459a3fefd5fab0ee8e19268adb9d9eadab2a7
提交 | 用户 | 时间
3e359e 1 <!-- UserTask 自定义配置:
H 2      1. 审批人与提交人为同一人时
3      2. 审批人拒绝时
4      3. 审批人为空时
5 -->
6 <template>
7   <div class="panel-tab__content">
8     <el-divider content-position="left">审批人拒绝时</el-divider>
9     <el-form-item prop="rejectHandlerType">
10       <el-radio-group
11         v-model="rejectHandlerType"
12         :disabled="returnTaskList.length === 0"
13         @change="updateRejectHandlerType"
14       >
15         <div class="flex-col">
16           <div v-for="(item, index) in REJECT_HANDLER_TYPES" :key="index">
17             <el-radio :key="item.value" :value="item.value" :label="item.label" />
18           </div>
19         </div>
20       </el-radio-group>
21     </el-form-item>
22     <el-form-item
23       v-if="rejectHandlerType == RejectHandlerType.RETURN_USER_TASK"
24       label="驳回节点"
25       prop="returnNodeId"
26     >
27       <el-select v-model="returnNodeId" clearable style="width: 100%" @change="updateReturnNodeId">
28         <el-option
29           v-for="item in returnTaskList"
30           :key="item.id"
31           :label="item.name"
32           :value="item.id"
33         />
34       </el-select>
35     </el-form-item>
36
37     <el-divider content-position="left">审批人为空时</el-divider>
38     <el-form-item prop="assignEmptyHandlerType">
39       <el-radio-group v-model="assignEmptyHandlerType" @change="updateAssignEmptyHandlerType">
40         <div class="flex-col">
41           <div v-for="(item, index) in ASSIGN_EMPTY_HANDLER_TYPES" :key="index">
42             <el-radio :key="item.value" :value="item.value" :label="item.label" />
43           </div>
44         </div>
45       </el-radio-group>
46     </el-form-item>
47     <el-form-item
48       v-if="assignEmptyHandlerType == AssignEmptyHandlerType.ASSIGN_USER"
49       label="指定用户"
50       prop="assignEmptyHandlerUserIds"
51       span="24"
52     >
53       <el-select
54         v-model="assignEmptyUserIds"
55         clearable
56         multiple
57         style="width: 100%"
58         @change="updateAssignEmptyUserIds"
59       >
60         <el-option
61           v-for="item in userOptions"
62           :key="item.id"
63           :label="item.nickname"
64           :value="item.id"
65         />
66       </el-select>
67     </el-form-item>
68
69     <el-divider content-position="left">审批人与提交人为同一人时</el-divider>
70     <el-radio-group v-model="assignStartUserHandlerType" @change="updateAssignStartUserHandlerType">
71       <div class="flex-col">
72         <div v-for="(item, index) in ASSIGN_START_USER_HANDLER_TYPES" :key="index">
73           <el-radio :key="item.value" :value="item.value" :label="item.label" />
74         </div>
75       </div>
76     </el-radio-group>
77   </div>
78 </template>
79
80 <script lang="ts" setup>
81 import {
82   ASSIGN_START_USER_HANDLER_TYPES,
83   RejectHandlerType,
84   REJECT_HANDLER_TYPES,
85   ASSIGN_EMPTY_HANDLER_TYPES,
86   AssignEmptyHandlerType
87 } from '@/components/SimpleProcessDesignerV2/src/consts'
88 import * as UserApi from '@/api/system/user'
89
90 defineOptions({ name: 'ElementCustomConfig' })
91 const props = defineProps({
92   id: String,
93   type: String
94 })
95 const prefix = inject('prefix')
96
97 // 审批人与提交人为同一人时
98 const assignStartUserHandlerTypeEl = ref()
99 const assignStartUserHandlerType = ref()
100
101 // 审批人拒绝时
102 const rejectHandlerTypeEl = ref()
103 const rejectHandlerType = ref()
104 const returnNodeIdEl = ref()
105 const returnNodeId = ref()
106 const returnTaskList = ref([])
107
108 // 审批人为空时
109 const assignEmptyHandlerTypeEl = ref()
110 const assignEmptyHandlerType = ref()
111 const assignEmptyUserIdsEl = ref()
112 const assignEmptyUserIds = ref()
113
114 const elExtensionElements = ref()
115 const otherExtensions = ref()
116 const bpmnElement = ref()
117 const bpmnInstances = () => (window as any)?.bpmnInstances
118
119 const resetCustomConfigList = () => {
120   bpmnElement.value = bpmnInstances().bpmnElement
121
122   // 获取可回退的列表
123   returnTaskList.value = findAllPredecessorsExcludingStart(
124     bpmnElement.value.id,
125     bpmnInstances().modeler
126   )
127
128   // 获取元素扩展属性 或者 创建扩展属性
129   elExtensionElements.value =
130     bpmnElement.value.businessObject?.extensionElements ??
131     bpmnInstances().moddle.create('bpmn:ExtensionElements', { values: [] })
132
133   // 审批人与提交人为同一人时
134   assignStartUserHandlerTypeEl.value =
135     elExtensionElements.value.values?.filter(
136       (ex) => ex.$type === `${prefix}:AssignStartUserHandlerType`
137     )?.[0] || bpmnInstances().moddle.create(`${prefix}:AssignStartUserHandlerType`, { value: 1 })
138   assignStartUserHandlerType.value = assignStartUserHandlerTypeEl.value.value
139
140   // 审批人拒绝时
141   rejectHandlerTypeEl.value =
142     elExtensionElements.value.values?.filter(
143       (ex) => ex.$type === `${prefix}:RejectHandlerType`
144     )?.[0] || bpmnInstances().moddle.create(`${prefix}:RejectHandlerType`, { value: 1 })
145   rejectHandlerType.value = rejectHandlerTypeEl.value.value
146   returnNodeIdEl.value =
147     elExtensionElements.value.values?.filter(
148       (ex) => ex.$type === `${prefix}:RejectReturnTaskId`
149     )?.[0] || bpmnInstances().moddle.create(`${prefix}:RejectReturnTaskId`, { value: '' })
150   returnNodeId.value = returnNodeIdEl.value.value
151
152   // 审批人为空时
153   assignEmptyHandlerTypeEl.value =
154     elExtensionElements.value.values?.filter(
155       (ex) => ex.$type === `${prefix}:AssignEmptyHandlerType`
156     )?.[0] || bpmnInstances().moddle.create(`${prefix}:AssignEmptyHandlerType`, { value: 1 })
157   assignEmptyHandlerType.value = assignEmptyHandlerTypeEl.value.value
158   assignEmptyUserIdsEl.value =
159     elExtensionElements.value.values?.filter(
160       (ex) => ex.$type === `${prefix}:AssignEmptyUserIds`
161     )?.[0] || bpmnInstances().moddle.create(`${prefix}:AssignEmptyUserIds`, { value: '' })
162   assignEmptyUserIds.value = assignEmptyUserIdsEl.value.value.split(',').map((item) => {
163     // 如果数字超出了最大安全整数范围,则将其作为字符串处理
164     let num = Number(item)
165     return num > Number.MAX_SAFE_INTEGER || num < -Number.MAX_SAFE_INTEGER ? item : num
166   })
167
168   // 保留剩余扩展元素,便于后面更新该元素对应属性
169   otherExtensions.value =
170     elExtensionElements.value.values?.filter(
171       (ex) =>
172         ex.$type !== `${prefix}:AssignStartUserHandlerType` &&
173         ex.$type !== `${prefix}:RejectHandlerType` &&
174         ex.$type !== `${prefix}:RejectReturnTaskId` &&
175         ex.$type !== `${prefix}:AssignEmptyHandlerType` &&
176         ex.$type !== `${prefix}:AssignEmptyUserIds`
177     ) ?? []
178
179   // 更新元素扩展属性,避免后续报错
180   updateElementExtensions()
181 }
182
183 const updateAssignStartUserHandlerType = () => {
184   assignStartUserHandlerTypeEl.value.value = assignStartUserHandlerType.value
185
186   updateElementExtensions()
187 }
188
189 const updateRejectHandlerType = () => {
190   rejectHandlerTypeEl.value.value = rejectHandlerType.value
191
192   returnNodeId.value = returnTaskList.value[0].id
193   returnNodeIdEl.value.value = returnNodeId.value
194
195   updateElementExtensions()
196 }
197
198 const updateReturnNodeId = () => {
199   returnNodeIdEl.value.value = returnNodeId.value
200
201   updateElementExtensions()
202 }
203
204 const updateAssignEmptyHandlerType = () => {
205   assignEmptyHandlerTypeEl.value.value = assignEmptyHandlerType.value
206
207   updateElementExtensions()
208 }
209
210 const updateAssignEmptyUserIds = () => {
211   assignEmptyUserIdsEl.value.value = assignEmptyUserIds.value.toString()
212
213   updateElementExtensions()
214 }
215
216 const updateElementExtensions = () => {
217   const extensions = bpmnInstances().moddle.create('bpmn:ExtensionElements', {
218     values: [
219       ...otherExtensions.value,
220       assignStartUserHandlerTypeEl.value,
221       rejectHandlerTypeEl.value,
222       returnNodeIdEl.value,
223       assignEmptyHandlerTypeEl.value,
224       assignEmptyUserIdsEl.value
225     ]
226   })
227   bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
228     extensionElements: extensions
229   })
230 }
231
232 watch(
233   () => props.id,
234   (val) => {
235     val &&
236       val.length &&
237       nextTick(() => {
238         resetCustomConfigList()
239       })
240   },
241   { immediate: true }
242 )
243
244 function findAllPredecessorsExcludingStart(elementId, modeler) {
245   const elementRegistry = modeler.get('elementRegistry')
246   const allConnections = elementRegistry.filter((element) => element.type === 'bpmn:SequenceFlow')
247   const predecessors = new Set() // 使用 Set 来避免重复节点
248
249   // 检查是否是开始事件节点
250   function isStartEvent(element) {
251     return element.type === 'bpmn:StartEvent'
252   }
253
254   function findPredecessorsRecursively(element) {
255     // 获取与当前节点相连的所有连接
256     const incomingConnections = allConnections.filter((connection) => connection.target === element)
257
258     incomingConnections.forEach((connection) => {
259       const source = connection.source // 获取前置节点
260
261       // 只添加不是开始事件的前置节点
262       if (!isStartEvent(source)) {
263         predecessors.add(source.businessObject)
264         // 递归查找前置节点
265         findPredecessorsRecursively(source)
266       }
267     })
268   }
269
270   const targetElement = elementRegistry.get(elementId)
271   if (targetElement) {
272     findPredecessorsRecursively(targetElement)
273   }
274
275   return Array.from(predecessors) // 返回前置节点数组
276 }
277
278 const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
279 onMounted(async () => {
280   // 获得用户列表
281   userOptions.value = await UserApi.getSimpleUserList()
282 })
283 </script>