流程状态优化

This commit is contained in:
2025-12-11 20:22:54 +08:00
parent 223d118e0b
commit 79d311354c
5 changed files with 40 additions and 37 deletions

View File

@@ -274,65 +274,66 @@ public class ProcessService implements Iprocess{
.processInstanceId(processInstanceId)
.list();
Map<String, HistoricActivityInstance> activityMap = new HashMap<>();
Map<String, HistoricActivityInstance> historicActivityInstanceHashMap = new HashMap<>();
for (HistoricActivityInstance hist : historicActivities) {
if (!activityMap.containsKey(hist.getActivityId()) ||
hist.getStartTime().after(activityMap.get(hist.getActivityId()).getStartTime())) {
activityMap.put(hist.getActivityId(), hist);
if (!historicActivityInstanceHashMap.containsKey(hist.getActivityId()) ||
hist.getStartTime().after(historicActivityInstanceHashMap.get(hist.getActivityId()).getStartTime())) {
historicActivityInstanceHashMap.put(hist.getActivityId(), hist);
}
}
// 3. 准备运行时 Active ID 列表
// 注意重试中的任务Active Job一定包含在这里面所以它会被标记为 isActive = true
List<String> activeActivityIds = isRunning
? runtimeService.getActiveActivityIds(processInstanceId)
: Collections.emptyList();
// 4. 准备异常信息 (DeadLetterJob 代表严重错误/失败)
// 4. 准备异常信息 (仅关注 DeadLetterJob - 彻底失败的任务)
Map<String, String> errorMap = new HashMap<>();
boolean hasDeadLetterJobs = false; // 标记流程是否有死信
boolean hasDeadLetterJobs = false;
if (isRunning) {
// 死信作业 (DeadLetterJob) - 彻底失败
// 只查死信作业
List<Job> deadJobs = managementService.createDeadLetterJobQuery()
.processInstanceId(processInstanceId).list();
if (!deadJobs.isEmpty()) {
hasDeadLetterJobs = true;
}
// 普通作业 (Job) - 包含重试中的异常
List<Job> activeJobs = managementService.createJobQuery()
.processInstanceId(processInstanceId).list();
// 【优化】:只有存在死信时,才去查 Execution 映射 ActivityId
// 这样重试中的流程(无死信)可以少查一次数据库
List<Execution> executions = runtimeService.createExecutionQuery()
.processInstanceId(processInstanceId).list();
Map<String, String> executionToActivityMap = executions.stream()
.filter(e -> e.getActivityId() != null)
.collect(Collectors.toMap(Execution::getId, Execution::getActivityId, (v1, v2) -> v1));
// 映射 ExecutionId -> ActivityId
List<Execution> executions = runtimeService.createExecutionQuery()
.processInstanceId(processInstanceId).list();
Map<String, String> executionToActivityMap = executions.stream()
.filter(e -> e.getActivityId() != null)
.collect(Collectors.toMap(Execution::getId, Execution::getActivityId, (v1, v2) -> v1));
Consumer<Job> mapJobToError = job -> {
if (job.getExceptionMessage() != null) {
String activityId = executionToActivityMap.get(job.getExecutionId());
if (activityId != null) {
errorMap.put(activityId, job.getExceptionMessage());
for (Job job : deadJobs) {
if (job.getExceptionMessage() != null) {
String activityId = executionToActivityMap.get(job.getExecutionId());
if (activityId != null) {
errorMap.put(activityId, job.getExceptionMessage());
}
}
}
};
deadJobs.forEach(mapJobToError);
activeJobs.forEach(mapJobToError);
}
// 【已移除】:原有的 createJobQuery (activeJobs) 查询逻辑。
// 解释:重试中的任务虽然带有异常信息,但在业务逻辑上视为“正在执行(Active)”,不视为“错误(Error)”。
}
// --- 5. 构建流程实例级状态 (ProcessInfo) ---
// 这里传入新的状态标志:hasDeadLetterJobs, isProcessSuspended
// 只要 hasDeadLetterJobs 为 false流程状态就会显示为 running (或 suspended)
processInfo = buildProcessInstanceInfo(processInstanceId, isRunning, isProcessSuspended, hasDeadLetterJobs);
// --- 6. 构建节点级状态 ---
for (NodeDetailInfo node : nodes) {
String originalNodeId = node.getId();
HistoricActivityInstance myHist = activityMap.get(originalNodeId);
HistoricActivityInstance myHist = historicActivityInstanceHashMap.get(originalNodeId);
boolean isActive = activeActivityIds.contains(originalNodeId);
boolean isFinished = myHist != null && myHist.getEndTime() != null;
// 只有死信表里的才算 Error
String errorMessage = errorMap.get(originalNodeId);
boolean isError = errorMessage != null;
@@ -340,9 +341,10 @@ public class ProcessService implements Iprocess{
String displayStatus;
if (isError) {
displayStatus = "error"; // 节点报错优先
displayStatus = "error"; // 彻底挂死:红色
} else if (isActive) {
// 【优化点】:如果节点是 Active但流程是 Suspended则节点状态为 suspended
// 如果是重试任务isError=false, isActive=true -> 进入这里 -> 显示为 Active (蓝色)
// 同时兼容挂起状态显示
if (isProcessSuspended) {
displayStatus = "suspended";
} else {
@@ -358,18 +360,18 @@ public class ProcessService implements Iprocess{
Date endTime = myHist != null ? myHist.getEndTime() : null;
Long duration = myHist != null ? myHist.getDurationInMillis() : null;
// ServiceTask 异步回调逻辑特殊处理 (保持原有逻辑,叠加挂起判断)
// ServiceTask 异步回调逻辑特殊处理
if (isAsyncCallbackNode(node)) {
if (isError) {
node.setErrorMessage(errorMessage);
} else {
String waitNodeId = FlowNodeIdUtils.generateAsyncTaskId(originalNodeId);
HistoricActivityInstance waitHist = activityMap.get(waitNodeId);
HistoricActivityInstance waitHist = historicActivityInstanceHashMap.get(waitNodeId);
boolean waitIsActive = activeActivityIds.contains(waitNodeId);
boolean waitIsFinished = waitHist != null && waitHist.getEndTime() != null;
if (waitIsActive) {
// 同样:如果 ReceiveTask 等待中,但流程挂起,显示挂起
// 等待回调中,同样受挂起状态影响
displayStatus = isProcessSuspended ? "suspended" : "active";
endTime = null;
if (startTime != null) {
@@ -382,6 +384,7 @@ public class ProcessService implements Iprocess{
duration = endTime.getTime() - startTime.getTime();
}
} else if (isFinished && !waitIsFinished && !waitIsActive) {
// 刚发完 ServiceTask还没生成 ReceiveTask 的中间态
displayStatus = isProcessSuspended ? "suspended" : "active";
endTime = null;
}