fix:优化流程节点重试接口实体类封装,重试逻辑改成从头重试,不再原地重试
This commit is contained in:
@@ -1145,9 +1145,7 @@ public class ProcessService implements Iprocess{
|
|||||||
|
|
||||||
public SdmResponse retryFailedNode( String processInstanceId,String failNodeId) {
|
public SdmResponse retryFailedNode( String processInstanceId,String failNodeId) {
|
||||||
try {
|
try {
|
||||||
// 2. 查找 Job ID (参考上面的代码)
|
|
||||||
String jobId = findDeadJobId(processInstanceId, failNodeId);
|
String jobId = findDeadJobId(processInstanceId, failNodeId);
|
||||||
// 3. 执行重试
|
|
||||||
managementService.moveDeadLetterJobToExecutableJob(jobId, 1);
|
managementService.moveDeadLetterJobToExecutableJob(jobId, 1);
|
||||||
log.info("作业已恢复,等待异步执行器拾取执行...");
|
log.info("作业已恢复,等待异步执行器拾取执行...");
|
||||||
return SdmResponse.success("重试任务已提交");
|
return SdmResponse.success("重试任务已提交");
|
||||||
@@ -1160,33 +1158,70 @@ public class ProcessService implements Iprocess{
|
|||||||
/**
|
/**
|
||||||
* 任意节点跳转重试 (Rewind/Jump)
|
* 任意节点跳转重试 (Rewind/Jump)
|
||||||
* 场景:节点失败(进死信)后,用户修改参数,跳转回任意前置节点重新跑。
|
* 场景:节点失败(进死信)后,用户修改参数,跳转回任意前置节点重新跑。
|
||||||
|
* 支持智能修正目标节点:如果是本地应用(Local App)链路,自动跳转回注册节点。
|
||||||
*
|
*
|
||||||
* @param procInstId 流程实例ID
|
* @param procInstId 流程实例ID
|
||||||
* @param targetNodeId 目标逻辑节点ID (用户想跳去哪里,如 "TaskA")
|
* @param targetNodeId 目标逻辑节点ID (用户想跳去哪里,如 "TaskA")
|
||||||
* @param newVariables 新的参数
|
* @param newVariables 新的参数
|
||||||
*/
|
*/
|
||||||
public SdmResponse retryToNode(String procInstId, String targetNodeId, Map<String, Object> 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. 获取当前流程实例中 **所有** 活跃/停滞的节点
|
// 1. 获取当前流程实例中 **所有** 活跃/停滞的节点
|
||||||
// 包含:正在运行的、报错进死信的、UserTask等待中的
|
// 包含:正在运行的、报错进死信的、UserTask等待中的
|
||||||
// 为什么要全拿?防止并行分支回退时产生幽灵分支。
|
// 为什么要全拿?防止并行分支回退时产生幽灵分支。
|
||||||
List<String> allActiveActivityIds = getFailedActivityIds(procInstId);
|
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()) {
|
if (allActiveActivityIds.isEmpty()) {
|
||||||
return SdmResponse.failed("当前流程已结束或状态异常,无法执行跳转");
|
return SdmResponse.failed("当前流程已结束或状态异常,无法执行跳转");
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("当前活跃节点集合: {},将全部收束至目标: {}", allActiveActivityIds, targetNodeId);
|
log.info("当前活跃/失败节点集合: {},将全部收束至目标: {}", allActiveActivityIds, targetNodeId);
|
||||||
|
|
||||||
// 2. 更新流程变量
|
// 2. 更新流程变量
|
||||||
if (newVariables != null && !newVariables.isEmpty()) {
|
if (newVariables != null && !newVariables.isEmpty()) {
|
||||||
runtimeService.setVariables(procInstId, newVariables);
|
runtimeService.setVariables(procInstId, newVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 净室清理 (已移除,由 Delegate/Listener 自动处理)
|
// 3. 执行全量跳转
|
||||||
|
|
||||||
// 4. 执行全量跳转
|
|
||||||
try {
|
try {
|
||||||
runtimeService.createChangeActivityStateBuilder()
|
runtimeService.createChangeActivityStateBuilder()
|
||||||
.processInstanceId(procInstId)
|
.processInstanceId(procInstId)
|
||||||
|
|||||||
Reference in New Issue
Block a user