前言
实现思路:
处理掉当前的代办节点(也就是删除正在运行的该任务,更新维护历史数据)
跳转到目标节点,并把目标节点作为待办任务节点
任意跳转(包含单实例、多实例)
1.实现思路
处理掉当前的代办节点(也就是删除正在运行的该任务,更新维护历史数据)
跳转到目标节点,并把目标节点作为待办任务节点

要继续运转流程,则向operations中压入ContinueProcessOperation,
多实例压入planContinueMultiInstanceOperation
要结束流程则压入EndExecutionOperation。
在每一个操作完成的时候,将接下来要执行的操作压入operations栈中,这样就达到了流程运转的效果
2.任意跳转命令类
代码如下(示例):
public class JumpTaskCmd implements Command<Void>, Serializable {
/**
* 当前流程实例的待办节点
* 当多实例节点为并行时,会有多个节点
* 跳过多实例节点时,需要把它们都删除
*/
private List<String> taskIds;
/**
* 以下两个节点,targetNodeId跳过过去的节点,即将为代办任务节点
* var 是targetNodeId节点需要的参数,如:候选人、多实例完成率等等
*/
private String targetNodeId;
private Map<String, Object> vars;
public JumpMultiCmd(List<String> taskIds, String targetNodeId, Map<String, Object> vars) {
this.taskIds = taskIds;
this.targetNodeId = targetNodeId;
this.vars = vars;
}
@Override
public Void execute(CommandContext commandContext) {
//获取其中一个代办任务
String taskId = taskIds.get(0);
//任务执行管理器
TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
TaskEntity taskEntity = taskEntityManager.findById(taskId);
//流程定义对象信息
String processDefinitionId = taskEntity.getProcessDefinitionId();
Process process = ProcessDefinitionUtil.getProcess(processDefinitionId);
//节点的元信息对象,封装了节点的元数据,如入线和出线
Activity flowElement = (Activity) process.getFlowElement(taskEntity.getTaskDefinitionKey());
// 执行实例对象
String executionId = taskEntity.getExecutionId();
ExecutionEntity currentExecutionEntity = executionEntityManager.findById(executionId);
Object behavior = flowElement.getBehavior();
//判断当前节点的行为类,即是否多实例任务类型,主要做两件事,删除2级实例下的三级实例,然后重新设置2级实例的信息执行更新操作
if (behavior instanceof MultiInstanceActivityBehavior) {
HistoricTaskInstanceEntityManager historicTaskInstance = commandContext.getHistoricTaskInstanceEntityManager();
this.taskIds.forEach(historicTaskInstance::delete);
executionEntityManager.deleteChildExecutions(currentExecutionEntity, "jump task", false);
currentExecutionEntity.setActive(true);
currentExecutionEntity.setMultiInstanceRoot(false);
executionEntityManager.update(currentExecutionEntity);
} else {
//不是多实例
//删除历史任务节点
HistoricTaskInstanceEntityManager historicTaskInstance = commandContext.getHistoricTaskInstanceEntityManager();
historicTaskInstance.delete(taskId);
//删除当前的任务并把条件删掉
IdentityLinkEntityManager identityLinkEntityManager = commandContext.getIdentityLinkEntityManager();
identityLinkEntityManager.deleteIdentityLinksByTaskId(taskId);
//taskEntityManager.delete(taskId); 报外键冲突,执行前面的代码
taskEntityManager.deleteTask(taskEntity, "jumpReason", false, false);
}
//使用agenda驱动实例的继续运转,即跳入到目标节点
ActivitiEngineAgenda agenda = commandContext.getAgenda();
// 如果目标节点为结束节点(不是用户节点)
if (FLOW_NODE_EVENT_END.equals(targetNodeId)) {
FlowElement targetFlowElement = process.getFlowElement(targetNodeId);
currentExecutionEntity.setCurrentFlowElement(targetFlowElement);
agenda.planEndExecutionOperation(currentExecutionEntity);
return null;
}
// 目标节点处理
Activity targetFlowElement = (Activity) process.getFlowElement(targetNodeId);
behavior = targetFlowElement.getBehavior();
// 当目标节点为多实例节点时,需要从执行实例中获取它们父实例对象
if (behavior instanceof MultiInstanceActivityBehavior) {
//待跳出节点的二级实例对象(多实例下的执行实例对象为三级实例对象)
ExecutionEntity secondExecutionEntity = currentExecutionEntity.getParent();
secondExecutionEntity.setCurrentFlowElement(targetFlowElement);
if (!Objects.isNull(vars) && vars.size() > 0) {// 如需要提供的参数
secondExecutionEntity.setVariables(vars);
}
agenda.planContinueMultiInstanceOperation(secondExecutionEntity);
return null;
}
if (!Objects.isNull(vars) && vars.size() > 0) {
currentExecutionEntity.setVariables(vars);
}
currentExecutionEntity.setCurrentFlowElement(targetFlowElement);
agenda.planContinueProcessInCompensation(currentExecutionEntity);
return null;
}
}
如果你对工作流感兴趣,想了解更多,请点击
Java工作流管理系统(activity6.0)