fix:支持任意节点开始执行
This commit is contained in:
@@ -119,14 +119,23 @@ public class ProcessController implements IFlowableFeignClient {
|
||||
* 根据流程定义ID启动流程实例
|
||||
*
|
||||
* @param processDefinitionId 流程定义ID(指定版本)
|
||||
* @param targetNodeId 可选,指定从该节点启动(内部会智能修正到真实入口节点)
|
||||
* @param variables 可选的流程启动变量
|
||||
*/
|
||||
@PostMapping("/startByProcessDefinitionId")
|
||||
public SdmResponse startByProcessDefinitionId(
|
||||
@RequestParam String processDefinitionId,
|
||||
@RequestParam(required = false) String targetNodeId,
|
||||
@RequestBody(required = false) Map<String, Object> variables) {
|
||||
log.info("开始启动流程定义: {}",processDefinitionId);
|
||||
ProcessInstance processInstance = processService.startByProcessDefinitionId(processDefinitionId, variables);
|
||||
log.info("开始启动流程定义: {}, targetNodeId: {}", processDefinitionId, targetNodeId);
|
||||
|
||||
ProcessInstance processInstance;
|
||||
if (targetNodeId != null && !targetNodeId.isBlank()) {
|
||||
processInstance = processService.startProcessAtNode(processDefinitionId, targetNodeId, variables);
|
||||
} else {
|
||||
processInstance = processService.startByProcessDefinitionId(processDefinitionId, variables);
|
||||
}
|
||||
|
||||
ProcessInstanceResp processInstanceResp = new ProcessInstanceResp();
|
||||
processInstanceResp.setProcessInstanceId(processInstance.getId());
|
||||
processInstanceResp.setProcessDefinitionId(processInstance.getProcessDefinitionId());
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.flowable.validation.ProcessValidatorFactory;
|
||||
import org.flowable.validation.ValidationError;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
@@ -149,14 +150,71 @@ public class ProcessService implements Iprocess{
|
||||
if (variables == null) {
|
||||
variables = Collections.emptyMap();
|
||||
}
|
||||
|
||||
|
||||
log.info("根据流程定义ID启动流程实例, 流程定义ID: {}, 变量数量: {}", processDefinitionId, variables.size());
|
||||
|
||||
ProcessInstance instance = runtimeService.startProcessInstanceById(processDefinitionId, variables);
|
||||
|
||||
log.info("流程实例启动成功, 实例ID: {}, 流程定义ID: {}, 业务Key: {}",
|
||||
instance.getId(), instance.getProcessDefinitionId(), instance.getBusinessKey());
|
||||
|
||||
|
||||
log.info("流程实例启动成功, 实例ID: {}, 流程定义ID: {}, 业务Key: {}",
|
||||
instance.getId(), instance.getProcessDefinitionId(), instance.getBusinessKey());
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从任意节点启动流程(利用 StartEvent 异步特性,在同事务内启动 + 跳转)
|
||||
*
|
||||
* @param processDefinitionId 流程定义ID
|
||||
* @param targetNodeId 目标节点ID(可传原始节点ID或复合节点ID)
|
||||
* @param variables 流程变量
|
||||
* @return 启动后的流程实例
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ProcessInstance startProcessAtNode(String processDefinitionId, String targetNodeId, Map<String, Object> variables) {
|
||||
log.info("开始从指定节点启动流程. 流程定义: {}, 目标节点: {}", processDefinitionId, targetNodeId);
|
||||
|
||||
// 1. 获取 BPMN 模型
|
||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
|
||||
if (bpmnModel == null || bpmnModel.getMainProcess() == null) {
|
||||
throw new RuntimeException("流程定义不存在: " + processDefinitionId);
|
||||
}
|
||||
|
||||
// 2. 找 StartEvent
|
||||
StartEvent startEvent = bpmnModel.getMainProcess().findFlowElementsOfType(StartEvent.class).stream()
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new RuntimeException("流程模型中缺少 StartEvent"));
|
||||
String startEventId = startEvent.getId();
|
||||
|
||||
// 3. 智能修正目标节点(复用现有复合节点规则)
|
||||
String realTargetNodeId = targetNodeId;
|
||||
String originalNodeId = FlowNodeIdUtils.parseOriginalNodeId(targetNodeId);
|
||||
|
||||
String registerNodeId = FlowNodeIdUtils.generateRegisterTaskId(originalNodeId);
|
||||
String waitUserNodeId = FlowNodeIdUtils.generateWaitUserTaskId(originalNodeId);
|
||||
|
||||
if (bpmnModel.getMainProcess().getFlowElement(registerNodeId) != null) {
|
||||
realTargetNodeId = registerNodeId;
|
||||
} else if (bpmnModel.getMainProcess().getFlowElement(waitUserNodeId) != null) {
|
||||
realTargetNodeId = waitUserNodeId;
|
||||
} else if (bpmnModel.getMainProcess().getFlowElement(realTargetNodeId) == null) {
|
||||
throw new RuntimeException("目标节点不存在: " + targetNodeId);
|
||||
}
|
||||
|
||||
log.info("原始目标节点: {}, 智能修正后的真实入口: {}", targetNodeId, realTargetNodeId);
|
||||
|
||||
// 4. 启动流程(StartEvent 异步,流程会先停在 StartEvent)
|
||||
if (variables == null) {
|
||||
variables = new HashMap<>();
|
||||
}
|
||||
ProcessInstance instance = runtimeService.startProcessInstanceById(processDefinitionId, variables);
|
||||
|
||||
// 5. 同事务内立刻跳转到目标节点
|
||||
runtimeService.createChangeActivityStateBuilder()
|
||||
.processInstanceId(instance.getId())
|
||||
.moveActivityIdTo(startEventId, realTargetNodeId)
|
||||
.changeState();
|
||||
|
||||
log.info("流程已成功从节点 [{}] 启动,实例ID: {}", realTargetNodeId, instance.getId());
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user