服务热线
135-6963-3175
工作流引擎之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)); }
上述跳转命令类的缺陷
只适用于常规节点的跳转,不支持分支节点的跳转、多实例节点的跳转以及并行节点的跳转。
流程实例和执行实例架构图:
flowableEngineAgenda.planContinueProcessInCompensation(executionEntity);
当前节点是普通节点
executionEntity:指的是执行实例(左图)
当前节点是多实例节点
executionEntity:指的是执行实例(执行实例1、执行实例2、执行实例3的父执行实例)(右图)
flowableEngineAgenda.planContinueProcessInCompensation(executionEntity);