珍惜当下 展望未来!

跳转到任意节点实现

跳转到任意节点实现

1.在流程运行过程中,任意跳转

需求:如下,执行到节点4的时候,我任务不符合要求,需要驳回/回退到节点1重新开始审批
节点1审批完后也可以重新指向节点4 (跳转到任意节点)

image-20220705112119484

实现思路:

  • 将所有的节点设置一个唯一的id,作为跳转的标识
  • 首先自己查询出所有执行过的节点,也就是审批节点5之前的节点列表(里面包含每个节点的唯一id/key)
    --->可以从自己的业务系统表或者从activiti的历史任务表查
  • 选择一个回退的节点,
  • 完成当前任务,并设置当前节点的流向为选择的回退节点即可,
    注意设置好并执行完回退操作后,记得把当前节点的流向恢复成原来的,不然下次进来的时候会自动扭转到回退节点(因为这里的设置针对的是流程图,而不是流程实例)**

给每个节点设置唯一的id

image-20220705105948711

回退接口实现

 /**
     * 
     * @param taskId 当前任务id
     * @param nodeId 跳转的节点id
     */
    @GetMapping("/backToEveryNode")
    @ApiOperation(value = "完成当前任务  并   跳转到任意节点")
    public void backToEveryNode(String taskId,String nodeId) {


        //当前任务信息
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();

        //获得当前流程的活动ID
        ExecutionQuery executionQuery = runtimeService.createExecutionQuery();
        Execution execution = executionQuery.executionId(task.getExecutionId()).singleResult();
        String activityId = execution.getActivityId();


        //获取当前节点和目标节点的节点信息
        FlowNode currentFlowNode = getFlowNode(task.getProcessDefinitionId(), activityId);
        FlowNode targetFlowNode = getFlowNode(task.getProcessDefinitionId(), nodeId);

        //获取当前节点的原始流出节点信息
        List<SequenceFlow> oldFlowNodeOutgoingFlows = currentFlowNode.getOutgoingFlows();


        //重新设置流出节点信息  为退回的节点
        SequenceFlow sequenceFlow = new SequenceFlow();
        sequenceFlow.setId("newTempSequenceId");
        sequenceFlow.setSourceFlowElement(currentFlowNode);
        sequenceFlow.setTargetFlowElement(targetFlowNode);//设置流出节点信息  为退回的节点
        List<SequenceFlow> newSequenceFlows = new ArrayList<>();
        newSequenceFlows.add(sequenceFlow);
        currentFlowNode.setOutgoingFlows(newSequenceFlows);

        //完成当前任务
        taskService.complete(taskId);

        //最后恢复原来的流转走向
        currentFlowNode.setOutgoingFlows(oldFlowNodeOutgoingFlows);
    }

    private FlowNode getFlowNode(String processDefinitionId, String activityId) {
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        return (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityId);
    }

2.开启实例时 ,指定跳转的节点

实现启动实例时 直接跳到node3

image-20220809165616469

原理同上

  • 1.拿到开始节点,保存原始流向
  • 2.临时修改流向为指定的节点
  • 3.开启实例
  • 4.恢复开始节点原来的流向

代码:

 /**
     * @param procDefId 流程定义id
     * @param nodeKey   节点id
     */
    @GetMapping("/commitToEveryNode")
    @ApiOperation(value = "开启实例   并提交到指定任务节点")
    public void commitToEveryNode(String procDefId, String nodeKey) {
        //流程定义id
        BpmnModel bpmnModel = repositoryService.getBpmnModel(procDefId);
        Process process = bpmnModel.getProcesses().get(0);
        //获取所有节点
        Collection<FlowElement> flowElements = process.getFlowElements();
        System.out.println(flowElements);
        //拿到开始节点
        if (CollectionUtils.isEmpty(flowElements)) {
            throw new RuntimeException("流程图有误,请检查");
        }
        Collection<FlowElement> startFlowElements = flowElements.stream().filter(bean -> bean instanceof StartEvent).collect(Collectors.toList());
        FlowNode startNode = (FlowNode) ((List<FlowElement>) startFlowElements).get(0);

        //拿到要跳转的节点
        FlowNode jumpNode = getFlowNode(procDefId, nodeKey);
        if (jumpNode == null) {
            throw new RuntimeException("要跳转的目标节点不存在");
        }

        //获取当前节点的原始流出节点信息
        List<SequenceFlow> oldFlowNodeOutgoingFlows = startNode.getOutgoingFlows();


        //临时设置开始节点的流向  为要跳转的节点
        SequenceFlow sequenceFlow = new SequenceFlow();
        sequenceFlow.setId("newTempSequenceId");
        sequenceFlow.setSourceFlowElement(startNode);
        sequenceFlow.setTargetFlowElement(jumpNode);
        List<SequenceFlow> newSequenceFlows = new ArrayList<>();
        newSequenceFlows.add(sequenceFlow);
        startNode.setOutgoingFlows(newSequenceFlows);

        //开启流程实例
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId);
        System.out.println(processInstance);

        //恢复原来的流转走向
        startNode.setOutgoingFlows(oldFlowNodeOutgoingFlows);
    }


    private FlowNode getFlowNode(String processDefinitionId, String activityId) {
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        return (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityId);
    }
posted @ 2022-07-05 11:25  嘿嘿-  阅读(568)  评论(0编辑  收藏  举报