流程状态优化

This commit is contained in:
2025-12-11 20:56:05 +08:00
parent cd5b4c0b69
commit 82fc6c6968
5 changed files with 121 additions and 30 deletions

View File

@@ -184,6 +184,7 @@ public class ExportWordScriptHandler implements ExecutionHandler<Map<String, Obj
UploadFilesReq req = new UploadFilesReq();
req.setDirId(currentNodeOutputDirId);
req.setFile(multipartFile);
log.info("上传文件参数:{}", req);
// 调用上传文件的方法
// 注意:这里应该处理返回值
dataFeignClient.uploadFiles(req);

View File

@@ -0,0 +1,41 @@
package com.sdm.flowable.enums;
/**
* 节点状态枚举
*/
public enum NodeStateEnum {
/**
* 等待中
*/
PENDING("pending"),
/**
* 活动中
*/
ACTIVE("active"),
/**
* 挂起
*/
SUSPENDED("suspended"),
/**
* 错误
*/
ERROR("error"),
/**
* 已完成
*/
FINISHED("finished");
private final String code;
NodeStateEnum(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}

View File

@@ -0,0 +1,41 @@
package com.sdm.flowable.enums;
/**
* 流程实例状态枚举
*/
public enum ProcessInstanceStateEnum {
/**
* 运行中
*/
RUNNING("running"),
/**
* 挂起
*/
SUSPENDED("suspended"),
/**
* 错误
*/
ERROR("error"),
/**
* 已完成
*/
COMPLETED("completed"),
/**
* 已取消
*/
CANCELLED("cancelled");
private final String code;
ProcessInstanceStateEnum(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}

View File

@@ -12,14 +12,14 @@ import com.sdm.flowable.constants.FlowableConfig;
import com.sdm.flowable.delegate.UniversalDelegate;
import com.sdm.flowable.dto.req.CompleteTaskReq;
import com.sdm.flowable.enums.FlowElementTypeEnums;
import com.sdm.flowable.enums.NodeStateEnum;
import com.sdm.flowable.enums.ProcessInstanceStateEnum;
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;
@@ -37,8 +37,6 @@ import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -293,32 +291,42 @@ public class ProcessService implements Iprocess{
boolean hasDeadLetterJobs = false;
if (isRunning) {
// 只查死信作业
// A. 查死信 (Error 来源)
List<Job> deadJobs = managementService.createDeadLetterJobQuery()
.processInstanceId(processInstanceId).list();
if (!deadJobs.isEmpty()) {
hasDeadLetterJobs = true;
// B. 查普通作业 (补全 Active 来源,防止重试瞬间查不到状态)
List<Job> activeJobs = managementService.createJobQuery()
.processInstanceId(processInstanceId).list();
// 【优化】:只有存在死信时,才去查 Execution 映射 ActivityId
// 这样重试中的流程(无死信)可以少查一次数据库
// C. 只有当有 作业(死信或普通) 时,才去查 Execution 映射
if (!deadJobs.isEmpty() || !activeJobs.isEmpty()) {
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));
for (Job job : deadJobs) {
if (job.getExceptionMessage() != null) {
String activityId = executionToActivityMap.get(job.getExecutionId());
if (activityId != null) {
errorMap.put(activityId, job.getExceptionMessage());
// 处理死信 -> 放入 errorMap
if (!deadJobs.isEmpty()) {
hasDeadLetterJobs = true;
for (Job job : deadJobs) {
if (job.getExceptionMessage() != null) {
String actId = executionToActivityMap.get(job.getExecutionId());
if (actId != null) errorMap.put(actId, job.getExceptionMessage());
}
}
}
// 【重点改动】处理普通作业 -> 强制加入 activeActivityIds
// 只要 Job 表里有,它就是 Active 的,不管 Execution 查出来是不是
for (Job job : activeJobs) {
String actId = executionToActivityMap.get(job.getExecutionId());
if (actId != null && !activeActivityIds.contains(actId)) {
activeActivityIds.add(actId);
}
}
}
// 【已移除】:原有的 createJobQuery (activeJobs) 查询逻辑。
// 解释:重试中的任务虽然带有异常信息,但在业务逻辑上视为“正在执行(Active)”,不视为“错误(Error)”。
}
// --- 5. 构建流程实例级状态 (ProcessInfo) ---
@@ -341,19 +349,19 @@ public class ProcessService implements Iprocess{
String displayStatus;
if (isError) {
displayStatus = "error"; // 彻底挂死:红色
displayStatus = NodeStateEnum.ERROR.getCode(); // 彻底挂死:红色
} else if (isActive) {
// 如果是重试任务isError=false, isActive=true -> 进入这里 -> 显示为 Active (蓝色)
// 同时兼容挂起状态显示
if (isProcessSuspended) {
displayStatus = "suspended";
displayStatus = NodeStateEnum.SUSPENDED.getCode();
} else {
displayStatus = "active";
displayStatus = NodeStateEnum.ACTIVE.getCode();
}
} else if (isFinished) {
displayStatus = "finished";
displayStatus = NodeStateEnum.FINISHED.getCode();
} else {
displayStatus = "pending";
displayStatus = NodeStateEnum.PENDING.getCode();
}
Date startTime = myHist != null ? myHist.getStartTime() : null;
@@ -372,20 +380,20 @@ public class ProcessService implements Iprocess{
if (waitIsActive) {
// 等待回调中,同样受挂起状态影响
displayStatus = isProcessSuspended ? "suspended" : "active";
displayStatus = isProcessSuspended ? NodeStateEnum.SUSPENDED.getCode() : NodeStateEnum.ACTIVE.getCode();
endTime = null;
if (startTime != null) {
duration = System.currentTimeMillis() - startTime.getTime();
}
} else if (waitIsFinished) {
displayStatus = "finished";
displayStatus = NodeStateEnum.FINISHED.getCode();
endTime = waitHist.getEndTime();
if (startTime != null && endTime != null) {
duration = endTime.getTime() - startTime.getTime();
}
} else if (isFinished && !waitIsFinished && !waitIsActive) {
// 刚发完 ServiceTask还没生成 ReceiveTask 的中间态
displayStatus = isProcessSuspended ? "suspended" : "active";
displayStatus = isProcessSuspended ? NodeStateEnum.SUSPENDED.getCode() : NodeStateEnum.ACTIVE.getCode();
endTime = null;
}
}
@@ -440,11 +448,11 @@ public class ProcessService implements Iprocess{
if (isRunning) {
// --- 运行中 ---
if (hasError) {
status = "error"; // 有死信作业,视为异常
status = ProcessInstanceStateEnum.ERROR.getCode(); // 有死信作业,视为异常
} else if (isSuspended) {
status = "suspended"; // 被挂起
status = ProcessInstanceStateEnum.SUSPENDED.getCode(); // 被挂起
} else {
status = "running"; // 正常运行
status = ProcessInstanceStateEnum.RUNNING.getCode(); // 正常运行
}
} else {
// --- 已结束 (运行时查不到,历史表里有) ---
@@ -452,11 +460,11 @@ public class ProcessService implements Iprocess{
if (deleteReason == null) {
// 1. 正常走完结束节点deleteReason 为空
status = "completed";
status = ProcessInstanceStateEnum.COMPLETED.getCode();
} else {
// 2. 有删除原因,说明是被取消或强制终止的
// 你可以根据 reason 的内容做更细的区分,或者统称为 cancelled
status = "cancelled";
status = ProcessInstanceStateEnum.CANCELLED.getCode();
}
}
info.setStatus(status);