Procházet zdrojové kódy

feat:【bpm 工作流】审批人自选时,相同节点共享数据

YunaiV před 7 měsíci
rodič
revize
ca17d5ac21

+ 23 - 0
src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue

@@ -51,8 +51,10 @@
           >
             <div class="ml-10px -mt-15px -mb-35px">
               <ProcessInstanceTimeline
+                ref="nextAssigneesTimelineRef"
                 :activity-nodes="nextAssigneesActivityNode"
                 :show-status-icon="false"
+                :enable-approve-user-select="true"
                 @select-user-confirm="selectNextAssigneesConfirm"
               />
             </div>
@@ -571,6 +573,7 @@ const approveFormRef = ref<FormInstance>()
 const signRef = ref()
 const approveSignFormRef = ref()
 const nextAssigneesActivityNode = ref<ProcessInstanceApi.ApprovalNodeInfo[]>([]) // 下一个审批节点信息
+const nextAssigneesTimelineRef = ref() // 下一个节点审批人时间线组件的引用
 const approveReasonForm = reactive({
   reason: '',
   signPicUrl: '',
@@ -717,6 +720,10 @@ const closePopover = (type: string, formRef: FormInstance | undefined) => {
   }
   popOverVisible.value[type] = false
   nextAssigneesActivityNode.value = []
+  // 清理 Timeline 组件中的自定义审批人数据
+  if (nextAssigneesTimelineRef.value) {
+    nextAssigneesTimelineRef.value.batchSetCustomApproveUsers({})
+  }
 }
 
 /** 流程通过时,根据表单变量查询新的流程节点,判断下一个节点类型是否为自选审批人 */
@@ -729,6 +736,7 @@ const initNextAssigneesFormField = async () => {
     processVariablesStr: JSON.stringify(variables)
   })
   if (data && data.length > 0) {
+    const customApproveUsersData: Record<string, any[]> = {} // 用于收集需要设置到 Timeline 组件的自定义审批人数据
     data.forEach((node: any) => {
       if (
         // 情况一:当前节点没有审批人,并且是发起人自选
@@ -740,7 +748,18 @@ const initNextAssigneesFormField = async () => {
       ) {
         nextAssigneesActivityNode.value.push(node)
       }
+
+      // 如果节点有 candidateUsers,设置到 customApproveUsers 中
+      if (node.candidateUsers && node.candidateUsers.length > 0) {
+        customApproveUsersData[node.id] = node.candidateUsers
+      }
     })
+
+    // 将 candidateUsers 设置到 Timeline 组件中
+    await nextTick() // 等待下一个 tick,确保 Timeline 组件已经渲染
+    if (nextAssigneesTimelineRef.value && Object.keys(customApproveUsersData).length > 0) {
+      nextAssigneesTimelineRef.value.batchSetCustomApproveUsers(customApproveUsersData)
+    }
   }
 }
 
@@ -803,6 +822,10 @@ const handleAudit = async (pass: boolean, formRef: FormInstance | undefined) =>
       await TaskApi.approveTask(data)
       popOverVisible.value.approve = false
       nextAssigneesActivityNode.value = []
+      // 清理 Timeline 组件中的自定义审批人数据
+      if (nextAssigneesTimelineRef.value) {
+        nextAssigneesTimelineRef.value.batchSetCustomApproveUsers({})
+      }
       message.success('审批通过成功')
     } else {
       // 审批不通过数据

+ 26 - 9
src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue

@@ -15,7 +15,7 @@
         >
           <img class="w-full h-full" :src="getApprovalNodeImg(activity.nodeType)" alt="" />
           <div
-            v-if="showStatusIcon"
+            v-if="props.showStatusIcon"
             class="position-absolute top-17px left-17px rounded-full flex items-center p-1px border-2 border-white border-solid"
             :style="{ backgroundColor: getApprovalNodeColor(activity.status) }"
           >
@@ -55,13 +55,13 @@
           class="flex flex-wrap gap2 items-center"
           v-if="
             isEmpty(activity.tasks) &&
-            isEmpty(activity.candidateUsers) &&
-            (CandidateStrategy.START_USER_SELECT === activity.candidateStrategy ||
-              CandidateStrategy.APPROVE_USER_SELECT === activity.candidateStrategy)
+            ((CandidateStrategy.START_USER_SELECT === activity.candidateStrategy &&
+              isEmpty(activity.candidateUsers)) ||
+              (props.enableApproveUserSelect &&
+                CandidateStrategy.APPROVE_USER_SELECT === activity.candidateStrategy))
           "
         >
           <!--  && activity.nodeType === NodeType.USER_TASK_NODE -->
-
           <el-tooltip content="添加用户" placement="left">
             <el-button
               class="!px-6px"
@@ -119,7 +119,7 @@
                 </template>
                 <!-- 信息:任务 ICON -->
                 <div
-                  v-if="showStatusIcon && onlyStatusIconShow.includes(task.status)"
+                  v-if="props.showStatusIcon && onlyStatusIconShow.includes(task.status)"
                   class="position-absolute top-19px left-23px rounded-full flex items-center p-1px border-2 border-white border-solid"
                   :style="{ backgroundColor: statusIconMap2[task.status]?.color }"
                 >
@@ -165,7 +165,7 @@
 
             <!-- 信息:任务 ICON -->
             <div
-              v-if="showStatusIcon"
+              v-if="props.showStatusIcon"
               class="position-absolute top-20px left-24px rounded-full flex items-center p-1px border-2 border-white border-solid"
               :style="{ backgroundColor: statusIconMap2['-1']?.color }"
             >
@@ -198,13 +198,15 @@ import transactorSvg from '@/assets/svgs/bpm/transactor.svg'
 import childProcessSvg from '@/assets/svgs/bpm/child-process.svg'
 
 defineOptions({ name: 'BpmProcessInstanceTimeline' })
-withDefaults(
+const props = withDefaults(
   defineProps<{
     activityNodes: ProcessInstanceApi.ApprovalNodeInfo[] // 审批节点信息
     showStatusIcon?: boolean // 是否显示头像右下角状态图标
+    enableApproveUserSelect?: boolean // 是否开启审批人自选功能
   }>(),
   {
-    showStatusIcon: true // 默认值为 true
+    showStatusIcon: true, // 默认值为 true
+    enableApproveUserSelect: false // 默认值为 false
   }
 )
 const { push } = useRouter() // 路由
@@ -341,4 +343,19 @@ const handleChildProcess = (activity: any) => {
     }
   })
 }
+
+/** 设置自定义审批人 */
+const setCustomApproveUsers = (activityId: string, users: any[]) => {
+  customApproveUsers.value[activityId] = users || []
+}
+
+/** 批量设置多个节点的自定义审批人 */
+const batchSetCustomApproveUsers = (data: Record<string, any[]>) => {
+  Object.keys(data).forEach((activityId) => {
+    customApproveUsers.value[activityId] = data[activityId] || []
+  })
+}
+
+// 暴露方法给父组件
+defineExpose({ setCustomApproveUsers, batchSetCustomApproveUsers })
 </script>