fix:优化流程节点重试接口实体类封装,重试逻辑改成从头重试,不再原地重试

This commit is contained in:
2026-01-27 17:28:57 +08:00
parent db3e389bf5
commit 3bbda4a43e

View File

@@ -1145,9 +1145,7 @@ public class ProcessService implements Iprocess{
public SdmResponse retryFailedNode( String processInstanceId,String failNodeId) {
try {
// 2. 查找 Job ID (参考上面的代码)
String jobId = findDeadJobId(processInstanceId, failNodeId);
// 3. 执行重试
managementService.moveDeadLetterJobToExecutableJob(jobId, 1);
log.info("作业已恢复,等待异步执行器拾取执行...");
return SdmResponse.success("重试任务已提交");
@@ -1160,33 +1158,70 @@ public class ProcessService implements Iprocess{
/**
* 任意节点跳转重试 (Rewind/Jump)
* 场景:节点失败(进死信)后,用户修改参数,跳转回任意前置节点重新跑。
* 支持智能修正目标节点如果是本地应用Local App链路自动跳转回注册节点。
*
* @param procInstId 流程实例ID
* @param targetNodeId 目标逻辑节点ID (用户想跳去哪里,如 "TaskA")
* @param newVariables 新的参数
*/
public SdmResponse retryToNode(String procInstId, String targetNodeId, Map<String, Object> newVariables) {
log.info("开始执行回退重试 (Rewind), 流程: {}, 目标: {}", procInstId, targetNodeId);
log.info("开始执行回退重试 (Rewind), 流程: {}, 原始目标: {}", procInstId, targetNodeId);
// 0. 智能修正目标节点 (针对 Local App 链路)
// 获取流程定义模型
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(procInstId)
.singleResult();
if (processInstance == null) {
return SdmResponse.failed("流程实例不存在或已结束");
}
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
if (bpmnModel != null) {
// 尝试解析原始节点ID (去除 _check, _wait 等后缀)
String originalNodeId = FlowNodeIdUtils.parseOriginalNodeId(targetNodeId);
// 推测是否存在对应的注册节点 (Local App 特征)
String registerNodeId = FlowNodeIdUtils.generateRegisterTaskId(originalNodeId);
// 如果注册节点存在,说明这是 Local App 链路,且必须从注册节点重新开始
// 避免直接跳到中间状态 (如 check 或 wait),导致本地应用没拉起来
if (bpmnModel.getMainProcess().getFlowElement(registerNodeId) != null) {
if (!registerNodeId.equals(targetNodeId)) {
log.info("检测到 Local App 链路,自动修正重试目标: {} -> {}", targetNodeId, registerNodeId);
targetNodeId = registerNodeId;
}
}
}
// 1. 获取当前流程实例中 **所有** 活跃/停滞的节点
// 包含正在运行的、报错进死信的、UserTask等待中的
// 为什么要全拿?防止并行分支回退时产生幽灵分支。
List<String> allActiveActivityIds = getFailedActivityIds(procInstId);
// 如果没有找到死信节点,尝试获取当前活跃节点 (可能是 UserTask 等待中,或者正常的运行中节点)
if (allActiveActivityIds.isEmpty()) {
allActiveActivityIds = runtimeService.createExecutionQuery()
.processInstanceId(procInstId)
.list()
.stream()
.map(Execution::getActivityId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
}
if (allActiveActivityIds.isEmpty()) {
return SdmResponse.failed("当前流程已结束或状态异常,无法执行跳转");
}
log.info("当前活跃节点集合: {},将全部收束至目标: {}", allActiveActivityIds, targetNodeId);
log.info("当前活跃/失败节点集合: {},将全部收束至目标: {}", allActiveActivityIds, targetNodeId);
// 2. 更新流程变量
if (newVariables != null && !newVariables.isEmpty()) {
runtimeService.setVariables(procInstId, newVariables);
}
// 3. 净室清理 (已移除,由 Delegate/Listener 自动处理)
// 4. 执行全量跳转
// 3. 执行全量跳转
try {
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(procInstId)