dengzedong
5 天以前 f9b459a3fefd5fab0ee8e19268adb9d9eadab2a7
提交 | 用户 | 时间
3e359e 1 <template>
H 2   <div
3     class="h-50px bottom-10 text-14px flex items-center color-#32373c dark:color-#fff font-bold btn-container"
4   >
5     <!-- 【通过】按钮 -->
6     <el-popover
7       :visible="popOverVisible.approve"
8       placement="top-end"
9       :width="420"
10       trigger="click"
11       v-if="runningTask && isHandleTaskStatus() && isShowButton(OperationButtonType.APPROVE)"
12     >
13       <template #reference>
14         <el-button plain type="success" @click="openPopover('approve')">
15           <Icon icon="ep:select" />&nbsp; {{ getButtonDisplayName(OperationButtonType.APPROVE) }}
16         </el-button>
17       </template>
18       <!-- 审批表单 -->
19       <div class="flex flex-col flex-1 pt-20px px-20px" v-loading="formLoading">
20         <el-form
21           label-position="top"
22           class="mb-auto"
23           ref="formRef"
24           :model="genericForm"
25           :rules="genericRule"
26           label-width="100px"
27         >
28           <el-card v-if="runningTask?.formId > 0" class="mb-15px !-mt-10px">
29             <template #header>
30               <span class="el-icon-picture-outline"> 填写表单【{{ runningTask?.formName }}】 </span>
31             </template>
32             <form-create
33               v-model="approveForm.value"
34               v-model:api="approveFormFApi"
35               :option="approveForm.option"
36               :rule="approveForm.rule"
37             />
38           </el-card>
39           <el-form-item label="审批意见" prop="reason">
40             <el-input
41               v-model="genericForm.reason"
42               placeholder="请输入审批意见"
43               type="textarea"
44               :rows="4"
45             />
46           </el-form-item>
47           <el-form-item>
48             <el-button :disabled="formLoading" type="success" @click="handleAudit(true)">
49               {{ getButtonDisplayName(OperationButtonType.APPROVE) }}
50             </el-button>
51             <el-button @click="popOverVisible.approve = false"> 取消 </el-button>
52           </el-form-item>
53         </el-form>
54       </div>
55     </el-popover>
56
57     <!-- 【拒绝】按钮 -->
58     <el-popover
59       :visible="popOverVisible.reject"
60       placement="top-end"
61       :width="420"
62       trigger="click"
63       v-if="runningTask && isHandleTaskStatus() && isShowButton(OperationButtonType.REJECT)"
64     >
65       <template #reference>
66         <el-button class="mr-20px" plain type="danger" @click="openPopover('reject')">
67           <Icon icon="ep:close" />&nbsp; {{ getButtonDisplayName(OperationButtonType.REJECT) }}
68         </el-button>
69       </template>
70       <!-- 审批表单 -->
71       <div class="flex flex-col flex-1 pt-20px px-20px" v-loading="formLoading">
72         <el-form
73           label-position="top"
74           class="mb-auto"
75           ref="formRef"
76           :model="genericForm"
77           :rules="genericRule"
78           label-width="100px"
79         >
80           <el-card v-if="runningTask?.formId > 0" class="mb-15px !-mt-10px">
81             <template #header>
82               <span class="el-icon-picture-outline"> 填写表单【{{ runningTask?.formName }}】 </span>
83             </template>
84             <form-create
85               v-model="approveForm.value"
86               v-model:api="approveFormFApi"
87               :option="approveForm.option"
88               :rule="approveForm.rule"
89             />
90           </el-card>
91           <el-form-item label="审批意见" prop="reason">
92             <el-input
93               v-model="genericForm.reason"
94               placeholder="请输入审批意见"
95               type="textarea"
96               :rows="4"
97             />
98           </el-form-item>
99           <el-form-item>
100             <el-button :disabled="formLoading" type="danger" @click="handleAudit(false)">
101               {{ getButtonDisplayName(OperationButtonType.REJECT) }}
102             </el-button>
103             <el-button @click="popOverVisible.reject = false"> 取消 </el-button>
104           </el-form-item>
105         </el-form>
106       </div>
107     </el-popover>
108
109     <!-- 【抄送】按钮 -->
110     <el-popover
111       :visible="popOverVisible.copy"
112       placement="top-start"
113       :width="420"
114       trigger="click"
115       v-if="runningTask && isHandleTaskStatus() && isShowButton(OperationButtonType.COPY)"
116     >
117       <template #reference>
118         <div @click="openPopover('copy')" class="hover-bg-gray-100 rounded-xl p-6px">
119           <Icon :size="14" icon="svg-icon:send" />&nbsp;
120           {{ getButtonDisplayName(OperationButtonType.COPY) }}
121         </div>
122       </template>
123       <div class="flex flex-col flex-1 pt-20px px-20px" v-loading="formLoading">
124         <el-form
125           label-position="top"
126           class="mb-auto"
127           ref="formRef"
128           :model="genericForm"
129           :rules="genericRule"
130           label-width="100px"
131         >
132           <el-form-item label="抄送人" prop="copyUserIds">
133             <el-select
134               v-model="genericForm.copyUserIds"
135               clearable
136               style="width: 100%"
137               multiple
138               placeholder="请选择抄送人"
139             >
140               <el-option
141                 v-for="item in userOptions"
142                 :key="item.id"
143                 :label="item.nickname"
144                 :value="item.id"
145               />
146             </el-select>
147           </el-form-item>
148           <el-form-item label="抄送意见" prop="copyReason">
149             <el-input
150               v-model="genericForm.copyReason"
151               clearable
152               placeholder="请输入抄送意见"
153               type="textarea"
154               :rows="3"
155             />
156           </el-form-item>
157           <el-form-item>
158             <el-button :disabled="formLoading" type="primary" @click="handleCopy">
159               {{ getButtonDisplayName(OperationButtonType.COPY) }}
160             </el-button>
161             <el-button @click="popOverVisible.copy = false"> 取消 </el-button>
162           </el-form-item>
163         </el-form>
164       </div>
165     </el-popover>
166
167     <!-- 【转交】按钮 -->
168     <el-popover
169       :visible="popOverVisible.transfer"
170       placement="top-start"
171       :width="420"
172       trigger="click"
173       v-if="runningTask && isHandleTaskStatus() && isShowButton(OperationButtonType.TRANSFER)"
174     >
175       <template #reference>
176         <div @click="openPopover('transfer')" class="hover-bg-gray-100 rounded-xl p-6px">
177           <Icon :size="14" icon="fa:share-square-o" />&nbsp;
178           {{ getButtonDisplayName(OperationButtonType.TRANSFER) }}
179         </div>
180       </template>
181       <div class="flex flex-col flex-1 pt-20px px-20px" v-loading="formLoading">
182         <el-form
183           label-position="top"
184           class="mb-auto"
185           ref="formRef"
186           :model="genericForm"
187           :rules="genericRule"
188           label-width="100px"
189         >
190           <el-form-item label="新审批人" prop="assigneeUserId">
191             <el-select v-model="genericForm.assigneeUserId" clearable style="width: 100%">
192               <el-option
193                 v-for="item in userOptions"
194                 :key="item.id"
195                 :label="item.nickname"
196                 :value="item.id"
197               />
198             </el-select>
199           </el-form-item>
200           <el-form-item label="审批意见" prop="reason">
201             <el-input
202               v-model="genericForm.reason"
203               clearable
204               placeholder="请输入审批意见"
205               type="textarea"
206               :rows="3"
207             />
208           </el-form-item>
209           <el-form-item>
210             <el-button :disabled="formLoading" type="primary" @click="handleTransfer()">
211               {{ getButtonDisplayName(OperationButtonType.TRANSFER) }}
212             </el-button>
213             <el-button @click="popOverVisible.transfer = false"> 取消 </el-button>
214           </el-form-item>
215         </el-form>
216       </div>
217     </el-popover>
218
219     <!-- 【委派】按钮 -->
220     <el-popover
221       :visible="popOverVisible.delegate"
222       placement="top-start"
223       :width="420"
224       trigger="click"
225       v-if="runningTask && isHandleTaskStatus() && isShowButton(OperationButtonType.DELEGATE)"
226     >
227       <template #reference>
228         <div @click="openPopover('delegate')" class="hover-bg-gray-100 rounded-xl p-6px">
229           <Icon :size="14" icon="ep:position" />&nbsp;
230           {{ getButtonDisplayName(OperationButtonType.DELEGATE) }}
231         </div>
232       </template>
233       <div class="flex flex-col flex-1 pt-20px px-20px" v-loading="formLoading">
234         <el-form
235           label-position="top"
236           class="mb-auto"
237           ref="formRef"
238           :model="genericForm"
239           :rules="genericRule"
240           label-width="100px"
241         >
242           <el-form-item label="接收人" prop="delegateUserId">
243             <el-select v-model="genericForm.delegateUserId" clearable style="width: 100%">
244               <el-option
245                 v-for="item in userOptions"
246                 :key="item.id"
247                 :label="item.nickname"
248                 :value="item.id"
249               />
250             </el-select>
251           </el-form-item>
252           <el-form-item label="审批意见" prop="reason">
253             <el-input
254               v-model="genericForm.reason"
255               clearable
256               placeholder="请输入审批意见"
257               type="textarea"
258               :rows="3"
259             />
260           </el-form-item>
261           <el-form-item>
262             <el-button :disabled="formLoading" type="primary" @click="handleDelegate()">
263               {{ getButtonDisplayName(OperationButtonType.DELEGATE) }}
264             </el-button>
265             <el-button @click="popOverVisible.delegate = false"> 取消 </el-button>
266           </el-form-item>
267         </el-form>
268       </div>
269     </el-popover>
270
271     <!-- 【加签】按钮 当前任务审批人为A,向前加签选了一个C,则需要C先审批,然后再是A审批,向后加签B,A审批完,需要B再审批完,才算完成这个任务节点 -->
272     <el-popover
273       :visible="popOverVisible.addSign"
274       placement="top-start"
275       :width="420"
276       trigger="click"
277       v-if="runningTask && isHandleTaskStatus() && isShowButton(OperationButtonType.ADD_SIGN)"
278     >
279       <template #reference>
280         <div @click="openPopover('addSign')" class="hover-bg-gray-100 rounded-xl p-6px">
281           <Icon :size="14" icon="ep:plus" />&nbsp;
282           {{ getButtonDisplayName(OperationButtonType.ADD_SIGN) }}
283         </div>
284       </template>
285       <div class="flex flex-col flex-1 pt-20px px-20px" v-loading="formLoading">
286         <el-form
287           label-position="top"
288           class="mb-auto"
289           ref="formRef"
290           :model="genericForm"
291           :rules="genericRule"
292           label-width="100px"
293         >
294           <el-form-item label="加签处理人" prop="addSignUserIds">
295             <el-select v-model="genericForm.addSignUserIds" multiple clearable style="width: 100%">
296               <el-option
297                 v-for="item in userOptions"
298                 :key="item.id"
299                 :label="item.nickname"
300                 :value="item.id"
301               />
302             </el-select>
303           </el-form-item>
304           <el-form-item label="审批意见" prop="reason">
305             <el-input
306               v-model="genericForm.reason"
307               clearable
308               placeholder="请输入审批意见"
309               type="textarea"
310               :rows="3"
311             />
312           </el-form-item>
313           <el-form-item>
314             <el-button :disabled="formLoading" type="primary" @click="handlerAddSign('before')">
315               向前{{ getButtonDisplayName(OperationButtonType.ADD_SIGN) }}
316             </el-button>
317             <el-button :disabled="formLoading" type="primary" @click="handlerAddSign('after')">
318               向后{{ getButtonDisplayName(OperationButtonType.ADD_SIGN) }}
319             </el-button>
320             <el-button @click="popOverVisible.addSign = false"> 取消 </el-button>
321           </el-form-item>
322         </el-form>
323       </div>
324     </el-popover>
325
326     <!-- 【减签】按钮 -->
327     <el-popover
328       :visible="popOverVisible.deleteSign"
329       placement="top-start"
330       :width="420"
331       trigger="click"
332       v-if="runningTask?.children.length > 0"
333     >
334       <template #reference>
335         <div @click="openPopover('deleteSign')" class="hover-bg-gray-100 rounded-xl p-6px">
336           <Icon :size="14" icon="ep:semi-select" />&nbsp; 减签
337         </div>
338       </template>
339       <div class="flex flex-col flex-1 pt-20px px-20px" v-loading="formLoading">
340         <el-form
341           label-position="top"
342           class="mb-auto"
343           ref="formRef"
344           :model="genericForm"
345           :rules="genericRule"
346           label-width="100px"
347         >
348           <el-form-item label="减签人员" prop="deleteSignTaskId">
349             <el-select v-model="genericForm.deleteSignTaskId" clearable style="width: 100%">
350               <el-option
351                 v-for="item in runningTask.children"
352                 :key="item.id"
353                 :label="getDeleteSignUserLabel(item)"
354                 :value="item.id"
355               />
356             </el-select>
357           </el-form-item>
358           <el-form-item label="审批意见" prop="reason">
359             <el-input
360               v-model="genericForm.reason"
361               clearable
362               placeholder="请输入审批意见"
363               type="textarea"
364               :rows="3"
365             />
366           </el-form-item>
367           <el-form-item>
368             <el-button :disabled="formLoading" type="primary" @click="handlerDeleteSign()">
369               减签
370             </el-button>
371             <el-button @click="popOverVisible.deleteSign = false"> 取消 </el-button>
372           </el-form-item>
373         </el-form>
374       </div>
375     </el-popover>
376
377     <!-- 【退回】按钮 -->
378     <el-popover
379       :visible="popOverVisible.return"
380       placement="top-start"
381       :width="420"
382       trigger="click"
383       v-if="runningTask && isHandleTaskStatus() && isShowButton(OperationButtonType.RETURN)"
384     >
385       <template #reference>
386         <div @click="openReturnPopover" class="hover-bg-gray-100 rounded-xl p-6px">
387           <Icon :size="14" icon="ep:back" />&nbsp;
388           {{ getButtonDisplayName(OperationButtonType.RETURN) }}
389         </div>
390       </template>
391       <div class="flex flex-col flex-1 pt-20px px-20px" v-loading="formLoading">
392         <el-form
393           label-position="top"
394           class="mb-auto"
395           ref="formRef"
396           :model="genericForm"
397           :rules="genericRule"
398           label-width="100px"
399         >
400           <el-form-item label="退回节点" prop="targetTaskDefinitionKey">
401             <el-select v-model="genericForm.targetTaskDefinitionKey" clearable style="width: 100%">
402               <el-option
403                 v-for="item in returnList"
404                 :key="item.taskDefinitionKey"
405                 :label="item.name"
406                 :value="item.taskDefinitionKey"
407               />
408             </el-select>
409           </el-form-item>
410           <el-form-item label="退回理由" prop="returnReason">
411             <el-input
412               v-model="genericForm.returnReason"
413               clearable
414               placeholder="请输入退回理由"
415               type="textarea"
416               :rows="3"
417             />
418           </el-form-item>
419           <el-form-item>
420             <el-button :disabled="formLoading" type="primary" @click="handleReturn()">
421               {{ getButtonDisplayName(OperationButtonType.RETURN) }}
422             </el-button>
423             <el-button @click="popOverVisible.return = false"> 取消 </el-button>
424           </el-form-item>
425         </el-form>
426       </div>
427     </el-popover>
428
429     <!--【取消】按钮 这个对应发起人的取消, 只有发起人可以取消 -->
430     <el-popover
431       :visible="popOverVisible.cancel"
432       placement="top-start"
433       :width="420"
434       trigger="click"
435       v-if="
436         userId === processInstance?.startUser?.id && !isEndProcessStatus(processInstance?.status)
437       "
438     >
439       <template #reference>
440         <div @click="openPopover('cancel')" class="hover-bg-gray-100 rounded-xl p-6px">
441           <Icon :size="14" icon="fa:mail-reply" />&nbsp; 取消
442         </div>
443       </template>
444       <div class="flex flex-col flex-1 pt-20px px-20px" v-loading="formLoading">
445         <el-form
446           label-position="top"
447           class="mb-auto"
448           ref="formRef"
449           :model="genericForm"
450           :rules="genericRule"
451           label-width="100px"
452         >
453           <el-form-item label="取消理由" prop="cancelReason">
454             <span class="text-#878c93 text-12px">&nbsp; 取消后,该审批流程将自动结束</span>
455             <el-input
456               v-model="genericForm.cancelReason"
457               clearable
458               placeholder="请输入取消理由"
459               type="textarea"
460               :rows="3"
461             />
462           </el-form-item>
463           <el-form-item>
464             <el-button :disabled="formLoading" type="primary" @click="handleCancel()">
465               取消
466             </el-button>
467             <el-button @click="popOverVisible.cancel = false"> 取消 </el-button>
468           </el-form-item>
469         </el-form>
470       </div>
471     </el-popover>
472     <!-- 【再次提交】 按钮-->
473     <div
474       @click="handleReCreate()"
475       class="hover-bg-gray-100 rounded-xl p-6px"
476       v-if="
477         userId === processInstance?.startUser?.id &&
478         isEndProcessStatus(processInstance?.status) &&
479         processDefinition?.formType === 10
480       "
481     >
482       <Icon :size="14" icon="ep:refresh" />&nbsp; 再次提交
483     </div>
484   </div>
485 </template>
486 <script lang="ts" setup>
487 import { useUserStoreWithOut } from '@/store/modules/user'
488 import { setConfAndFields2 } from '@/utils/formCreate'
489 import * as TaskApi from '@/api/bpm/task'
490 import * as ProcessInstanceApi from '@/api/bpm/processInstance'
491 import { propTypes } from '@/utils/propTypes'
492 import {
493   OperationButtonType,
494   OPERATION_BUTTON_NAME
495 } from '@/components/SimpleProcessDesignerV2/src/consts'
496 import { BpmProcessInstanceStatus } from '@/utils/constants'
497
498 defineOptions({ name: 'ProcessInstanceBtnContainer' })
499
500 const router = useRouter() // 路由
501 const message = useMessage() // 消息弹窗
502 const { proxy } = getCurrentInstance() as any
503
504 const userId = useUserStoreWithOut().getUser.id // 当前登录的编号
505 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
506 const props = defineProps({
507   processInstance: propTypes.object, // 流程实例信息
508   processDefinition: propTypes.object, // 流程定义信息
509   userOptions: propTypes.any
510 })
511
512 const formLoading = ref(false) // 表单加载中
513 const popOverVisible = ref({
514   approve: false,
515   reject: false,
516   transfer: false,
517   delegate: false,
518   addSign: false,
519   return: false,
520   copy: false,
521   cancel: false,
522   deleteSign: false
523 }) // 气泡卡是否展示
524 const returnList = ref([] as any) // 退回节点
525
526 // ========== 审批信息 ==========
527 const runningTask = ref<any>() // 运行中的任务
528 const genericForm = ref<any>({}) // 通用表单
529 const approveForm = ref<any>({}) // 审批通过时,额外的补充信息
530 const approveFormFApi = ref<any>({}) // approveForms 的 fAPi
531 const formRef = ref()
532 const genericRule = reactive({
533   reason: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
534   returnReason: [{ required: true, message: '退回理由不能为空', trigger: 'blur' }],
535   cancelReason: [{ required: true, message: '取消理由不能为空', trigger: 'blur' }],
536   copyUserIds: [{ required: true, message: '抄送人不能为空', trigger: 'change' }],
537   assigneeUserId: [{ required: true, message: '新审批人不能为空', trigger: 'change' }],
538   delegateUserId: [{ required: true, message: '接收人不能为空', trigger: 'change' }],
539   addSignUserIds: [{ required: true, message: '加签处理人不能为空', trigger: 'change' }],
540   deleteSignTaskId: [{ required: true, message: '减签人员不能为空', trigger: 'change' }],
541   targetTaskDefinitionKey: [{ required: true, message: '退回节点不能为空', trigger: 'change' }]
542 }) // 表单校验规则
543
544 /** 监听 approveFormFApis,实现它对应的 form-create 初始化后,隐藏掉对应的表单提交按钮 */
545 watch(
546   () => approveFormFApi.value,
547   (val) => {
548     val?.btn?.show(false)
549     val?.resetBtn?.show(false)
550   },
551   {
552     deep: true
553   }
554 )
555
556 /** 弹出退回气泡卡 */
557 const openReturnPopover = async () => {
558   returnList.value = await TaskApi.getTaskListByReturn(runningTask.value.id)
559   if (returnList.value.length === 0) {
560     message.warning('当前没有可退回的节点')
561     return
562   }
563   await openPopover('return')
564 }
565
566 /** 弹出气泡卡 */
567 const openPopover = async (type: string) => {
568   Object.keys(popOverVisible.value).forEach((item) => {
569     popOverVisible.value[item] = item === type
570   })
571   await nextTick()
572   formRef.value.resetFields()
573 }
574
575 /** 处理审批通过和不通过的操作 */
576 const handleAudit = async (pass: boolean) => {
577   formLoading.value = true
578   try {
579     const genericFormRef = proxy.$refs['formRef']
580     // 1.2 校验表单
581     const elForm = unref(genericFormRef)
582     if (!elForm) return
583     const valid = await elForm.validate()
584     if (!valid) return
585
586     // 2.1 提交审批
587     const data = {
588       id: runningTask.value.id,
589       reason: genericForm.value.reason
590     }
591     if (pass) {
592       // 审批通过,并且有额外的 approveForm 表单,需要校验 + 拼接到 data 表单里提交
593       const formCreateApi = approveFormFApi.value
594       if (Object.keys(formCreateApi)?.length > 0) {
595         await formCreateApi.validate()
596         // @ts-ignore
597         data.variables = approveForm.value.value
598       }
599       await TaskApi.approveTask(data)
600       popOverVisible.value.approve = false
601       message.success('审批通过成功')
602     } else {
603       await TaskApi.rejectTask(data)
604       popOverVisible.value.reject = false
605       message.success('审批不通过成功')
606     }
607     // 2.2 加载最新数据
608     reload()
609   } finally {
610     formLoading.value = false
611   }
612 }
613
614 /** 处理抄送 */
615 const handleCopy = async () => {
616   formLoading.value = true
617   try {
618     const copyFormRef = proxy.$refs['formRef']
619     // 1. 校验表单
620     const elForm = unref(copyFormRef)
621     if (!elForm) return
622     const valid = await elForm.validate()
623     if (!valid) return
624     // 2. 提交抄送
625     const data = {
626       id: runningTask.value.id,
627       reason: genericForm.value.copyReason,
628       copyUserIds: genericForm.value.copyUserIds
629     }
630     await TaskApi.copyTask(data)
631     popOverVisible.value.copy = false
632     message.success('操作成功')
633   } finally {
634     formLoading.value = false
635   }
636 }
637
638 /** 处理转交 */
639 const handleTransfer = async () => {
640   formLoading.value = true
641   try {
642     const transferFormRef = proxy.$refs['formRef']
643     // 1.1 校验表单
644     const elForm = unref(transferFormRef)
645     if (!elForm) return
646     const valid = await elForm.validate()
647     if (!valid) return
648     // 1.2 提交转交
649     const data = {
650       id: runningTask.value.id,
651       reason: genericForm.value.reason,
652       assigneeUserId: genericForm.value.assigneeUserId
653     }
654
655     await TaskApi.transferTask(data)
656     popOverVisible.value.transfer = false
657     message.success('操作成功')
658     // 2. 加载最新数据
659     reload()
660   } finally {
661     formLoading.value = false
662   }
663 }
664
665 /** 处理委派 */
666 const handleDelegate = async () => {
667   formLoading.value = true
668   try {
669     const deletegateFormRef = proxy.$refs['formRef']
670     // 1.1 校验表单
671     const elForm = unref(deletegateFormRef)
672     if (!elForm) return
673     const valid = await elForm.validate()
674     if (!valid) return
675     // 1.2 处理委派
676     const data = {
677       id: runningTask.value.id,
678       reason: genericForm.value.reason,
679       delegateUserId: genericForm.value.delegateUserId
680     }
681
682     await TaskApi.delegateTask(data)
683     popOverVisible.value.delegate = false
684     message.success('操作成功')
685     // 2. 加载最新数据
686     reload()
687   } finally {
688     formLoading.value = false
689   }
690 }
691
692 /** 处理加签 */
693 const handlerAddSign = async (type: string) => {
694   formLoading.value = true
695   try {
696     const transferFormRef = proxy.$refs['formRef']
697     // 1.1 校验表单
698     const elForm = unref(transferFormRef)
699     if (!elForm) return
700     const valid = await elForm.validate()
701     if (!valid) return
702     // 1.2 提交加签
703     const data = {
704       id: runningTask.value.id,
705       type,
706       reason: genericForm.value.reason,
707       userIds: genericForm.value.addSignUserIds
708     }
709     await TaskApi.signCreateTask(data)
710     message.success('操作成功')
711     popOverVisible.value.addSign = false
712     // 2 加载最新数据
713     reload()
714   } finally {
715     formLoading.value = false
716   }
717 }
718
719 /** 处理退回 */
720 const handleReturn = async () => {
721   formLoading.value = true
722   try {
723     const returnFormRef = proxy.$refs['formRef']
724     // 1.1 校验表单
725     const elForm = unref(returnFormRef)
726     if (!elForm) return
727     const valid = await elForm.validate()
728     if (!valid) return
729     // 1.2 提交退回
730     const data = {
731       id: runningTask.value.id,
732       reason: genericForm.value.returnReason,
733       targetTaskDefinitionKey: genericForm.value.targetTaskDefinitionKey
734     }
735
736     await TaskApi.returnTask(data)
737     popOverVisible.value.return = false
738     message.success('操作成功')
739     // 2 重新加载数据
740     reload()
741   } finally {
742     formLoading.value = false
743   }
744 }
745
746 /** 处理取消 */
747 const handleCancel = async () => {
748   formLoading.value = true
749   try {
750     const cancelFormRef = proxy.$refs['formRef']
751     // 1.1 校验表单
752     const elForm = unref(cancelFormRef)
753     if (!elForm) return
754     const valid = await elForm.validate()
755     if (!valid) return
756     // 1.2 提交取消
757     await ProcessInstanceApi.cancelProcessInstanceByStartUser(
758       props.processInstance.id,
759       genericForm.value.cancelReason
760     )
761     popOverVisible.value.return = false
762     message.success('操作成功')
763     // 2 重新加载数据
764     reload()
765   } finally {
766     formLoading.value = false
767   }
768 }
769
770 /** 处理再次提交 */
771 const handleReCreate = async () => {
772   // 跳转发起流程界面
773   await router.push({
774     name: 'BpmProcessInstanceCreate',
775     query: { processInstanceId: props.processInstance?.id }
776   })
777 }
778
779 /** 获取减签人员标签 */
780 const getDeleteSignUserLabel = (task: any): string => {
781   const deptName = task?.assigneeUser?.deptName || task?.ownerUser?.deptName
782   const nickname = task?.assigneeUser?.nickname || task?.ownerUser?.nickname
783   return `${nickname} ( 所属部门:${deptName} )`
784 }
785 /** 处理减签 */
786 const handlerDeleteSign = async () => {
787   formLoading.value = true
788   try {
789     const deleteFormRef = proxy.$refs['formRef']
790     // 1.1 校验表单
791     const elForm = unref(deleteFormRef)
792     if (!elForm) return
793     const valid = await elForm.validate()
794     if (!valid) return
795     // 1.2 提交减签
796     const data = {
797       id: genericForm.value.deleteSignTaskId,
798       reason: genericForm.value.reason
799     }
800     await TaskApi.signDeleteTask(data)
801     message.success('减签成功')
802     popOverVisible.value.deleteSign = false
803     // 2 加载最新数据
804     reload()
805   } finally {
806     formLoading.value = false
807   }
808 }
809 /** 重新加载数据 */
810 const reload = () => {
811   emit('success')
812 }
813
814 /** 任务是否为处理中状态 */
815 const isHandleTaskStatus = () => {
816   let canHandle = false
817   if (TaskApi.TaskStatusEnum.RUNNING === runningTask.value?.status) {
818     canHandle = true
819   }
820   return canHandle
821 }
822
823 /** 流程状态是否为结束状态 */
824 const isEndProcessStatus = (status: number) => {
825   let isEndStatus = false
826   if (
827     BpmProcessInstanceStatus.APPROVE === status ||
828     BpmProcessInstanceStatus.REJECT === status ||
829     BpmProcessInstanceStatus.CANCEL === status
830   ) {
831     isEndStatus = true
832   }
833   return isEndStatus
834 }
835
836 /** 是否显示按钮 */
837 const isShowButton = (btnType: OperationButtonType): boolean => {
838   let isShow = true
839   if (runningTask.value?.buttonsSetting && runningTask.value?.buttonsSetting[btnType]) {
840     isShow = runningTask.value.buttonsSetting[btnType].enable
841   }
842   return isShow
843 }
844
845 /** 获取按钮的显示名称 */
846 const getButtonDisplayName = (btnType: OperationButtonType) => {
847   let displayName = OPERATION_BUTTON_NAME.get(btnType)
848   if (runningTask.value?.buttonsSetting && runningTask.value?.buttonsSetting[btnType]) {
849     displayName = runningTask.value.buttonsSetting[btnType].displayName
850   }
851   return displayName
852 }
853
854 const loadTodoTask = (task: any) => {
855   genericForm.value = {}
856   approveForm.value = {}
857   approveFormFApi.value = {}
858   runningTask.value = task
859   // 处理 approve 表单.
860   if (task && task.formId && task.formConf) {
861     const tempApproveForm = {}
862     setConfAndFields2(tempApproveForm, task.formConf, task.formFields, task.formVariables)
863     approveForm.value = tempApproveForm
864   } else {
865     approveForm.value = {} // 占位,避免为空
866   }
867 }
868
869 defineExpose({ loadTodoTask })
870 </script>
871
872 <style lang="scss" scoped>
873 :deep(.el-affix--fixed) {
874   background-color: var(--el-bg-color);
875 }
876
877 .btn-container {
878   > div {
879     display: flex;
880     margin: 0 8px;
881     cursor: pointer;
882     align-items: center;
883
884     &:hover {
885       color: #6db5ff;
886     }
887   }
888 }
889 </style>