mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 12:18:42 +08:00 
			
		
		
		
	【功能优化】工作流:流程详情的重构 70%:优化 getRunApproveNodeList 方法,处理加签子任务的计算
This commit is contained in:
		@@ -18,26 +18,26 @@ import java.util.Objects;
 | 
				
			|||||||
public enum BpmSimpleModelNodeType implements IntArrayValuable {
 | 
					public enum BpmSimpleModelNodeType implements IntArrayValuable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 0 ~ 1 开始和结束
 | 
					    // 0 ~ 1 开始和结束
 | 
				
			||||||
    START_NODE(0, "startEvent", "开始节点"),
 | 
					    START_NODE(0, "开始", "startEvent"),
 | 
				
			||||||
    END_NODE(1, "endEvent", "结束节点"),
 | 
					    END_NODE(1, "结束", "endEvent"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 10 ~ 49 各种节点
 | 
					    // 10 ~ 49 各种节点
 | 
				
			||||||
    START_USER_NODE(10, "userTask", "发起人节点"), // 发起人节点。前端的开始节点,Id 固定
 | 
					    START_USER_NODE(10, "发起人", "userTask"), // 发起人节点。前端的开始节点,Id 固定
 | 
				
			||||||
    APPROVE_NODE(11, "userTask", "审批人节点"),
 | 
					    APPROVE_NODE(11, "审批人", "userTask"),
 | 
				
			||||||
    COPY_NODE(12, "serviceTask", "抄送人节点"),
 | 
					    COPY_NODE(12, "抄送人", "serviceTask"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 50 ~ 条件分支
 | 
					    // 50 ~ 条件分支
 | 
				
			||||||
    CONDITION_NODE(50, "sequenceFlow", "条件节点"), // 用于构建流转条件的表达式
 | 
					    CONDITION_NODE(50, "条件", "sequenceFlow"), // 用于构建流转条件的表达式
 | 
				
			||||||
    CONDITION_BRANCH_NODE(51, "exclusiveGateway", "条件分支节点"),
 | 
					    CONDITION_BRANCH_NODE(51, "条件分支", "exclusiveGateway"),
 | 
				
			||||||
    PARALLEL_BRANCH_NODE(52, "parallelGateway", "并行分支节点"),
 | 
					    PARALLEL_BRANCH_NODE(52, "并行分支", "parallelGateway"),
 | 
				
			||||||
    INCLUSIVE_BRANCH_NODE(53, "inclusiveGateway", "包容分支节点"),
 | 
					    INCLUSIVE_BRANCH_NODE(53, "包容分支", "inclusiveGateway"),
 | 
				
			||||||
    ;
 | 
					    ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmSimpleModelNodeType::getType).toArray();
 | 
					    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmSimpleModelNodeType::getType).toArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final Integer type;
 | 
					    private final Integer type;
 | 
				
			||||||
    private final String bpmnType;
 | 
					 | 
				
			||||||
    private final String name;
 | 
					    private final String name;
 | 
				
			||||||
 | 
					    private final String bpmnType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 判断是否为分支节点
 | 
					     * 判断是否为分支节点
 | 
				
