潘志宝
22 小时以前 221918bba28d2384d03c596a68256d7832e4a0e0
提交 | 用户 | 时间
3e359e 1 import { TaskStatusEnum } from '@/api/bpm/task'
H 2 import * as RoleApi from '@/api/system/role'
3 import * as DeptApi from '@/api/system/dept'
4 import * as PostApi from '@/api/system/post'
5 import * as UserApi from '@/api/system/user'
6 import * as UserGroupApi from '@/api/bpm/userGroup'
7 import {
8   SimpleFlowNode,
9   CandidateStrategy,
10   NodeType,
11   ApproveMethodType,
12   RejectHandlerType,
13   NODE_DEFAULT_NAME,
14   AssignStartUserHandlerType,
15   AssignEmptyHandlerType,
c9a6f7 16   FieldPermissionType
3e359e 17 } from './consts'
H 18 import { parseFormFields } from '@/components/FormCreate/src/utils/index'
19 export function useWatchNode(props: { flowNode: SimpleFlowNode }): Ref<SimpleFlowNode> {
20   const node = ref<SimpleFlowNode>(props.flowNode)
21   watch(
22     () => props.flowNode,
23     (newValue) => {
24       node.value = newValue
25     }
26   )
27   return node
28 }
29
30 // 解析 formCreate 所有表单字段, 并返回
31 const parseFormCreateFields = (formFields?: string[]) => {
32   const result: Array<Record<string, any>> = []
33   if (formFields) {
34     formFields.forEach((fieldStr: string) => {
35       parseFormFields(JSON.parse(fieldStr), result)
36     })
37   }
38   return result
39 }
40
41 /**
42  * @description 表单数据权限配置,用于发起人节点 、审批节点、抄送节点
43  */
44 export function useFormFieldsPermission(defaultPermission: FieldPermissionType) {
45   // 字段权限配置. 需要有 field, title,  permissioin 属性
46   const fieldsPermissionConfig = ref<Array<Record<string, any>>>([])
47
48   const formType = inject<Ref<number>>('formType') // 表单类型
49
50   const formFields = inject<Ref<string[]>>('formFields') // 流程表单字段
51
52   const getNodeConfigFormFields = (nodeFormFields?: Array<Record<string, string>>) => {
53     nodeFormFields = toRaw(nodeFormFields)
c9a6f7 54     if (!nodeFormFields || nodeFormFields.length === 0) {
H 55       fieldsPermissionConfig.value = getDefaultFieldsPermission(unref(formFields))
56     } else {
57       fieldsPermissionConfig.value = mergeFieldsPermission(nodeFormFields, unref(formFields))
58     }
3e359e 59   }
c9a6f7 60   // 合并已经设置的表单字段权限,当前流程表单字段 (可能新增,或删除了字段)
H 61   const mergeFieldsPermission = (
62     formFieldsPermisson: Array<Record<string, string>>,
63     formFields?: string[]
64   ) => {
65     let mergedFieldsPermission: Array<Record<string, any>> = []
66     if (formFields) {
67       mergedFieldsPermission = parseFormCreateFields(formFields).map((item) => {
68         const found = formFieldsPermisson.find(
69           (fieldPermission) => fieldPermission.field == item.field
70         )
71         return {
72           field: item.field,
73           title: item.title,
74           permission: found ? found.permission : defaultPermission
75         }
76       })
77     }
78     return mergedFieldsPermission
79   }
80
3e359e 81   // 默认的表单权限: 获取表单的所有字段,设置字段默认权限为只读
H 82   const getDefaultFieldsPermission = (formFields?: string[]) => {
83     let defaultFieldsPermission: Array<Record<string, any>> = []
84     if (formFields) {
85       defaultFieldsPermission = parseFormCreateFields(formFields).map((item) => {
86         return {
87           field: item.field,
88           title: item.title,
89           permission: defaultPermission
90         }
91       })
92     }
93     return defaultFieldsPermission
94   }
95
96   // 获取表单的所有字段,作为下拉框选项
97   const formFieldOptions = parseFormCreateFields(unref(formFields))
98
99   return {
100     formType,
101     fieldsPermissionConfig,
102     formFieldOptions,
103     getNodeConfigFormFields
104   }
105 }
106 /**
107  * @description 获取表单的字段
108  */
109 export function useFormFields() {
110   const formFields = inject<Ref<string[]>>('formFields') // 流程表单字段
111   return parseFormCreateFields(unref(formFields))
112 }
113
114 export type UserTaskFormType = {
115   //candidateParamArray: any[]
116   candidateStrategy: CandidateStrategy
117   approveMethod: ApproveMethodType
118   roleIds?: number[] // 角色
119   deptIds?: number[] // 部门
120   deptLevel?: number // 部门层级
121   userIds?: number[] // 用户
122   userGroups?: number[] // 用户组
123   postIds?: number[] // 岗位
124   expression?: string // 流程表达式
125   formUser?: string // 表单内用户字段
126   formDept?: string // 表单内部门字段
127   approveRatio?: number
128   rejectHandlerType?: RejectHandlerType
129   returnNodeId?: string
130   timeoutHandlerEnable?: boolean
131   timeoutHandlerType?: number
132   assignEmptyHandlerType?: AssignEmptyHandlerType
133   assignEmptyHandlerUserIds?: number[]
134   assignStartUserHandlerType?: AssignStartUserHandlerType
135   timeDuration?: number
136   maxRemindCount?: number
137   buttonsSetting: any[]
138 }
139
140 export type CopyTaskFormType = {
141   // candidateParamArray: any[]
142   candidateStrategy: CandidateStrategy
143   roleIds?: number[] // 角色
144   deptIds?: number[] // 部门
145   deptLevel?: number // 部门层级
146   userIds?: number[] // 用户
147   userGroups?: number[] // 用户组
148   postIds?: number[] // 岗位
149   formUser?: string // 表单内用户字段
150   formDept?: string // 表单内部门字段
151   expression?: string // 流程表达式
152 }
153
154 /**
155  * @description 节点表单数据。 用于审批节点、抄送节点
156  */
157 export function useNodeForm(nodeType: NodeType) {
158   const roleOptions = inject<Ref<RoleApi.RoleVO[]>>('roleList') // 角色列表
159   const postOptions = inject<Ref<PostApi.PostVO[]>>('postList') // 岗位列表
160   const userOptions = inject<Ref<UserApi.UserVO[]>>('userList') // 用户列表
161   const deptOptions = inject<Ref<DeptApi.DeptVO[]>>('deptList') // 部门列表
162   const userGroupOptions = inject<Ref<UserGroupApi.UserGroupVO[]>>('userGroupList') // 用户组列表
163   const deptTreeOptions = inject('deptTree') // 部门树
164   const formFields = inject<Ref<string[]>>('formFields') // 流程表单字段
165   const configForm = ref<UserTaskFormType | CopyTaskFormType>()
166   if (nodeType === NodeType.USER_TASK_NODE) {
167     configForm.value = {
168       candidateStrategy: CandidateStrategy.USER,
169       approveMethod: ApproveMethodType.SEQUENTIAL_APPROVE,
170       approveRatio: 100,
171       rejectHandlerType: RejectHandlerType.FINISH_PROCESS,
172       assignStartUserHandlerType: AssignStartUserHandlerType.START_USER_AUDIT,
173       returnNodeId: '',
174       timeoutHandlerEnable: false,
175       timeoutHandlerType: 1,
176       timeDuration: 6, // 默认 6小时
177       maxRemindCount: 1, // 默认 提醒 1次
178       buttonsSetting: []
179     }
180   } else {
181     configForm.value = {
182       candidateStrategy: CandidateStrategy.USER
183     }
184   }
185
186   const getShowText = (): string => {
187     let showText = ''
188     // 指定成员
189     if (configForm.value?.candidateStrategy === CandidateStrategy.USER) {
190       if (configForm.value?.userIds!.length > 0) {
191         const candidateNames: string[] = []
192         userOptions?.value.forEach((item) => {
193           if (configForm.value?.userIds!.includes(item.id)) {
194             candidateNames.push(item.nickname)
195           }
196         })
197         showText = `指定成员:${candidateNames.join(',')}`
198       }
199     }
200     // 指定角色
201     if (configForm.value?.candidateStrategy === CandidateStrategy.ROLE) {
202       if (configForm.value.roleIds!.length > 0) {
203         const candidateNames: string[] = []
204         roleOptions?.value.forEach((item) => {
205           if (configForm.value?.roleIds!.includes(item.id)) {
206             candidateNames.push(item.name)
207           }
208         })
209         showText = `指定角色:${candidateNames.join(',')}`
210       }
211     }
212     // 指定部门
213     if (
214       configForm.value?.candidateStrategy === CandidateStrategy.DEPT_MEMBER ||
215       configForm.value?.candidateStrategy === CandidateStrategy.DEPT_LEADER ||
216       configForm.value?.candidateStrategy === CandidateStrategy.MULTI_LEVEL_DEPT_LEADER
217     ) {
218       if (configForm.value?.deptIds!.length > 0) {
219         const candidateNames: string[] = []
220         deptOptions?.value.forEach((item) => {
221           if (configForm.value?.deptIds!.includes(item.id!)) {
222             candidateNames.push(item.name)
223           }
224         })
225         if (configForm.value.candidateStrategy === CandidateStrategy.DEPT_MEMBER) {
226           showText = `部门成员:${candidateNames.join(',')}`
227         } else if (configForm.value.candidateStrategy === CandidateStrategy.DEPT_LEADER) {
228           showText = `部门的负责人:${candidateNames.join(',')}`
229         } else {
230           showText = `多级部门的负责人:${candidateNames.join(',')}`
231         }
232       }
233     }
234
235     // 指定岗位
236     if (configForm.value?.candidateStrategy === CandidateStrategy.POST) {
237       if (configForm.value.postIds!.length > 0) {
238         const candidateNames: string[] = []
239         postOptions?.value.forEach((item) => {
240           if (configForm.value?.postIds!.includes(item.id!)) {
241             candidateNames.push(item.name)
242           }
243         })
244         showText = `指定岗位: ${candidateNames.join(',')}`
245       }
246     }
247     // 指定用户组
248     if (configForm.value?.candidateStrategy === CandidateStrategy.USER_GROUP) {
249       if (configForm.value?.userGroups!.length > 0) {
250         const candidateNames: string[] = []
251         userGroupOptions?.value.forEach((item) => {
252           if (configForm.value?.userGroups!.includes(item.id)) {
253             candidateNames.push(item.name)
254           }
255         })
256         showText = `指定用户组: ${candidateNames.join(',')}`
257       }
258     }
259
260     // 表单内用户字段
261     if (configForm.value?.candidateStrategy === CandidateStrategy.FORM_USER) {
262       const formFieldOptions = parseFormCreateFields(unref(formFields))
263       const item = formFieldOptions.find((item) => item.field === configForm.value?.formUser)
264       showText = `表单用户:${item?.title}`
265     }
266
267     // 表单内部门负责人
268     if (configForm.value?.candidateStrategy === CandidateStrategy.FORM_DEPT_LEADER) {
269       showText = `表单内部门负责人`
270     }
271
272     // 发起人自选
273     if (configForm.value?.candidateStrategy === CandidateStrategy.START_USER_SELECT) {
274       showText = `发起人自选`
275     }
276     // 发起人自己
277     if (configForm.value?.candidateStrategy === CandidateStrategy.START_USER) {
278       showText = `发起人自己`
279     }
280     // 发起人的部门负责人
281     if (configForm.value?.candidateStrategy === CandidateStrategy.START_USER_DEPT_LEADER) {
282       showText = `发起人的部门负责人`
283     }
284     // 发起人的部门负责人
285     if (
286       configForm.value?.candidateStrategy === CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER
287     ) {
288       showText = `发起人连续部门负责人`
289     }
290     // 流程表达式
291     if (configForm.value?.candidateStrategy === CandidateStrategy.EXPRESSION) {
292       showText = `流程表达式:${configForm.value.expression}`
293     }
294     return showText
295   }
296
297   /**
298    *  处理候选人参数的赋值
299    */
300   const handleCandidateParam = () => {
301     let candidateParam: undefined | string = undefined
302     if (!configForm.value) {
303       return candidateParam
304     }
305     switch (configForm.value.candidateStrategy) {
306       case CandidateStrategy.USER:
307         candidateParam = configForm.value.userIds!.join(',')
308         break
309       case CandidateStrategy.ROLE:
310         candidateParam = configForm.value.roleIds!.join(',')
311         break
312       case CandidateStrategy.POST:
313         candidateParam = configForm.value.postIds!.join(',')
314         break
315       case CandidateStrategy.USER_GROUP:
316         candidateParam = configForm.value.userGroups!.join(',')
317         break
318       case CandidateStrategy.FORM_USER:
319         candidateParam = configForm.value.formUser!
320         break
321       case CandidateStrategy.EXPRESSION:
322         candidateParam = configForm.value.expression!
323         break
324       case CandidateStrategy.DEPT_MEMBER:
325       case CandidateStrategy.DEPT_LEADER:
326         candidateParam = configForm.value.deptIds!.join(',')
327         break
328       // 发起人部门负责人
329       case CandidateStrategy.START_USER_DEPT_LEADER:
330       case CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER:
331         candidateParam = configForm.value.deptLevel + ''
332         break
333       // 指定连续多级部门的负责人
334       case CandidateStrategy.MULTI_LEVEL_DEPT_LEADER: {
335         // 候选人参数格式: | 分隔 。左边为部门(多个部门用 , 分隔)。 右边为部门层级
336         const deptIds = configForm.value.deptIds!.join(',')
337         candidateParam = deptIds.concat('|' + configForm.value.deptLevel + '')
338         break
339       }
340       // 表单内部门的负责人
341       case CandidateStrategy.FORM_DEPT_LEADER: {
342         // 候选人参数格式: | 分隔 。左边为表单内部门字段。 右边为部门层级
343         const deptFieldOnForm = configForm.value.formDept!
344         candidateParam = deptFieldOnForm.concat('|' + configForm.value.deptLevel + '')
345         break
346       }
347       default:
348         break
349     }
350     return candidateParam
351   }
352   /**
353    *  解析候选人参数
354    */
355   const parseCandidateParam = (
356     candidateStrategy: CandidateStrategy,
357     candidateParam: string | undefined
358   ) => {
359     if (!configForm.value || !candidateParam) {
360       return
361     }
362     switch (candidateStrategy) {
363       case CandidateStrategy.USER: {
364         configForm.value.userIds = candidateParam.split(',').map((item) => +item)
365         break
366       }
367       case CandidateStrategy.ROLE:
368         configForm.value.roleIds = candidateParam.split(',').map((item) => +item)
369         break
370       case CandidateStrategy.POST:
371         configForm.value.postIds = candidateParam.split(',').map((item) => +item)
372         break
373       case CandidateStrategy.USER_GROUP:
374         configForm.value.userGroups = candidateParam.split(',').map((item) => +item)
375         break
376       case CandidateStrategy.FORM_USER:
377         configForm.value.formUser = candidateParam
378         break
379       case CandidateStrategy.EXPRESSION:
380         configForm.value.expression = candidateParam
381         break
382       case CandidateStrategy.DEPT_MEMBER:
383       case CandidateStrategy.DEPT_LEADER:
384         configForm.value.deptIds = candidateParam.split(',').map((item) => +item)
385         break
386       // 发起人部门负责人
387       case CandidateStrategy.START_USER_DEPT_LEADER:
388       case CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER:
389         configForm.value.deptLevel = +candidateParam
390         break
391       // 指定连续多级部门的负责人
392       case CandidateStrategy.MULTI_LEVEL_DEPT_LEADER: {
393         // 候选人参数格式: | 分隔 。左边为部门(多个部门用 , 分隔)。 右边为部门层级
394         const paramArray = candidateParam.split('|')
395         configForm.value.deptIds = paramArray[0].split(',').map((item) => +item)
396         configForm.value.deptLevel = +paramArray[1]
397         break
398       }
399       // 表单内的部门负责人
400       case CandidateStrategy.FORM_DEPT_LEADER: {
401         // 候选人参数格式: | 分隔 。左边为表单内的部门字段。 右边为部门层级
402         const paramArray = candidateParam.split('|')
403         configForm.value.formDept = paramArray[0]
404         configForm.value.deptLevel = +paramArray[1]
405         break
406       }
407       default:
408         break
409     }
410   }
411   return {
412     configForm,
413     roleOptions,
414     postOptions,
415     userOptions,
416     userGroupOptions,
417     deptTreeOptions,
418     handleCandidateParam,
419     parseCandidateParam,
420     getShowText
421   }
422 }
423
424 /**
425  * @description 抽屉配置
426  */
427 export function useDrawer() {
428   // 抽屉配置是否可见
429   const settingVisible = ref(false)
430   // 关闭配置抽屉
431   const closeDrawer = () => {
432     settingVisible.value = false
433   }
434   // 打开配置抽屉
435   const openDrawer = () => {
436     settingVisible.value = true
437   }
438   return {
439     settingVisible,
440     closeDrawer,
441     openDrawer
442   }
443 }
444
445 /**
446  * @description 节点名称配置
447  */
448 export function useNodeName(nodeType: NodeType) {
449   // 节点名称
450   const nodeName = ref<string>()
451   // 节点名称输入框
452   const showInput = ref(false)
453   // 点击节点名称编辑图标
454   const clickIcon = () => {
455     showInput.value = true
456   }
457   // 节点名称输入框失去焦点
458   const blurEvent = () => {
459     showInput.value = false
460     nodeName.value = nodeName.value || (NODE_DEFAULT_NAME.get(nodeType) as string)
461   }
462   return {
463     nodeName,
464     showInput,
465     clickIcon,
466     blurEvent
467   }
468 }
469
470 export function useNodeName2(node: Ref<SimpleFlowNode>, nodeType: NodeType) {
471   // 显示节点名称输入框
472   const showInput = ref(false)
473   // 节点名称输入框失去焦点
474   const blurEvent = () => {
475     showInput.value = false
476     node.value.name = node.value.name || (NODE_DEFAULT_NAME.get(nodeType) as string)
477   }
478   // 点击节点标题进行输入
479   const clickTitle = () => {
480     showInput.value = true
481   }
482   return {
483     showInput,
484     clickTitle,
485     blurEvent
486   }
487 }
488
489 /**
490  * @description 根据节点任务状态,获取节点任务状态样式
491  */
492 export function useTaskStatusClass(taskStatus: TaskStatusEnum | undefined): string {
493   if (!taskStatus) {
494     return ''
495   }
496   if (taskStatus === TaskStatusEnum.APPROVE) {
497     return 'status-pass'
498   }
499   if (taskStatus === TaskStatusEnum.RUNNING) {
500     return 'status-running'
501   }
502   if (taskStatus === TaskStatusEnum.REJECT) {
503     return 'status-reject'
504   }
505   if (taskStatus === TaskStatusEnum.CANCEL) {
506     return 'status-cancel'
507   }
508
509   return ''
510 }