dengzedong
5 天以前 3357b5f0f0919f7a52cd32a6d6de0acb14e0daaf
提交 | 用户 | 时间
3e359e 1 <template>
H 2   <el-drawer
3     :append-to-body="true"
4     v-model="settingVisible"
5     :show-close="false"
6     :size="550"
7     :before-close="saveConfig"
8     class="justify-start"
9   >
10     <template #header>
11       <div class="config-header">
12         <input
13           v-if="showInput"
14           type="text"
15           class="config-editable-input"
16           @blur="blurEvent()"
17           v-mountedFocus
18           v-model="nodeName"
19           :placeholder="nodeName"
20         />
21         <div v-else class="node-name">
22           {{ nodeName }} <Icon class="ml-1" icon="ep:edit-pen" :size="16" @click="clickIcon()" />
23         </div>
24         <div class="divide-line"></div>
25       </div>
26     </template>
27     <div class="flex flex-items-center mb-3">
28       <span class="font-size-16px mr-3">审批类型 :</span>
29       <el-radio-group v-model="approveType">
30         <el-radio
31           v-for="(item, index) in APPROVE_TYPE"
32           :key="index"
33           :value="item.value"
34           :label="item.value"
35         >
36           {{ item.label }}
37         </el-radio>
38       </el-radio-group>
39     </div>
40     <el-tabs type="border-card" v-model="activeTabName" v-if="approveType === ApproveType.USER">
41       <el-tab-pane label="审批人" name="user">
42         <div>
43           <el-form ref="formRef" :model="configForm" label-position="top" :rules="formRules">
44             <el-form-item label="审批人设置" prop="candidateStrategy">
45               <el-radio-group
46                 v-model="configForm.candidateStrategy"
47                 @change="changeCandidateStrategy"
48               >
49                 <el-radio
50                   v-for="(dict, index) in CANDIDATE_STRATEGY"
51                   :key="index"
52                   :value="dict.value"
53                   :label="dict.value"
54                 >
55                   {{ dict.label }}
56                 </el-radio>
57               </el-radio-group>
58             </el-form-item>
59             <el-form-item
60               v-if="configForm.candidateStrategy == CandidateStrategy.ROLE"
61               label="指定角色"
62               prop="roleIds"
63             >
64               <el-select v-model="configForm.roleIds" clearable multiple style="width: 100%">
65                 <el-option
66                   v-for="item in roleOptions"
67                   :key="item.id"
68                   :label="item.name"
69                   :value="item.id"
70                 />
71               </el-select>
72             </el-form-item>
73             <el-form-item
74               v-if="
75                 configForm.candidateStrategy == CandidateStrategy.DEPT_MEMBER ||
76                 configForm.candidateStrategy == CandidateStrategy.DEPT_LEADER ||
77                 configForm.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER
78               "
79               label="指定部门"
80               prop="deptIds"
81               span="24"
82             >
83               <el-tree-select
84                 ref="treeRef"
85                 v-model="configForm.deptIds"
86                 :data="deptTreeOptions"
87                 :props="defaultProps"
88                 empty-text="加载中,请稍后"
89                 multiple
90                 node-key="id"
91                 :check-strictly="true"
92                 style="width: 100%"
93                 show-checkbox
94               />
95             </el-form-item>
96             <el-form-item
97               v-if="configForm.candidateStrategy == CandidateStrategy.POST"
98               label="指定岗位"
99               prop="postIds"
100               span="24"
101             >
102               <el-select v-model="configForm.postIds" clearable multiple style="width: 100%">
103                 <el-option
104                   v-for="item in postOptions"
105                   :key="item.id"
106                   :label="item.name"
107                   :value="item.id!"
108                 />
109               </el-select>
110             </el-form-item>
111             <el-form-item
112               v-if="configForm.candidateStrategy == CandidateStrategy.USER"
113               label="指定用户"
114               prop="userIds"
115               span="24"
116             >
117               <el-select v-model="configForm.userIds" clearable multiple style="width: 100%">
118                 <el-option
119                   v-for="item in userOptions"
120                   :key="item.id"
121                   :label="item.nickname"
122                   :value="item.id"
123                 />
124               </el-select>
125             </el-form-item>
126             <el-form-item
127               v-if="configForm.candidateStrategy === CandidateStrategy.USER_GROUP"
128               label="指定用户组"
129               prop="userGroups"
130             >
131               <el-select v-model="configForm.userGroups" clearable multiple style="width: 100%">
132                 <el-option
133                   v-for="item in userGroupOptions"
134                   :key="item.id"
135                   :label="item.name"
136                   :value="item.id"
137                 />
138               </el-select>
139             </el-form-item>
140             <el-form-item
141               v-if="configForm.candidateStrategy === CandidateStrategy.FORM_USER"
142               label="表单内用户字段"
143               prop="formUser"
144             >
145               <el-select v-model="configForm.formUser" clearable style="width: 100%">
146                 <el-option
147                   v-for="(item, idx) in userFieldOnFormOptions"
148                   :key="idx"
149                   :label="item.title"
150                   :value="item.field"
151                   :disabled ="!item.required"
152                 />
153               </el-select>
154             </el-form-item>
155             <el-form-item
156               v-if="configForm.candidateStrategy === CandidateStrategy.FORM_DEPT_LEADER"
157               label="表单内部门字段"
158               prop="formDept"
159             >
160               <el-select v-model="configForm.formDept" clearable style="width: 100%">
161                 <el-option
162                   v-for="(item, idx) in deptFieldOnFormOptions"
163                   :key="idx"
164                   :label="item.title"
165                   :value="item.field"
166                   :disabled ="!item.required"
167                 />
168               </el-select>
169             </el-form-item>
170             <el-form-item
171               v-if="
172                 configForm.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER ||
173                 configForm.candidateStrategy == CandidateStrategy.START_USER_DEPT_LEADER ||
174                 configForm.candidateStrategy ==
175                   CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER ||
176                 configForm.candidateStrategy == CandidateStrategy.FORM_DEPT_LEADER
177               "
178               :label="deptLevelLabel!"
179               prop="deptLevel"
180               span="24"
181             >
182               <el-select v-model="configForm.deptLevel" clearable>
183                 <el-option
184                   v-for="(item, index) in MULTI_LEVEL_DEPT"
185                   :key="index"
186                   :label="item.label"
187                   :value="item.value"
188                 />
189               </el-select>
190             </el-form-item>
191             <!-- TODO @jason:后续要支持选择已经存好的表达式 -->
192             <el-form-item
193               v-if="configForm.candidateStrategy === CandidateStrategy.EXPRESSION"
194               label="流程表达式"
195               prop="expression"
196             >
197               <el-input
198                 type="textarea"
199                 v-model="configForm.expression"
200                 clearable
201                 style="width: 100%"
202               />
203             </el-form-item>
204             <el-form-item label="多人审批方式" prop="approveMethod">
205               <el-radio-group v-model="configForm.approveMethod" @change="approveMethodChanged">
206                 <div class="flex-col">
207                   <div
208                     v-for="(item, index) in APPROVE_METHODS"
209                     :key="index"
210                     class="flex items-center"
211                   >
212                     <el-radio :value="item.value" :label="item.value">
213                       {{ item.label }}
214                     </el-radio>
215                     <el-form-item prop="approveRatio">
216                       <el-input-number
217                         v-model="configForm.approveRatio"
218                         :min="10"
219                         :max="100"
220                         :step="10"
221                         size="small"
222                         v-if="
223                           item.value === ApproveMethodType.APPROVE_BY_RATIO &&
224                           configForm.approveMethod === ApproveMethodType.APPROVE_BY_RATIO
225                         "
226                       />
227                     </el-form-item>
228                   </div>
229                 </div>
230               </el-radio-group>
231             </el-form-item>
232
233             <el-divider content-position="left">审批人拒绝时</el-divider>
234             <el-form-item prop="rejectHandlerType">
235               <el-radio-group v-model="configForm.rejectHandlerType">
236                 <div class="flex-col">
237                   <div v-for="(item, index) in REJECT_HANDLER_TYPES" :key="index">
238                     <el-radio :key="item.value" :value="item.value" :label="item.label" />
239                   </div>
240                 </div>
241               </el-radio-group>
242             </el-form-item>
243             <el-form-item
244               v-if="configForm.rejectHandlerType == RejectHandlerType.RETURN_USER_TASK"
245               label="驳回节点"
246               prop="returnNodeId"
247             >
248               <el-select v-model="configForm.returnNodeId" clearable style="width: 100%">
249                 <el-option
250                   v-for="item in returnTaskList"
251                   :key="item.id"
252                   :label="item.name"
253                   :value="item.id"
254                 />
255               </el-select>
256             </el-form-item>
257
258             <el-divider content-position="left">审批人超时未处理时</el-divider>
259             <el-form-item label="启用开关" prop="timeoutHandlerEnable">
260               <el-switch
261                 v-model="configForm.timeoutHandlerEnable"
262                 active-text="开启"
263                 inactive-text="关闭"
264                 @change="timeoutHandlerChange"
265               />
266             </el-form-item>
267             <el-form-item
268               label="执行动作"
269               prop="timeoutHandlerType"
270               v-if="configForm.timeoutHandlerEnable"
271             >
272               <el-radio-group
273                 v-model="configForm.timeoutHandlerType"
274                 @change="timeoutHandlerTypeChanged"
275               >
276                 <el-radio-button
277                   v-for="item in TIMEOUT_HANDLER_TYPES"
278                   :key="item.value"
279                   :value="item.value"
280                   :label="item.label"
281                 />
282               </el-radio-group>
283             </el-form-item>
284             <el-form-item label="超时时间设置" v-if="configForm.timeoutHandlerEnable">
285               <span class="mr-2">当超过</span>
286               <el-form-item prop="timeDuration">
287                 <el-input-number
288                   class="mr-2"
289                   :style="{ width: '100px' }"
290                   v-model="configForm.timeDuration"
291                   :min="1"
292                   controls-position="right"
293                 />
294               </el-form-item>
295               <el-select
296                 v-model="timeUnit"
297                 class="mr-2"
298                 :style="{ width: '100px' }"
299                 @change="timeUnitChange"
300               >
301                 <el-option
302                   v-for="item in TIME_UNIT_TYPES"
303                   :key="item.value"
304                   :label="item.label"
305                   :value="item.value"
306                 />
307               </el-select>
308               未处理
309             </el-form-item>
310             <el-form-item
311               label="最大提醒次数"
312               prop="maxRemindCount"
313               v-if="configForm.timeoutHandlerEnable && configForm.timeoutHandlerType === 1"
314             >
315               <el-input-number v-model="configForm.maxRemindCount" :min="1" :max="10" />
316             </el-form-item>
317
318             <el-divider content-position="left">审批人为空时</el-divider>
319             <el-form-item prop="assignEmptyHandlerType">
320               <el-radio-group v-model="configForm.assignEmptyHandlerType">
321                 <div class="flex-col">
322                   <div v-for="(item, index) in ASSIGN_EMPTY_HANDLER_TYPES" :key="index">
323                     <el-radio :key="item.value" :value="item.value" :label="item.label" />
324                   </div>
325                 </div>
326               </el-radio-group>
327             </el-form-item>
328             <el-form-item
329               v-if="configForm.assignEmptyHandlerType == AssignEmptyHandlerType.ASSIGN_USER"
330               label="指定用户"
331               prop="assignEmptyHandlerUserIds"
332               span="24"
333             >
334               <el-select
335                 v-model="configForm.assignEmptyHandlerUserIds"
336                 clearable
337                 multiple
338                 style="width: 100%"
339               >
340                 <el-option
341                   v-for="item in userOptions"
342                   :key="item.id"
343                   :label="item.nickname"
344                   :value="item.id"
345                 />
346               </el-select>
347             </el-form-item>
348
349             <el-divider content-position="left">审批人与提交人为同一人时</el-divider>
350             <el-form-item prop="assignStartUserHandlerType">
351               <el-radio-group v-model="configForm.assignStartUserHandlerType">
352                 <div class="flex-col">
353                   <div v-for="(item, index) in ASSIGN_START_USER_HANDLER_TYPES" :key="index">
354                     <el-radio :key="item.value" :value="item.value" :label="item.label" />
355                   </div>
356                 </div>
357               </el-radio-group>
358             </el-form-item>
359           </el-form>
360         </div>
361       </el-tab-pane>
362       <el-tab-pane label="操作按钮设置" name="buttons">
363         <div class="button-setting-pane">
364           <div class="button-setting-desc">操作按钮</div>
365           <div class="button-setting-title">
366             <div class="button-title-label">操作按钮</div>
367             <div class="pl-4 button-title-label">显示名称</div>
368             <div class="button-title-label">启用</div>
369           </div>
370           <div class="button-setting-item" v-for="(item, index) in buttonsSetting" :key="index">
371             <div class="button-setting-item-label"> {{ OPERATION_BUTTON_NAME.get(item.id) }} </div>
372             <div class="button-setting-item-label">
373               <input
374                 type="text"
375                 class="editable-title-input"
376                 @blur="btnDisplayNameBlurEvent(index)"
377                 v-mountedFocus
378                 v-model="item.displayName"
379                 :placeholder="item.displayName"
380                 v-if="btnDisplayNameEdit[index]"
381               />
382               <el-button v-else text @click="changeBtnDisplayName(index)"
383                 >{{ item.displayName }} &nbsp;<Icon icon="ep:edit"
384               /></el-button>
385             </div>
386             <div class="button-setting-item-label">
387               <el-switch v-model="item.enable" />
388             </div>
389           </div>
390         </div>
391       </el-tab-pane>
392       <el-tab-pane label="表单字段权限" name="fields" v-if="formType === 10">
393         <div class="field-setting-pane">
394           <div class="field-setting-desc">字段权限</div>
395           <div class="field-permit-title">
396             <div class="setting-title-label first-title"> 字段名称 </div>
397             <div class="other-titles">
398               <span class="setting-title-label">只读</span>
399               <span class="setting-title-label">可编辑</span>
400               <span class="setting-title-label">隐藏</span>
401             </div>
402           </div>
403           <div
404             class="field-setting-item"
405             v-for="(item, index) in fieldsPermissionConfig"
406             :key="index"
407           >
408             <div class="field-setting-item-label"> {{ item.title }} </div>
409             <el-radio-group class="field-setting-item-group" v-model="item.permission">
410               <div class="item-radio-wrap">
411                 <el-radio
412                   :value="FieldPermissionType.READ"
413                   size="large"
414                   :label="FieldPermissionType.READ"
415                   ><span></span
416                 ></el-radio>
417               </div>
418               <div class="item-radio-wrap">
419                 <el-radio
420                   :value="FieldPermissionType.WRITE"
421                   size="large"
422                   :label="FieldPermissionType.WRITE"
423                   ><span></span
424                 ></el-radio>
425               </div>
426               <div class="item-radio-wrap">
427                 <el-radio
428                   :value="FieldPermissionType.NONE"
429                   size="large"
430                   :label="FieldPermissionType.NONE"
431                   ><span></span
432                 ></el-radio>
433               </div>
434             </el-radio-group>
435           </div>
436         </div>
437       </el-tab-pane>
438     </el-tabs>
439     <template #footer>
440       <el-divider />
441       <div>
442         <el-button type="primary" @click="saveConfig">确 定</el-button>
443         <el-button @click="closeDrawer">取 消</el-button>
444       </div>
445     </template>
446   </el-drawer>
447 </template>
448
449 <script setup lang="ts">
450 import {
451   SimpleFlowNode,
452   APPROVE_TYPE,
453   ApproveType,
454   APPROVE_METHODS,
455   CandidateStrategy,
456   NodeType,
457   ApproveMethodType,
458   TimeUnitType,
459   RejectHandlerType,
460   TIMEOUT_HANDLER_TYPES,
461   TIME_UNIT_TYPES,
462   REJECT_HANDLER_TYPES,
463   DEFAULT_BUTTON_SETTING,
464   OPERATION_BUTTON_NAME,
465   ButtonSetting,
466   MULTI_LEVEL_DEPT,
467   CANDIDATE_STRATEGY,
468   ASSIGN_START_USER_HANDLER_TYPES,
469   TimeoutHandlerType,
470   ASSIGN_EMPTY_HANDLER_TYPES,
471   AssignEmptyHandlerType,
472   FieldPermissionType
473 } from '../consts'
474
475 import {
476   useWatchNode,
477   useNodeName,
478   useFormFieldsPermission,
479   useNodeForm,
480   UserTaskFormType,
481   useDrawer
482 } from '../node'
483 import { defaultProps } from '@/utils/tree'
484 import { cloneDeep } from 'lodash-es'
485 import { convertTimeUnit, getApproveTypeText } from '../utils'
486 defineOptions({
487   name: 'UserTaskNodeConfig'
488 })
489 const props = defineProps({
490   flowNode: {
491     type: Object as () => SimpleFlowNode,
492     required: true
493   }
494 })
495 const emits = defineEmits<{
496   'find:returnTaskNodes': [nodeList: SimpleFlowNode[]]
497 }>()
498 const deptLevelLabel = computed(() => {
499   let label = '部门负责人来源'
500   if (configForm.value.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER) {
501     label = label + '(指定部门向上)'
502   } else if (configForm.value.candidateStrategy == CandidateStrategy.FORM_DEPT_LEADER) {
503     label = label + '(表单内部门向上)'
504   } else {
505     label = label + '(发起人部门向上)'
506   }
507   return label
508 })
509 // 监控节点的变化
510 const currentNode = useWatchNode(props)
511 // 抽屉配置
512 const { settingVisible, closeDrawer, openDrawer } = useDrawer()
513 // 节点名称配置
514 const { nodeName, showInput, clickIcon, blurEvent } = useNodeName(NodeType.USER_TASK_NODE)
515 // 激活的 Tab 标签页
516 const activeTabName = ref('user')
517 // 表单字段权限设置
518 const { formType, fieldsPermissionConfig, formFieldOptions, getNodeConfigFormFields } =
519   useFormFieldsPermission(FieldPermissionType.READ)
520 // 表单内用户字段选项, 必须是必填和用户选择器
521 const userFieldOnFormOptions = computed(() => {
522   return formFieldOptions.filter((item) => item.type === 'UserSelect')
523 })
524 // 表单内部门字段选项, 必须是必填和部门选择器
525 const deptFieldOnFormOptions = computed(() => {
526   return formFieldOptions.filter((item) => item.type === 'DeptSelect')
527 })
528 // 操作按钮设置
529 const { buttonsSetting, btnDisplayNameEdit, changeBtnDisplayName, btnDisplayNameBlurEvent } =
530   useButtonsSetting()
531 const approveType = ref(ApproveType.USER)
532 // 审批人表单设置
533 const formRef = ref() // 表单 Ref
534 // 表单校验规则
535 const formRules = reactive({
536   candidateStrategy: [{ required: true, message: '审批人设置不能为空', trigger: 'change' }],
537   userIds: [{ required: true, message: '用户不能为空', trigger: 'change' }],
538   roleIds: [{ required: true, message: '角色不能为空', trigger: 'change' }],
539   deptIds: [{ required: true, message: '部门不能为空', trigger: 'change' }],
540   userGroups: [{ required: true, message: '用户组不能为空', trigger: 'change' }],
541   formUser: [{ required: true, message: '表单内用户字段不能为空', trigger: 'change' }],
542   formDept: [{ required: true, message: '表单内部门字段不能为空', trigger: 'change' }],
543   postIds: [{ required: true, message: '岗位不能为空', trigger: 'change' }],
544   expression: [{ required: true, message: '流程表达式不能为空', trigger: 'blur' }],
545   approveMethod: [{ required: true, message: '多人审批方式不能为空', trigger: 'change' }],
546   approveRatio: [{ required: true, message: '通过比例不能为空', trigger: 'blur' }],
547   returnNodeId: [{ required: true, message: '驳回节点不能为空', trigger: 'change' }],
548   timeoutHandlerEnable: [{ required: true }],
549   timeoutHandlerType: [{ required: true }],
550   timeDuration: [{ required: true, message: '超时时间不能为空', trigger: 'blur' }],
551   maxRemindCount: [{ required: true, message: '提醒次数不能为空', trigger: 'blur' }],
552   assignEmptyHandlerType: [{ required: true }],
553   assignEmptyHandlerUserIds: [{ required: true, message: '用户不能为空', trigger: 'change' }],
554   assignStartUserHandlerType: [{ required: true }]
555 })
556
557 const {
558   configForm: tempConfigForm,
559   roleOptions,
560   postOptions,
561   userOptions,
562   userGroupOptions,
563   deptTreeOptions,
564   handleCandidateParam,
565   parseCandidateParam,
566   getShowText
567 } = useNodeForm(NodeType.USER_TASK_NODE)
568 const configForm = tempConfigForm as Ref<UserTaskFormType>
569
570 // 改变审批人设置策略
571 const changeCandidateStrategy = () => {
572   configForm.value.userIds = []
573   configForm.value.deptIds = []
574   configForm.value.roleIds = []
575   configForm.value.postIds = []
576   configForm.value.userGroups = []
577   configForm.value.deptLevel = 1
578   configForm.value.formUser = ''
579   configForm.value.formDept = ''
580   configForm.value.approveMethod = ApproveMethodType.SEQUENTIAL_APPROVE
581 }
582
583 // 审批方式改变
584 const approveMethodChanged = () => {
585   configForm.value.rejectHandlerType = RejectHandlerType.FINISH_PROCESS
586   if (configForm.value.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) {
587     configForm.value.approveRatio = 100
588   }
589   formRef.value.clearValidate('approveRatio')
590 }
591 // 审批拒绝 可退回的节点
592 const returnTaskList = ref<SimpleFlowNode[]>([])
593 // 审批人超时未处理设置
594 const {
595   timeoutHandlerChange,
596   cTimeoutType,
597   timeoutHandlerTypeChanged,
598   timeUnit,
599   timeUnitChange,
600   isoTimeDuration,
601   cTimeoutMaxRemindCount
602 } = useTimeoutHandler()
603
604 // 保存配置
605 const saveConfig = async () => {
606   activeTabName.value = 'user'
607   // 设置审批节点名称
608   currentNode.value.name = nodeName.value!
609   // 设置审批类型
610   currentNode.value.approveType = approveType.value
611   // 如果不是人工审批。返回
612   if (approveType.value !== ApproveType.USER) {
613     currentNode.value.showText = getApproveTypeText(approveType.value)
614     settingVisible.value = false
615     return true
616   }
617
618   if (!formRef) return false
619   const valid = await formRef.value.validate()
620   if (!valid) return false
621   const showText = getShowText()
622   if (!showText) return false
623
624   currentNode.value.candidateStrategy = configForm.value.candidateStrategy
625   // 处理 candidateParam 参数
626   currentNode.value.candidateParam = handleCandidateParam()
627   // 设置审批方式
628   currentNode.value.approveMethod = configForm.value.approveMethod
629   if (configForm.value.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) {
630     currentNode.value.approveRatio = configForm.value.approveRatio
631   }
632   // 设置拒绝处理
633   currentNode.value.rejectHandler = {
634     type: configForm.value.rejectHandlerType!,
635     returnNodeId: configForm.value.returnNodeId
636   }
637   // 设置超时处理
638   currentNode.value.timeoutHandler = {
639     enable: configForm.value.timeoutHandlerEnable!,
640     type: cTimeoutType.value,
641     timeDuration: isoTimeDuration.value,
642     maxRemindCount: cTimeoutMaxRemindCount.value
643   }
644   // 设置审批人为空时
645   currentNode.value.assignEmptyHandler = {
646     type: configForm.value.assignEmptyHandlerType!,
647     userIds:
648       configForm.value.assignEmptyHandlerType === AssignEmptyHandlerType.ASSIGN_USER
649         ? configForm.value.assignEmptyHandlerUserIds
650         : undefined
651   }
652   // 设置审批人与发起人相同时
653   currentNode.value.assignStartUserHandlerType = configForm.value.assignStartUserHandlerType
654   // 设置表单权限
655   currentNode.value.fieldsPermission = fieldsPermissionConfig.value
656   // 设置按钮权限
657   currentNode.value.buttonsSetting = buttonsSetting.value
658
659   currentNode.value.showText = showText
660   settingVisible.value = false
661   return true
662 }
663
664 // 显示审批节点配置, 由父组件传过来
665 const showUserTaskNodeConfig = (node: SimpleFlowNode) => {
666   nodeName.value = node.name
667   // 1 审批类型
668   approveType.value = node.approveType ? node.approveType : ApproveType.USER
669   // 如果审批类型不是人工审批返回
670   if (approveType.value !== ApproveType.USER) {
671     return
672   }
673
674   //2.1 审批人设置
675   configForm.value.candidateStrategy = node.candidateStrategy!
676   // 解析候选人参数
677   parseCandidateParam(node.candidateStrategy!, node?.candidateParam)
678   // 2.2 设置审批方式
679   configForm.value.approveMethod = node.approveMethod!
680   if (node.approveMethod == ApproveMethodType.APPROVE_BY_RATIO) {
681     configForm.value.approveRatio = node.approveRatio!
682   }
683   // 2.3 设置审批拒绝处理
684   configForm.value.rejectHandlerType = node.rejectHandler!.type
685   configForm.value.returnNodeId = node.rejectHandler?.returnNodeId
686   const matchNodeList = []
687   emits('find:returnTaskNodes', matchNodeList)
688   returnTaskList.value = matchNodeList
689   // 2.4 设置审批超时处理
690   configForm.value.timeoutHandlerEnable = node.timeoutHandler!.enable
691   if (node.timeoutHandler?.enable && node.timeoutHandler?.timeDuration) {
692     const strTimeDuration = node.timeoutHandler.timeDuration
693     let parseTime = strTimeDuration.slice(2, strTimeDuration.length - 1)
694     let parseTimeUnit = strTimeDuration.slice(strTimeDuration.length - 1)
695     configForm.value.timeDuration = parseInt(parseTime)
696     timeUnit.value = convertTimeUnit(parseTimeUnit)
697   }
698   configForm.value.timeoutHandlerType = node.timeoutHandler?.type
699   configForm.value.maxRemindCount = node.timeoutHandler?.maxRemindCount
700   // 2.5 设置审批人为空时
701   configForm.value.assignEmptyHandlerType = node.assignEmptyHandler?.type
702   configForm.value.assignEmptyHandlerUserIds = node.assignEmptyHandler?.userIds
703   // 2.6 设置用户任务的审批人与发起人相同时
704   configForm.value.assignStartUserHandlerType = node.assignStartUserHandlerType
705   // 3. 操作按钮设置
706   buttonsSetting.value = cloneDeep(node.buttonsSetting) || DEFAULT_BUTTON_SETTING
707   // 4. 表单字段权限配置
708   getNodeConfigFormFields(node.fieldsPermission)
709 }
710
711 defineExpose({ openDrawer, showUserTaskNodeConfig }) // 暴露方法给父组件
712
713 /**
714  * @description 操作按钮设置
715  */
716 function useButtonsSetting() {
717   const buttonsSetting = ref<ButtonSetting[]>()
718   // 操作按钮显示名称可编辑
719   const btnDisplayNameEdit = ref<boolean[]>([])
720   const changeBtnDisplayName = (index: number) => {
721     btnDisplayNameEdit.value[index] = true
722   }
723   const btnDisplayNameBlurEvent = (index: number) => {
724     btnDisplayNameEdit.value[index] = false
725     const buttonItem = buttonsSetting.value![index]
726     buttonItem.displayName = buttonItem.displayName || OPERATION_BUTTON_NAME.get(buttonItem.id)!
727   }
728   return {
729     buttonsSetting,
730     btnDisplayNameEdit,
731     changeBtnDisplayName,
732     btnDisplayNameBlurEvent
733   }
734 }
735
736 /**
737  * @description 审批人超时未处理配置
738  */
739 function useTimeoutHandler() {
740   // 时间单位
741   const timeUnit = ref(TimeUnitType.HOUR)
742
743   // 超时开关改变
744   const timeoutHandlerChange = () => {
745     if (configForm.value.timeoutHandlerEnable) {
746       timeUnit.value = 2
747       configForm.value.timeDuration = 6
748       configForm.value.timeoutHandlerType = 1
749       configForm.value.maxRemindCount = 1
750     }
751   }
752   // 超时执行的动作
753   const cTimeoutType = computed(() => {
754     if (!configForm.value.timeoutHandlerEnable) {
755       return undefined
756     }
757     return configForm.value.timeoutHandlerType
758   })
759
760   // 超时处理动作改变
761   const timeoutHandlerTypeChanged = () => {
762     if (configForm.value.timeoutHandlerType === TimeoutHandlerType.REMINDER) {
763       configForm.value.maxRemindCount = 1 // 超时提醒次数,默认为1
764     }
765   }
766
767   // 时间单位改变
768   const timeUnitChange = () => {
769     // 分钟,默认是 60 分钟
770     if (timeUnit.value === TimeUnitType.MINUTE) {
771       configForm.value.timeDuration = 60
772     }
773     // 小时,默认是 6 个小时
774     if (timeUnit.value === TimeUnitType.HOUR) {
775       configForm.value.timeDuration = 6
776     }
777     // 天, 默认 1天
778     if (timeUnit.value === TimeUnitType.DAY) {
779       configForm.value.timeDuration = 1
780     }
781   }
782   // 超时时间的 ISO 表示
783   const isoTimeDuration = computed(() => {
784     if (!configForm.value.timeoutHandlerEnable) {
785       return undefined
786     }
787     let strTimeDuration = 'PT'
788     if (timeUnit.value === TimeUnitType.MINUTE) {
789       strTimeDuration += configForm.value.timeDuration + 'M'
790     }
791     if (timeUnit.value === TimeUnitType.HOUR) {
792       strTimeDuration += configForm.value.timeDuration + 'H'
793     }
794     if (timeUnit.value === TimeUnitType.DAY) {
795       strTimeDuration += configForm.value.timeDuration + 'D'
796     }
797     return strTimeDuration
798   })
799
800   // 超时最大提醒次数
801   const cTimeoutMaxRemindCount = computed(() => {
802     if (!configForm.value.timeoutHandlerEnable) {
803       return undefined
804     }
805     if (configForm.value.timeoutHandlerType !== TimeoutHandlerType.REMINDER) {
806       return undefined
807     }
808     return configForm.value.maxRemindCount
809   })
810
811   return {
812     timeoutHandlerChange,
813     cTimeoutType,
814     timeoutHandlerTypeChanged,
815     timeUnit,
816     timeUnitChange,
817     isoTimeDuration,
818     cTimeoutMaxRemindCount
819   }
820 }
821 </script>
822
823 <style lang="scss" scoped>
824 .button-setting-pane {
825   display: flex;
826   flex-direction: column;
827   font-size: 14px;
828
829   .button-setting-desc {
830     padding-right: 8px;
831     margin-bottom: 16px;
832     font-size: 16px;
833     font-weight: 700;
834   }
835
836   .button-setting-title {
837     display: flex;
838     justify-content: space-between;
839     align-items: center;
840     height: 45px;
841     padding-left: 12px;
842     background-color: #f8fafc0a;
843     border: 1px solid #1f38581a;
844
845     & > :first-child {
846       width: 100px !important;
847       text-align: left !important;
848     }
849
850     & > :last-child {
851       text-align: center !important;
852     }
853
854     .button-title-label {
855       width: 150px;
856       font-size: 13px;
857       font-weight: 700;
858       color: #000;
859       text-align: left;
860     }
861   }
862
863   .button-setting-item {
864     align-items: center;
865     display: flex;
866     justify-content: space-between;
867     height: 38px;
868     padding-left: 12px;
869     border: 1px solid #1f38581a;
870     border-top: 0;
871
872     & > :first-child {
873       width: 100px !important;
874     }
875
876     & > :last-child {
877       text-align: center !important;
878     }
879
880     .button-setting-item-label {
881       width: 150px;
882       overflow: hidden;
883       text-align: left;
884       text-overflow: ellipsis;
885       white-space: nowrap;
886     }
887
888     .editable-title-input {
889       height: 24px;
890       max-width: 130px;
891       margin-left: 4px;
892       line-height: 24px;
893       border: 1px solid #d9d9d9;
894       border-radius: 4px;
895       transition: all 0.3s;
896
897       &:focus {
898         border-color: #40a9ff;
899         outline: 0;
900         box-shadow: 0 0 0 2px rgb(24 144 255 / 20%);
901       }
902     }
903   }
904 }
905 </style>