			||||||
@@ -50,16 +50,6 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable {
 | 
				
			|||||||
                || Objects.equals(INCLUSIVE_BRANCH_NODE.getType(), type);
 | 
					                || Objects.equals(INCLUSIVE_BRANCH_NODE.getType(), type);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 判断是否需要记录的节点
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param bpmnType bpmn节点类型
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public static boolean isRecordNode(String bpmnType) {
 | 
					 | 
				
			||||||
        return Objects.equals(APPROVE_NODE.getBpmnType(), bpmnType)
 | 
					 | 
				
			||||||
                || Objects.equals(END_NODE.getBpmnType(), bpmnType);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static BpmSimpleModelNodeType valueOf(Integer type) {
 | 
					    public static BpmSimpleModelNodeType valueOf(Integer type) {
 | 
				
			||||||
        return ArrayUtil.firstMatch(nodeType -> nodeType.getType().equals(type), values());
 | 
					        return ArrayUtil.firstMatch(nodeType -> nodeType.getType().equals(type), values());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
package cn.iocoder.yudao.module.bpm.enums.task;
 | 
					package cn.iocoder.yudao.module.bpm.enums.task;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import cn.hutool.core.util.ObjUtil;
 | 
				
			||||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 | 
					import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 | 
				
			||||||
import lombok.AllArgsConstructor;
 | 
					import lombok.AllArgsConstructor;
 | 
				
			||||||
import lombok.Getter;
 | 
					import lombok.Getter;
 | 
				
			||||||
@@ -63,4 +64,8 @@ public enum BpmTaskStatusEnum {
 | 
				
			|||||||
                RETURN.getStatus(), APPROVING.getStatus());
 | 
					                RETURN.getStatus(), APPROVING.getStatus());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static boolean isCancelStatus(Integer status) {
 | 
				
			||||||
 | 
					        return ObjUtil.equal(status, CANCEL.getStatus());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,6 @@ public class BpmSimpleModelNodeVO {
 | 
				
			|||||||
    @Schema(description = "模型节点名称", example = "领导审批")
 | 
					    @Schema(description = "模型节点名称", example = "领导审批")
 | 
				
			||||||
    private String name;
 | 
					    private String name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO @jason:和 gpt 大模型对了下这个字段的命名,貌似叫 displayText 合适点。可以等最后我们全局替换下。(优先级:低)
 | 
					 | 
				
			||||||
    @Schema(description = "节点展示内容", example = "指定成员: 芋道源码")
 | 
					    @Schema(description = "节点展示内容", example = "指定成员: 芋道源码")
 | 
				
			||||||
    private String showText;
 | 
					    private String showText;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,7 +55,7 @@ public class BpmTaskRespVO {
 | 
				
			|||||||
    @Schema(description = "父任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
 | 
					    @Schema(description = "父任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
 | 
				
			||||||
    private String parentTaskId;
 | 
					    private String parentTaskId;
 | 
				
			||||||
    @Schema(description = "子任务列表(由加签生成)", requiredMode = Schema.RequiredMode.REQUIRED, example = "childrenTask")
 | 
					    @Schema(description = "子任务列表(由加签生成)", requiredMode = Schema.RequiredMode.REQUIRED, example = "childrenTask")
 | 
				
			||||||
    private List<BpmTaskRespVO> children;
 | 
					    private List<BpmTaskRespVO> children; // 由加签生成,包含多层子任务
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Schema(description = "表单编号", example = "1024")
 | 
					    @Schema(description = "表单编号", example = "1024")
 | 
				
			||||||
    private Long formId;
 | 
					    private Long formId;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,6 @@ import java.util.Map;
 | 
				
			|||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 | 
					import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 | 
				
			||||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
 | 
					import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
 | 
				
			||||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils.isAddSignUserTask;
 | 
					import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils.isAddSignUserTask;
 | 
				
			||||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils.isAssignUserTask;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Bpm 任务 Convert
 | 
					 * Bpm 任务 Convert
 | 
				
			||||||
@@ -134,7 +133,8 @@ public interface BpmTaskConvert {
 | 
				
			|||||||
                                                          Map<Long, DeptRespDTO> deptMap) {
 | 
					                                                          Map<Long, DeptRespDTO> deptMap) {
 | 
				
			||||||
       return convertList(todoTaskList, task -> {
 | 
					       return convertList(todoTaskList, task -> {
 | 
				
			||||||
           // 找到分配给当前用户,或者当前用户加签的任务(为了减签)
 | 
					           // 找到分配给当前用户,或者当前用户加签的任务(为了减签)
 | 
				
			||||||
           if (!isAssignUserTask(userId, task) && !isAddSignUserTask(userId, task, childrenTaskMap)) {
 | 
					           if (!FlowableUtils.isAssignUserTask(userId, task)
 | 
				
			||||||
 | 
					                   && !FlowableUtils.isAddSignUserTask(userId, task, childrenTaskMap)) {
 | 
				
			||||||
               return null;
 | 
					               return null;
 | 
				
			||||||
           }
 | 
					           }
 | 
				
			||||||
           BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
 | 
					           BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -104,10 +104,6 @@ public interface BpmnModelConstants {
 | 
				
			|||||||
     * BPMN Start Event Node Id
 | 
					     * BPMN Start Event Node Id
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    String START_EVENT_NODE_ID = "StartEvent";
 | 
					    String START_EVENT_NODE_ID = "StartEvent";
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * BPMN Start Event Node Name
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    String START_EVENT_NODE_NAME = "开始";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 发起人节点 ID
 | 
					     * 发起人节点 ID
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -201,7 +201,8 @@ public class FlowableUtils {
 | 
				
			|||||||
     * @return 是否
 | 
					     * @return 是否
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static boolean isAssignUserTask(Long userId, Task task) {
 | 
					    public static boolean isAssignUserTask(Long userId, Task task) {
 | 
				
			||||||
        return ObjectUtil.equal(userId, NumberUtil.parseLong(task.getAssignee(), null));
 | 
					        Long assignee = NumberUtil.parseLong(task.getAssignee(), null);
 | 
				
			||||||
 | 
					        return ObjectUtil.equal(userId, assignee);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -212,11 +213,13 @@ public class FlowableUtils {
 | 
				
			|||||||
     * @return 是否
 | 
					     * @return 是否
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static boolean isOwnerUserTask(Long userId, Task task) {
 | 
					    public static boolean isOwnerUserTask(Long userId, Task task) {
 | 
				
			||||||
        return ObjectUtil.equal(userId, NumberUtil.parseLong(task.getOwner(), null));
 | 
					        Long assignee = NumberUtil.parseLong(task.getAssignee(), null);
 | 
				
			||||||
 | 
					        return ObjectUtil.equal(userId, assignee);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 判断指定用户,是否是当前任务的加签人
 | 
					     * 判断指定用户,是否是当前任务的加签人
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
     * @param userId 用户 Id
 | 
					     * @param userId 用户 Id
 | 
				
			||||||
     * @param task 任务
 | 
					     * @param task 任务
 | 
				
			||||||
     * @param  childrenTaskMap 子任务集合
 | 
					     * @param  childrenTaskMap 子任务集合
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -82,7 +82,8 @@ public class SimpleModelUtils {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static BpmSimpleModelNodeVO buildStartNode() {
 | 
					    private static BpmSimpleModelNodeVO buildStartNode() {
 | 
				
			||||||
        return new BpmSimpleModelNodeVO().setId(START_EVENT_NODE_ID).setName(START_EVENT_NODE_NAME)
 | 
					        return new BpmSimpleModelNodeVO().setId(START_EVENT_NODE_ID)
 | 
				
			||||||
 | 
					                .setName(BpmSimpleModelNodeType.START_USER_NODE.getName())
 | 
				
			||||||
                .setType(BpmSimpleModelNodeType.START_NODE.getType());
 | 
					                .setType(BpmSimpleModelNodeType.START_NODE.getType());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -131,6 +131,15 @@ public interface BpmTaskService {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    List<UserTask> getUserTaskListByReturn(String id);
 | 
					    List<UserTask> getUserTaskListByReturn(String id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取指定任务的子任务列表(多层)
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param parentTaskId 父任务 ID
 | 
				
			||||||
 | 
					     * @param tasks 任务列表
 | 
				
			||||||
 | 
					     * @return 子任务列表
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    List<HistoricTaskInstance> getAllChildrenTaskListByParentTaskId(String parentTaskId, List<HistoricTaskInstance> tasks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 获取指定任务的子任务列表
 | 
					     * 获取指定任务的子任务列表
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -306,6 +306,38 @@ public class BpmTaskServiceImpl implements BpmTaskService {
 | 
				
			|||||||
        return previousUserList;
 | 
					        return previousUserList;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public List<HistoricTaskInstance> getAllChildrenTaskListByParentTaskId(String parentTaskId, List<HistoricTaskInstance> tasks) {
 | 
				
			||||||
 | 
					        if (CollUtil.isEmpty(tasks)) {
 | 
				
			||||||
 | 
					            return Collections.emptyList();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Map<String, List<HistoricTaskInstance>> parentTaskMap = convertMultiMap(
 | 
				
			||||||
 | 
					                filterList(tasks, task -> StrUtil.isNotEmpty(task.getParentTaskId())), HistoricTaskInstance::getParentTaskId);
 | 
				
			||||||
 | 
					        if (CollUtil.isEmpty(parentTaskMap)) {
 | 
				
			||||||
 | 
					            return Collections.emptyList();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        List<HistoricTaskInstance> result = new ArrayList<>();
 | 
				
			||||||
 | 
					        // 1. 递归获取子级
 | 
				
			||||||
 | 
					        Stack<String> stack = new Stack<>();
 | 
				
			||||||
 | 
					        stack.push(parentTaskId);
 | 
				
			||||||
 | 
					        // 2. 递归遍历
 | 
				
			||||||
 | 
					        for (int i = 0; i < Short.MAX_VALUE; i++) {
 | 
				
			||||||
 | 
					            if (stack.isEmpty()) {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // 2.1 获取子任务们
 | 
				
			||||||
 | 
					            String taskId = stack.pop();
 | 
				
			||||||
 | 
					            List<HistoricTaskInstance> childTaskList = filterList(tasks, task -> StrUtil.equals(task.getParentTaskId(), taskId));
 | 
				
			||||||
 | 
					            // 2.2 如果非空,则添加到 stack 进一步递归
 | 
				
			||||||
 | 
					            if (CollUtil.isNotEmpty(childTaskList)) {
 | 
				
			||||||
 | 
					                stack.addAll(convertList(childTaskList, HistoricTaskInstance::getId));
 | 
				
			||||||
 | 
					                result.addAll(childTaskList);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 获得所有子任务列表
 | 
					     * 获得所有子任务列表
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user