知识库绑定工况库,知识库搜索、审批流程展示工况库

This commit is contained in:
2025-12-10 15:14:45 +08:00
parent 5cb62925ed
commit b3219dd39d
18 changed files with 343 additions and 70 deletions

View File

@@ -165,7 +165,20 @@ public class ProcessController implements IFlowableFeignClient {
}
/**
* 用户点击"重试"按钮传入目标节点ID
* 重试任务,目前只能重试当前失败的节点
*/
@PostMapping("/retryFailedNode")
public SdmResponse retryFailedNode(@RequestParam String processInstanceId, @RequestParam String failNodeId) {
log.info("开始重试任务: {}",failNodeId);
try {
processService.retryFailedNode(processInstanceId, failNodeId);
return SdmResponse.success("重试任务已提交");
} catch (Exception e) {
return SdmResponse.failed("重试失败");
}
}
/**
* 用户点击"重试"按钮传入目标节点ID ,可以从任意节点重试
*
* @param request 重试请求参数包括流程实例ID、目标节点ID和新变量
* @return 重试结果

View File

@@ -16,8 +16,10 @@ import com.sdm.flowable.service.IProcessNodeParamService;
import com.sdm.flowable.util.Dto2BpmnConverter;
import com.sdm.flowable.util.FlowNodeIdUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
@@ -203,6 +205,8 @@ public class ProcessService {
List<Execution> executions = runtimeService.createExecutionQuery()
.processInstanceId(processInstanceId).list();
Map<String, String> executionToActivityMap = executions.stream()
// 【关键】过滤掉 activityId 为 null 的记录根执行实例Root Execution代表流程实例本身的那条记录它的 activityId 通常是 null
.filter(e -> e.getActivityId() != null)
.collect(Collectors.toMap(Execution::getId, Execution::getActivityId, (v1, v2) -> v1));
// 填充错误 Map
@@ -509,6 +513,57 @@ public class ProcessService {
universalDelegate.signalByTaskId(request);
log.info("异步回调处理转发完成, 任务ID: {}", request.getAsyncTaskId());
}
/**
* 查找特定节点的死信作业ID用于后续重试操作。
* @param processInstanceId 流程实例ID
* @param activityId 节点ID
* @return
*/
private String findDeadJobId(String processInstanceId, String activityId) {
// 1. 先查出该实例下所有的死信作业 (通常不会很多)
List<Job> deadJobs = managementService.createDeadLetterJobQuery()
.processInstanceId(processInstanceId)
.list();
if (deadJobs.isEmpty()) {
throw new RuntimeException("未找到任何死信作业,请确认流程是否已结束或任务处于重试等待中");
}
// 2. 查出该实例下所有的 Execution (为了获取 ActivityId 映射)
// 这样只需要查 2 次数据库,而不是 N+1 次
List<Execution> executions = runtimeService.createExecutionQuery()
.processInstanceId(processInstanceId)
.list();
// 3. 构建 ExecutionId -> ActivityId 的映射
Map<String, String> execActivityMap = executions.stream()
.filter(e -> e.getActivityId() != null)
.collect(Collectors.toMap(Execution::getId, Execution::getActivityId, (v1, v2) -> v1));
// 4. 在内存中匹配找到对应的 Job
return deadJobs.stream()
.filter(job -> {
String actId = execActivityMap.get(job.getExecutionId());
return activityId.equals(actId);
})
.findFirst()
.map(Job::getId)
.orElseThrow(() -> new RuntimeException("在死信队列中未找到节点 [" + activityId + "] 的作业"));
}
public void retryFailedNode( String processInstanceId,String failNodeId) {
try {
// 2. 查找 Job ID (参考上面的代码)
String jobId = findDeadJobId(processInstanceId, failNodeId);
// 3. 执行重试
managementService.moveDeadLetterJobToExecutableJob(jobId, 3);
log.info("作业已恢复,等待异步执行器拾取执行...");
} catch (Exception e) {
log.error("重试节点失败, 流程ID: {}, 节点ID: {}, 异常信息: {}", processInstanceId, failNodeId, e.getMessage(), e);
throw new RuntimeException("重试失败");
}
}
/**
* 用户点击"重试"按钮传入目标节点ID