技术交流28群

服务热线

135-6963-3175

微信服务号

activiti之中国流程任意跳转 更新时间 2016-5-28 浏览2226次

工作流引擎之activiti6流程节点自由跳转实现

在中国式的流程需求中,诸如驳回,退回功能需要进行流程跳转,比如领导审批不通过,退回到申请人。这种中国式的流程需求,可以通过以下三种方式实现

1、通过流程图设计,新增一条驳回连接线,并在连接中配置一些条件进行跳转。通常业务口更希望不需要再额外添加连接线就能实现跳转。


2、动态修改流程定义环节的连线,然后执行跳转,完成后再恢复流程定义。 这种方法可以实现动态跳转,不需要修改Activiti自身执行,但是会动态修改系统中的流程定义缓存对象。理论上这会出现一个多线程下,全局变量不安全的问题。单个Activiti流程引擎中,流程定义缓存对象是被所有线程共用的,当一个应用服务器同时收到两个不同流程实例、同个流程定义、同个环节的任务提交请求。a要求驳回,所以该线程动态修改了流程定义;与此同时,b要求正常流转,但是执行过程中,依据的流程定义已被修改,可能导致b也走向了驳回。


activiti6实现节点自由跳转

1、通过直接操作数据库进行修改,这种方法不推荐,容易出错。 2、通过自定义的command进行实现org.activiti.engine.impl.interceptor.Command接口

通过自定义的command进行实现

@Override
    public Void execute(CommandContext commandContext) {
        System.out.println("跳转到目标流程节点:" + targetFlowNodeId);
        ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
        TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
        // 获取当前任务的来源任务及来源节点信息
        TaskEntity taskEntity = taskEntityManager.findById(curTaskId);
        ExecutionEntity executionEntity = executionEntityManager.findById(taskEntity.getExecutionId());
        Process process = ProcessDefinitionUtil.getProcess(executionEntity.getProcessDefinitionId());
        // 删除当前节点
        taskEntityManager.deleteTask(taskEntity, "", true, true);
        // 获取要跳转的目标节点
        FlowElement targetFlowElement = process.getFlowElement(targetFlowNodeId);
        executionEntity.setCurrentFlowElement(targetFlowElement);
        ActivitiEngineAgenda agenda = commandContext.getAgenda();
        agenda.planContinueProcessInCompensation(executionEntity);
        return null;
    }
/**
     * 跳转到指定流程节点
     * 
     * @param curTaskId
     * @param targetFlowNodeId
     *            指定的流程节点ID 比如跳转<endEvent id="endevent1" name="End"></endEvent> ,则targetFlowNodeId为endevent1
     */
    public static void jump2TargetFlowNode(String curTaskId, String targetFlowNodeId) {
        managementService.executeCommand(new Jump2TargetFlowNodeCommand(curTaskId, targetFlowNodeId));
    }

上述跳转命令类的缺陷

只适用于常规节点的跳转,不支持分支节点的跳转、多实例节点的跳转以及并行节点的跳转。


流程实例和执行实例架构图:

1643205426401.png

flowableEngineAgenda.planContinueProcessInCompensation(executionEntity);

当前节点是普通节点

executionEntity:指的是执行实例(左图)

当前节点是多实例节点

executionEntity:指的是执行实例(执行实例1、执行实例2、执行实例3的父执行实例)(右图)

flowableEngineAgenda.planContinueProcessInCompensation(executionEntity);