Flowable6.6-从任意节点启动 | 字痕随行
中国式流程有一些很变态的需求,比如流程重启。
我能想到流程重启的三种方式如下:
- 调用startProcessInstanceByKey重新执行一遍流程。
- 调用startProcessInstanceByKey重新启动流程,使用节点自由跳转的方式跳转到指定的UserTask。
- 自定义Cmd,直接从指定的UserTask启动。
需要说明的是,这三种方式在与用户交互时,都需要通过businessKey进行个性化处理。
前两种方式的实现在之前的示例中都有所介绍,本篇主要介绍一下第三种方式。
如果注意过BpmnModel里面的Process,就会发现Process有一个属性:initialFlowElement。
去看一下startProcessInstanceByKey的代码,会发现:
// Create the first execution that will visit all the process definition elements
ExecutionEntity execution = processEngineConfiguration.getExecutionEntityManager().createChildExecution(processInstance);
execution.setCurrentFlowElement(startInstanceBeforeContext.getInitialFlowElement());
这代码挺清晰的,设置了流程执行实例的当前节点元素。后面就会调用planContinueProcessOperation向下继续执行该节点的Behavior了。
所以,只需要定义一个Cmd就行了,只要这个Cmd里面能够改变initialFlowElement。
public class CustomRestartProcessCmd extends StartProcessInstanceCmd<ProcessInstance> {
ProcessInstanceHelper processInstanceHelper;
//从哪个节点开始启动
FlowElement restartFlowElement;
public CustomRestartProcessCmd(String processDefinitionKey, String processDefinitionId, String businessKey, Map<String, Object> variables) {
super(processDefinitionKey, processDefinitionId, businessKey, variables);
}
@Override
public ProcessInstance execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
processInstanceHelper = processEngineConfiguration.getProcessInstanceHelper();
ProcessDefinition processDefinition = getProcessDefinition(processEngineConfiguration, commandContext);
Process process = ProcessDefinitionUtil.getProcess(processDefinition.getId());
ProcessInstance processInstance = processInstanceHelper.createAndStartProcessInstanceWithInitialFlowElement(
processDefinition,
businessKey,
businessStatus,
processInstanceName,
restartFlowElement,
process,
variables,
transientVariables,
true);
return processInstance;
}
public FlowElement getRestartFlowElement() {
return restartFlowElement;
}
public void setRestartFlowElement(FlowElement restartFlowElement) {
this.restartFlowElement = restartFlowElement;
}
}
最后,测试的代码如下:
@RequestMapping(value = "restart/{id}")
@ResponseBody
public void restartProcess(@PathVariable("id") String id) {
HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery().activityInstanceId(id).singleResult();
BpmnModel bpmnModel = repositoryService.getBpmnModel(historicActivityInstance.getProcessDefinitionId());
FlowElement flowElement = bpmnModel.getFlowElement(historicActivityInstance.getActivityId());
CustomRestartProcessCmd cmd = new CustomRestartProcessCmd(
null,
historicActivityInstance.getProcessDefinitionId(),
UUID.randomUUID().toString(),
new HashMap<>()
);
cmd.setRestartFlowElement(flowElement);
managementService.executeCommand(cmd);
}
以上代码,我简单的测试了一下:
- 可以从任意UserTask启动。
- 可以从任意SubProcess启动(它会触发子流程内的StartEvent,然后流转到UserTask停住)。
以上,如果有错误,欢迎探讨和指正。
觉的不错?可以关注我的公众号↑↑↑