前言
實作思路:
處理掉目前的代辦節點(也就是删除正在運作的該任務,更新維護曆史資料)
跳轉到目标節點,并把目标節點作為待辦任務節點
任意跳轉(包含單執行個體、多執行個體)
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)