diff --git a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/utils/ModelUtils.java b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/utils/ModelUtils.java index f4bbca63..b9b18ff6 100644 --- a/ruoyi-flowable/src/main/java/com/ruoyi/flowable/utils/ModelUtils.java +++ b/ruoyi-flowable/src/main/java/com/ruoyi/flowable/utils/ModelUtils.java @@ -1,5 +1,6 @@ package com.ruoyi.flowable.utils; +import cn.hutool.core.util.ObjectUtil; import org.flowable.bpmn.converter.BpmnXMLConverter; import org.flowable.bpmn.model.Process; import org.flowable.bpmn.model.*; @@ -92,6 +93,23 @@ public class ModelUtils { return null; } + public static UserTask getUserTaskByKey(BpmnModel model, String taskKey) { + Process process = model.getMainProcess(); + FlowElement flowElement = process.getFlowElement(taskKey); + if (flowElement instanceof UserTask) { + return (UserTask) flowElement; + } + return null; + } + + public static boolean isMultiInstance(BpmnModel model, String taskKey) { + UserTask userTask = getUserTaskByKey(model, taskKey); + if (ObjectUtil.isNotNull(userTask)) { + return userTask.hasMultiInstanceLoopCharacteristics(); + } + return false; + } + /** * 获取所有用户任务节点 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/bo/WfTaskBo.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/bo/WfTaskBo.java index 73fd9c87..e9900ff7 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/bo/WfTaskBo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/domain/bo/WfTaskBo.java @@ -57,4 +57,8 @@ public class WfTaskBo { * 抄送用户Id */ private String copyUserIds; + /** + * 下一节点审批人 + */ + private String nextUserIds; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfTaskServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfTaskServiceImpl.java index 657b71a2..467536c8 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfTaskServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/workflow/service/impl/WfTaskServiceImpl.java @@ -97,6 +97,10 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ } // 设置任务节点名称 taskBo.setTaskName(task.getName()); + // 处理下一级审批人 + if (StringUtils.isNotBlank(taskBo.getNextUserIds())) { + this.assignNextUsers(task.getProcessDefinitionId(), taskBo.getProcInsId(), taskBo.getNextUserIds()); + } // 处理抄送用户 if (!copyService.makeCopy(taskBo)) { throw new RuntimeException("抄送任务失败"); @@ -684,4 +688,54 @@ public class WfTaskServiceImpl extends FlowServiceFactory implements IWfTaskServ } } } + + /** + * 指派下一任务审批人 + * @param processDefId 流程定义id + * @param processInsId 流程实例id + * @param userIds 用户ids + */ + private void assignNextUsers(String processDefId, String processInsId, String userIds) { + // 获取所有节点信息 + List list = taskService.createTaskQuery() + .processInstanceId(processInsId) + .list(); + if (list.size() == 0) { + return; + } + Queue assignIds = CollUtil.newLinkedList(userIds.split(",")); + if (list.size() == assignIds.size()) { + for (Task task : list) { + taskService.setAssignee(task.getId(), assignIds.poll()); + } + return; + } + BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefId); + // 优先处理非多实例任务 + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + Task task = iterator.next(); + if (!ModelUtils.isMultiInstance(bpmnModel, task.getTaskDefinitionKey())) { + if (!assignIds.isEmpty()) { + taskService.setAssignee(task.getId(), assignIds.poll()); + } + iterator.remove(); + } + } + // 若存在多实例任务,则进行动态加减签 + if (CollUtil.isNotEmpty(list)) { + if (assignIds.isEmpty()) { + // 动态减签 + for (Task task : list) { + runtimeService.deleteMultiInstanceExecution(task.getExecutionId(), true); + } + } else { + // 动态加签 + for (String assignId : assignIds) { + Map assignVariables = Collections.singletonMap(BpmnXMLConstants.ATTRIBUTE_TASK_USER_ASSIGNEE, assignId); + runtimeService.addMultiInstanceExecution(list.get(0).getTaskDefinitionKey(), list.get(0).getProcessInstanceId(), assignVariables); + } + } + } + } } diff --git a/ruoyi-ui/src/views/workflow/work/detail.vue b/ruoyi-ui/src/views/workflow/work/detail.vue index b4b9a4c9..681056a4 100644 --- a/ruoyi-ui/src/views/workflow/work/detail.vue +++ b/ruoyi-ui/src/views/workflow/work/detail.vue @@ -17,20 +17,31 @@ - + - {{ item.label }} + @close="handleClose('copy', item)"> + {{ item.nickName }} - + + + + + {{ item.nickName }} + + @@ -167,7 +178,7 @@ highlight-current-row @current-change="changeCurrentUser" @selection-change="handleSelectionChange"> - +