flowable工作流 - 过滤回退节点列表

基于开源项目KonBAI / RuoYi-Flowable-Plus使用的部分功能调整。原代码可回退至任一用户任务节点,因业务需求不允许重新修改申请表单填写信息,所以在展示回退列表时,需要屏蔽掉发起申请节点(与开始节点直连的用户任务节点)。

流程图示例

回退节点列表

 /**
     * 获取所有可回退的节点
     *
     * @param bo
     * @return
     */
    @Override
    public List<UserTask> findReturnTaskList(WfTaskBo bo) {
        // 当前任务 task
        Task task = taskService.createTaskQuery().taskId(bo.getTaskId()).singleResult();
        // 获取流程定义信息
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
        // 获取所有节点信息,暂不考虑子流程情况
        Process process = repositoryService.getBpmnModel(processDefinition.getId()).getProcesses().get(0);
        Collection<FlowElement> flowElements = process.getFlowElements();
        // 获取当前任务节点元素
        UserTask source = null;
        if (flowElements != null) {
            for (FlowElement flowElement : flowElements) {
                // 类型为用户节点
                if (flowElement.getId().equals(task.getTaskDefinitionKey())) {
                    source = (UserTask) flowElement;
                }
            }
        }
		
		// old >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        // 获取节点的所有路线
        // List<List<UserTask>> roads = FlowableUtils.findRoad(source, source, null, null, null);
        // -----------------------------------------------------------
		
        // new >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        // 获取节点的所有路线:不将前一个节点是开始节点的用户任务加入回退列表
        List<List<UserTask>> roads = FlowableUtils.findRoadNew(source, source, null, null, null);
        // -----------------------------------------------------------
        
        // 可回退的节点列表
        List<UserTask> userTaskList = new ArrayList<>();
        for (List<UserTask> road : roads) {
            if (userTaskList.size() == 0) {
                // 还没有可回退节点直接添加
                userTaskList = road;
            } else {
                // 如果已有回退节点,则比对取交集部分
                userTaskList.retainAll(road);
            }
        }
        return userTaskList;
    }

寻路方法

  /**
     * 从后向前寻路,获取到达节点的所有路线
     * 不存在直接回退到子流程,但是存在回退到父级流程的情况
     * new:如果任务节点的前一个节点是开始节点,则不将当前节点加入回退列表
     * @param source 起始节点
     * @param passRoads 已经经过的点集合
     * @param hasSequenceFlow 已经经过的路线
     * @param roads 路线
     * @return
     */
    public static List<List<UserTask>> findRoadNew(FlowElement currentsource, FlowElement source, List<UserTask> passRoads, Set<String> hasSequenceFlow, List<List<UserTask>> roads) {

       passRoads = passRoads == null ? new ArrayList<>() : passRoads;
        roads = roads == null ? new ArrayList<>() : roads;
        hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;

        // 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
        if (source instanceof StartEvent && source.getSubProcess() != null) {
            roads = findRoadNew(currentsource, source.getSubProcess(), passRoads, hasSequenceFlow, roads);
        }

        // 1.查指向当前任务的连线是否存在
        // -> 1.1.存在则继续往前查找节点
        //  -> 1.1.1.是开始节点 -> 不将当前任务加入路线
        //  -> 1.1.2.是用户任务节点 -> 将当前任务加入路线
        // -> 1.2.不存在则将当前任务直接加入路线

        // 根据类型,获取入口连线
        List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
        // 如果当前节点的入口连线存在,将连线加入已记录连线列表中,且记录当前任务;若连线已存在连线列表中,则跳过当前任务
        if (sequenceFlows != null && sequenceFlows.size() != 0) {
            for (SequenceFlow sequenceFlow: sequenceFlows) {
                // 如果发现连线重复,说明循环了,跳过这个循环
                if (hasSequenceFlow.contains(sequenceFlow.getId())) {
                    continue;
                }

                // 添加已经走过的连线
                hasSequenceFlow.add(sequenceFlow.getId());
                // new >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                // 添加经过路线,当前任务1.不等于传入节点 2.属于用户任务 3.连线的上一节点不是开始节点 -> 记录当前用户任务
                if (source instanceof UserTask && currentsource != source && !(sequenceFlow.getSourceFlowElement() instanceof StartEvent)) {
                    passRoads.add((UserTask) source);
                }
				// --------------------------------------------
                // 继续找上一个节点
                roads = findRoadNew(currentsource, sequenceFlow.getSourceFlowElement(), passRoads, hasSequenceFlow, roads);

            }
        } else {
            // 如果不存在上一级连线,添加路线
            roads.add(passRoads);
        }
        return roads;
    }

参考资料:
基于 RuoYi-Vue-Plus 进行二次开发扩展Flowable工作流功能项目

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值