欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

activity任意节点跳转

程序员文章站 2022-05-14 13:57:19
...

前言

在实际业务中,总会碰到一些特殊的需求,比如要实现任意两个审批节点之间的跳转,举例来说,某个审批流程有3级审批,来了这么个需求,一级审批完结之后在满足特定的条件下,可以直接进入到3级审批,即跳过中间的二级审批,所幸activity提供了这样的解决方案

本例我们用代码简单演示一下其实现流程

1、定义流程文件
activity任意节点跳转

2、部署与启动流程实例

	//部署
    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deployment =
                repositoryService.createDeployment().addClasspathResource("process/demo/jump.bpmn").name("jump").deploy();
        System.out.println(deployment.getId());
        System.out.println(deployment.getName());
    }

    //启动流程
    public static void main(String[] args) {
        String key = "jump1";
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        runtimeService.startProcessInstanceByKey(key);
    }

启动完毕后,在任务表产生一条数据
activity任意节点跳转

在编写代码之前,我们简单理一下思路,我们知道,流程在运转过程中,其实就是一个个执行实例在运转,具体来说,就是每个节点上的任务在执行,这一点大家可以重点关注任务表和执行动作表,即ACT_RU_TASK和ACT_RU_EXECUTION表

再进一步,每个节点本身有唯一的ID,即activityId,每个执行实例有自己的执行动作ID,即executionId,然后每个节点对应的任务有唯一的taskID,可以想象每个节点就是一个独立的运转对象,封装了和当前节点相关的所有参数,那么在审批节点流转过程中都可以拿到

拿到了这些信息,比如知道了当前节点的activityId和要跳转的activityID,以及正在执行的任务实例,是否可以通过activity提供的相关API完成节点跳转了呢?

说到这儿,基本上思路就出来了,在activity中,某个类通过实现Command接口,重写里面的execute方法,就可以帮助我们完成这一看似不可思议的功能,下面就按照这个思路来构造这个跳转的执行方法

3、跳转节点的执行类

public class JumpTestCmd implements Command<Void> {

    private String taskId;  //当前任务ID
    private String targetNodeId;    //跳转的目标节点ID

    public JumpTestCmd(String taskId, String targetNodeId) {
        this.taskId = taskId;
        this.targetNodeId = targetNodeId;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        ActivitiEngineAgenda contextAgenda = commandContext.getAgenda();
        TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
        TaskEntity taskEntity = taskEntityManager.findById(taskId);
        //执行实例ID
        String executionId = taskEntity.getExecutionId();
        //流程定义ID
        String processDefinitionId = taskEntity.getProcessDefinitionId();
        ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();

        //获取到执行实例对象,当前节点 【流程实例在执行过程中,一定是执行实例在运转,多实例情况下,指代的是三级执行实例】
        ExecutionEntity executionEntity = executionEntityManager.findById(executionId);
        //通过流程部署的ID获取整个流程对象
        Process process = ProcessDefinitionUtil.getProcess(processDefinitionId);
        HistoryManager historyManager = commandContext.getHistoryManager();

        //有了流程对象,可以获取到各个节点
        FlowElement flowElement = process.getFlowElement(targetNodeId);
        if (flowElement == null) {
            throw new RuntimeException("target flow not exist !");
        }
        //todo 更新历史活动表 调整了顺序,在节点实例进行跳转之前记录一下历史活动表的数据
        historyManager.recordActivityEnd(executionEntity,"do-jump");
        executionEntity.setCurrentFlowElement(flowElement);
        //使用contextAgenda让执行实例进行跳转
        contextAgenda.planContinueProcessInCompensation(executionEntity);
        //流程节点实例跳转之后,应该删除掉当前的任务
        taskEntityManager.delete(taskId);
        //更新历史任务表
        historyManager.recordTaskEnd(taskId,"do-jump");
        return null;
    }
}

我们在理解这段代码的时候,需要加深对commandContext这个对象的理解,还记得在spring框架中是怎么动态获取一个bean的实例吗?可以做类似的比较

4、执行自定义任务跳转

执行下面的代码,将当前第一个节点的任务跳转到总经理审批

	public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //传入两个参数 ,任务ID以及目标节点ID
        String targetNodeId = "step3";
        String taskId = "2505";
        processEngine.getManagementService().executeCommand(new JumpTestCmd(taskId,targetNodeId));
    }

这时候,我们再观察任务表数据,发现任务节点已经跳转到了总经理审批
activity任意节点跳转

那么是否能够正常完成审批呢?

5、完成审批任务

	public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String taskId = "5002";
        processEngine.getTaskService().complete(taskId);
    }

运行上面的代码,再去观察任务表,发现数据已经清空
activity任意节点跳转
是否完成流程审批,我们可以观察历史任务执行实例表ACT_HI_ACTINST
activity任意节点跳转

通过这个表,我们可以清楚的看到任务执行过程中经历的每个环节步骤,明显跳过了中间的审批节点,即达到了我们预期的目的。这里提一点,在流程未完结之前,我们还可以从本节点再往回跳转,参数只要写对即可,有兴趣的同学可以继续探究。

本篇简单演示了使用activity进行不同节点之间的跳转,当然这里的跳转其实是单实例情况下的跳转,在实际运用中,经常还会涉及到多实例和单实例等不同节点间的跳转情况,在后续我们将会逐步介绍,最后感谢观看!