数据总览 前端按钮权限设置
This commit is contained in:
@@ -114,6 +114,9 @@ public class FileMetadataInfoResp implements Serializable {
|
||||
@Schema(description = "完整访问URL(拼接minio网关地址 + objectKey)")
|
||||
private String fileUrl;
|
||||
|
||||
@Schema(description = "权限值")
|
||||
private Integer permissionValue;
|
||||
|
||||
private String approvalStatus;
|
||||
private String approveType;
|
||||
private String tempMetadata;
|
||||
|
||||
@@ -98,6 +98,10 @@ public class FileMetadataInfo implements Serializable {
|
||||
@TableField(value = "creatorName", insertStrategy = FieldStrategy.NEVER,select = false,updateStrategy = FieldStrategy.NEVER)
|
||||
private String creatorName;
|
||||
|
||||
@Schema(description= "更新者名称,列表展示使用")
|
||||
@TableField(value = "updaterName", insertStrategy = FieldStrategy.NEVER,select = false,updateStrategy = FieldStrategy.NEVER)
|
||||
private String updaterName;
|
||||
|
||||
@Schema(description= "创建时间")
|
||||
@TableField("createTime")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
@@ -21,4 +21,12 @@ public interface IFileUserPermissionService extends IService<FileUserPermission>
|
||||
* @return 是否有权限
|
||||
*/
|
||||
boolean hasFilePermission(Long fileId, Long userId, FilePermissionEnum permission);
|
||||
|
||||
/**
|
||||
* 获取文件权限位掩码
|
||||
* @param fileId 文件ID
|
||||
* @param userId 用户ID
|
||||
* @return 权限位掩码
|
||||
*/
|
||||
Integer getMergedPermission(Long fileId, Long userId);
|
||||
}
|
||||
|
||||
@@ -83,4 +83,48 @@ public class FileUserPermissionServiceImpl extends ServiceImpl<FileUserPermissio
|
||||
|
||||
return validPermission(parentId, userId, permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getMergedPermission(Long fileId, Long userId) {
|
||||
if (fileId == null || userId == null) return (int) FilePermissionEnum.ZERO.getValue();
|
||||
|
||||
FileMetadataInfo fileInfo = fileMetadataInfoService.getById(fileId);
|
||||
if (fileInfo == null) return (int) FilePermissionEnum.ZERO.getValue();
|
||||
|
||||
// 1. 系统内置基础文件夹,通常给满权限
|
||||
for (DirTypeEnum dirType : DirTypeEnum.getInitSpmdDir()) {
|
||||
if (fileInfo.getOriginalName().equals(dirType.getDirName())) {
|
||||
return (int) FilePermissionEnum.ALL.getValue(); // 1|2|4|8|16 = 31 (全权限)
|
||||
}
|
||||
}
|
||||
|
||||
// 开始递归计算合并权限
|
||||
return calculateRecursiveMergedPermission(fileId, userId);
|
||||
}
|
||||
|
||||
private int calculateRecursiveMergedPermission(Long fileId, Long userId) {
|
||||
// 默认只读权限
|
||||
byte currentPerm = FilePermissionEnum.READ.getValue();
|
||||
|
||||
// 查询当前节点该用户的显式权限记录
|
||||
FileUserPermission userPermRecord = this.lambdaQuery()
|
||||
.eq(FileUserPermission::getTFilemetaId, fileId)
|
||||
.eq(FileUserPermission::getUserId, userId)
|
||||
.one();
|
||||
|
||||
if (userPermRecord != null) {
|
||||
currentPerm = userPermRecord.getPermission();
|
||||
}
|
||||
|
||||
// 获取父节点
|
||||
FileMetadataInfo currentFile = fileMetadataInfoService.getById(fileId);
|
||||
|
||||
// 如果有父级且不是根目录,则继续向上合并
|
||||
if (currentFile != null && currentFile.getParentId() != null && currentFile.getParentId() > 0) {
|
||||
// 使用 | (按位或) 合并当前权限与父级权限
|
||||
return (byte) (currentPerm | calculateRecursiveMergedPermission(currentFile.getParentId(), userId));
|
||||
}
|
||||
|
||||
return currentPerm;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,13 +57,11 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.assertj.core.util.DateUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
@@ -644,7 +642,20 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
setAnalysisDirectionName(files);
|
||||
setSimulationPoolAndTaskInfo(files);
|
||||
PageInfo<FileMetadataInfo> page = new PageInfo<>(files);
|
||||
return PageUtils.getJsonObjectSdmResponse(files, page);
|
||||
|
||||
long total = page.getTotal();
|
||||
List<FileMetadataInfoResp> dtoList = files.stream().map(entity -> {
|
||||
FileMetadataInfoResp dto = new FileMetadataInfoResp();
|
||||
BeanUtils.copyProperties(entity, dto);
|
||||
|
||||
//计算当前用户对该文件的综合权限位
|
||||
// 对于列表查询,如果层级很深,频繁递归会有性能问题。
|
||||
dto.setPermissionValue(fileUserPermissionService.getMergedPermission(entity.getId(), ThreadLocalContext.getUserId()));
|
||||
return dto;
|
||||
}).collect(Collectors.toList());
|
||||
PageInfo<FileMetadataInfoResp> page1 = new PageInfo<>(dtoList);
|
||||
page1.setTotal(total);
|
||||
return PageUtils.getJsonObjectSdmResponse(dtoList, page1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -661,6 +672,8 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
FileMetadataInfoResp fileMetadataInfoResp = new FileMetadataInfoResp();
|
||||
BeanUtils.copyProperties(fileMetadataInfo, fileMetadataInfoResp);
|
||||
|
||||
fileMetadataInfoResp.setPermissionValue(fileUserPermissionService.getMergedPermission(fileMetadataInfo.getId(), ThreadLocalContext.getUserId()));
|
||||
|
||||
return SdmResponse.success(fileMetadataInfoResp);
|
||||
}
|
||||
|
||||
@@ -707,6 +720,10 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
List<FileMetadataInfoResp> dtoList = list.stream().map(entity -> {
|
||||
FileMetadataInfoResp dto = new FileMetadataInfoResp();
|
||||
BeanUtils.copyProperties(entity, dto);
|
||||
|
||||
//计算当前用户对该文件的综合权限位
|
||||
// 对于列表查询,如果层级很深,频繁递归会有性能问题。
|
||||
dto.setPermissionValue(fileUserPermissionService.getMergedPermission(entity.getId(), ThreadLocalContext.getUserId()));
|
||||
return dto;
|
||||
}).collect(Collectors.toList());
|
||||
PageInfo<FileMetadataInfoResp> page1 = new PageInfo<>(dtoList);
|
||||
@@ -784,7 +801,12 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
newObjectKey = oldObjectKey.substring(0, oldObjectKey.lastIndexOf("/") + 1) + newName;
|
||||
|
||||
minioService.renameFile(oldObjectKey, newObjectKey,bucketName);
|
||||
fileMetadataInfoService.lambdaUpdate().set(FileMetadataInfo::getObjectKey, newObjectKey).set(FileMetadataInfo::getOriginalName, newName).eq(FileMetadataInfo::getId, fileId).update();
|
||||
fileMetadataInfoService.lambdaUpdate()
|
||||
.set(FileMetadataInfo::getObjectKey, newObjectKey)
|
||||
.set(FileMetadataInfo::getOriginalName, newName)
|
||||
.set(FileMetadataInfo::getUpdateTime, new Date())
|
||||
.set(FileMetadataInfo::getUpdaterId, ThreadLocalContext.getUserId())
|
||||
.eq(FileMetadataInfo::getId, fileId).update();
|
||||
return SdmResponse.success("重命名成功");
|
||||
} catch (Exception e) {
|
||||
log.error("重命名文件失败", e);
|
||||
@@ -944,7 +966,12 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
|
||||
try {
|
||||
minioService.renameFile(oldDirMinioObjectKey, newDirMinioObjectKey,dirMetadataInfo.getBucketName());
|
||||
fileMetadataInfoService.lambdaUpdate().set(FileMetadataInfo::getObjectKey, newDirMinioObjectKey).set(FileMetadataInfo::getOriginalName, req.getNewName()).eq(FileMetadataInfo::getId, dirMetadataInfo.getId()).update();
|
||||
fileMetadataInfoService.lambdaUpdate()
|
||||
.set(FileMetadataInfo::getObjectKey, newDirMinioObjectKey)
|
||||
.set(FileMetadataInfo::getOriginalName, req.getNewName())
|
||||
.set(FileMetadataInfo::getUpdateTime, new Date())
|
||||
.set(FileMetadataInfo::getUpdaterId, ThreadLocalContext.getUserId())
|
||||
.eq(FileMetadataInfo::getId, dirMetadataInfo.getId()).update();
|
||||
return SdmResponse.success("重命名目录成功");
|
||||
} catch (Exception e) {
|
||||
log.error("重命名目录失败", e);
|
||||
@@ -1522,13 +1549,14 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
fileMetadataInfoLambdaQueryChainWrapper.eq(FileMetadataInfo::getParentId, parentDirId);
|
||||
}
|
||||
List<FileMetadataInfo> list = fileMetadataInfoLambdaQueryChainWrapper.eq(FileMetadataInfo::getTenantId, ThreadLocalContext.getTenantId()).eq(FileMetadataInfo::getDataType, DataTypeEnum.DIRECTORY.getValue()).orderByDesc(FileMetadataInfo::getCreateTime).list();
|
||||
setCreatorNames(list);
|
||||
|
||||
List<FileMetadataInfoResp> dtoList = list.stream().map(entity -> {
|
||||
FileMetadataInfoResp dto = new FileMetadataInfoResp();
|
||||
BeanUtils.copyProperties(entity, dto);
|
||||
|
||||
// todo 后面接入用户系统设置
|
||||
dto.setCreatorName("");
|
||||
//计算当前用户对该文件的综合权限位
|
||||
// 对于列表查询,如果层级很深,频繁递归会有性能问题。
|
||||
dto.setPermissionValue(fileUserPermissionService.getMergedPermission(entity.getId(), ThreadLocalContext.getUserId()));
|
||||
return dto;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
@@ -1577,10 +1605,11 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
tempFileMetadataInfo.setRemarks(req.getRemarks());
|
||||
tempFileMetadataInfo.setSimulationPoolInfoList(req.getSimulationPoolInfoList());
|
||||
tempFileMetadataInfo.setCreateTime(fileMetadataInfo.getCreateTime());
|
||||
tempFileMetadataInfo.setUpdateTime(fileMetadataInfo.getCreateTime());
|
||||
tempFileMetadataInfo.setUpdaterId(ThreadLocalContext.getUserId());
|
||||
tempFileMetadataInfo.setUpdateTime(LocalDateTime.now());
|
||||
fileMetadataInfo.setTempMetadata(JSONObject.toJSONString(tempFileMetadataInfo));
|
||||
fileMetadataInfo.setUpdateTime(LocalDateTime.now());
|
||||
fileMetadataInfo.setUpdaterId(ThreadLocalContext.getUserId());
|
||||
|
||||
//发起审批
|
||||
FileApproveRequestBuilder updateFileMetaIntoApproveRequestBuilder = FileApproveRequestBuilder.builder()
|
||||
@@ -1615,6 +1644,8 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
fileMetadataInfo.setProjectId(req.getProjectId());
|
||||
fileMetadataInfo.setAnalysisDirectionId(req.getAnalysisDirectionId());
|
||||
fileMetadataInfo.setRemarks(req.getRemarks());
|
||||
fileMetadataInfo.setUpdateTime(LocalDateTime.now());
|
||||
fileMetadataInfo.setUpdaterId(ThreadLocalContext.getUserId());
|
||||
}
|
||||
|
||||
fileMetadataInfoService.updateById(fileMetadataInfo);
|
||||
@@ -2172,12 +2203,20 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
try {
|
||||
if (ObjectUtils.isNotEmpty(list)) {
|
||||
// 提取去重的 creatorId
|
||||
List<Long> creatorIds = list.stream()
|
||||
List<Long> creatorIds = new ArrayList<>(list.stream()
|
||||
.map(FileMetadataInfo::getCreatorId)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.toList());
|
||||
|
||||
List<Long> updaterIds = list.stream()
|
||||
.map(FileMetadataInfo::getUpdaterId)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.toList();
|
||||
|
||||
creatorIds.addAll(updaterIds);
|
||||
|
||||
// 远程查询用户信息
|
||||
SdmResponse<List<CIDUserResp>> userListSdmRsp = sysUserFeignClient.listUserByIds(
|
||||
UserQueryReq.builder().userIds(creatorIds).build()
|
||||
@@ -2194,6 +2233,15 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
cidUser.getRealName()
|
||||
);
|
||||
fileMetadataInfo.setCreatorName(username);
|
||||
|
||||
Long updaterId = fileMetadataInfo.getUpdaterId();
|
||||
CIDUserResp cidUser1 = cidUserMap.get(updaterId);
|
||||
String username1 = Objects.isNull(cidUser1) ? "" : org.apache.commons.lang3.StringUtils.firstNonBlank(
|
||||
cidUser1.getNickname(),
|
||||
cidUser1.getUsername(),
|
||||
cidUser1.getRealName()
|
||||
);
|
||||
fileMetadataInfo.setUpdaterName(username1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public enum FlowElementTypeEnums {
|
||||
|
||||
public static FlowElementTypeEnums fromString(String type) {
|
||||
for (FlowElementTypeEnums flowElementType : FlowElementTypeEnums.values()) {
|
||||
if (flowElementType.type.equals(type)) {
|
||||
if (flowElementType.type.equalsIgnoreCase(type)) {
|
||||
return flowElementType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,13 @@ public enum NodeStateEnum {
|
||||
* 挂起
|
||||
*/
|
||||
SUSPENDED("suspended"),
|
||||
|
||||
/**
|
||||
* [新增] 等待用户确认(对应 Manual 模式卡在 _waitUser 节点)
|
||||
* 前端看到这个状态应显示"执行/继续"按钮
|
||||
*/
|
||||
WAITING_FOR_USER("waiting_for_user"),
|
||||
|
||||
|
||||
/**
|
||||
* 错误
|
||||
|
||||
@@ -286,7 +286,7 @@ public class ProcessService implements Iprocess{
|
||||
|
||||
// 4. 计算流程实例整体状态
|
||||
// 只要 hasDeadLetterJobs 为 false,流程状态就会显示为 running (或 suspended)
|
||||
processInfo = buildProcessInstanceInfo(processInstanceId, context.isRunning(), context.isSuspended(), context.isHasDeadLetterJobs());
|
||||
processInfo = buildProcessInstanceInfo(processInstanceId, context);
|
||||
|
||||
// 5. 计算每个节点的状态 (核心逻辑)
|
||||
calculateNodeStates(allNodes, context);
|
||||
@@ -303,6 +303,10 @@ public class ProcessService implements Iprocess{
|
||||
boolean isRunning;
|
||||
boolean isSuspended;
|
||||
boolean hasDeadLetterJobs;
|
||||
|
||||
// 记录最早发生错误的时间(死信作业的创建时间)
|
||||
Date earliestErrorTime;
|
||||
|
||||
// Map<ActivityId, ErrorMsg>
|
||||
Map<String, String> errorMap = new HashMap<>();
|
||||
// List<ActivityId>
|
||||
@@ -331,6 +335,7 @@ public class ProcessService implements Iprocess{
|
||||
ProcessStateContext ctx = new ProcessStateContext();
|
||||
|
||||
// 1. 获取运行时流程实例对象(判断是否运行中、是否挂起)
|
||||
// ACT_RU_EXECUTION (运行时执行实例表)
|
||||
ProcessInstance runtimeInstance = runtimeService.createProcessInstanceQuery()
|
||||
.processInstanceId(processInstanceId)
|
||||
.singleResult();
|
||||
@@ -338,18 +343,22 @@ public class ProcessService implements Iprocess{
|
||||
ctx.setSuspended(ctx.isRunning() && runtimeInstance.isSuspended());
|
||||
|
||||
// 2. 准备历史数据
|
||||
// 查询 ACT_HI_ACTINST 该流程实例下,所有的历史节点记录
|
||||
List<HistoricActivityInstance> historicActivities = historyService.createHistoricActivityInstanceQuery()
|
||||
.processInstanceId(processInstanceId)
|
||||
.list();
|
||||
for (HistoricActivityInstance hist : historicActivities) {
|
||||
if (!ctx.historyMap.containsKey(hist.getActivityId()) ||
|
||||
hist.getStartTime().after(ctx.historyMap.get(hist.getActivityId()).getStartTime())) {
|
||||
// 只保留节点最新的开始时间记录,防止重复覆盖(例如:重试作业)
|
||||
ctx.historyMap.put(hist.getActivityId(), hist);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 准备运行时 Active ID 列表
|
||||
if (ctx.isRunning()) {
|
||||
// 查 ACT_RU_EXECUTION 运行时活跃节点ID列表
|
||||
// historicActivities 也一定会有活跃节点ID,当流程的流转入 serviceTask_id1 的那一瞬间,引擎会立即在 ACT_HI_ACTINST 表插入一条记录
|
||||
ctx.activeActivityIds.addAll(runtimeService.getActiveActivityIds(processInstanceId));
|
||||
|
||||
// A. 查死信 (Error 来源)
|
||||
@@ -362,6 +371,9 @@ public class ProcessService implements Iprocess{
|
||||
|
||||
// C. 只有当有 作业(死信或普通) 时,才去查 Execution 映射
|
||||
if (!deadJobs.isEmpty() || !activeJobs.isEmpty()) {
|
||||
// 查 Execution 表,获取 ExecutionId 和 ActivityId 映射
|
||||
// Flowable 的 Job 表(ACT_RU_JOB 或 ACT_RU_DEADLETTER_JOB)存储的是“干活的任务单”,里面只有 executionId(执行指针 ID),没有 activityId(BPMN 里的节点 ID,如 ServiceTask_1)
|
||||
// 就算已经进入 ACT_RU_DEADLETTER_JOB 死信队列了 , ACT_RU_EXECUTION 还是会有对应的 ExecutionId 和 ActivityId
|
||||
List<Execution> executions = runtimeService.createExecutionQuery()
|
||||
.processInstanceId(processInstanceId).list();
|
||||
Map<String, String> executionToActivityMap = executions.stream()
|
||||
@@ -371,6 +383,16 @@ public class ProcessService implements Iprocess{
|
||||
// 处理死信 -> 放入 errorMap
|
||||
if (!deadJobs.isEmpty()) {
|
||||
ctx.setHasDeadLetterJobs(true);
|
||||
|
||||
// 找到最早的死信时间,作为流程“卡住”的时间点
|
||||
Date firstError = deadJobs.stream()
|
||||
.map(Job::getCreateTime)
|
||||
.filter(Objects::nonNull)
|
||||
.min(Date::compareTo)
|
||||
.orElse(null);
|
||||
ctx.setEarliestErrorTime(firstError);
|
||||
|
||||
|
||||
for (Job job : deadJobs) {
|
||||
if (job.getExceptionMessage() != null) {
|
||||
String actId = executionToActivityMap.get(job.getExecutionId());
|
||||
@@ -393,7 +415,11 @@ public class ProcessService implements Iprocess{
|
||||
}
|
||||
|
||||
// 构建流程实例信息
|
||||
private ProcessInstanceInfo buildProcessInstanceInfo(String processInstanceId, boolean isRunning, boolean isSuspended, boolean hasError) {
|
||||
private ProcessInstanceInfo buildProcessInstanceInfo(String processInstanceId, ProcessStateContext context) {
|
||||
boolean isRunning = context.isRunning();
|
||||
boolean isSuspended = context.isSuspended();
|
||||
boolean hasError = context.isHasDeadLetterJobs();
|
||||
|
||||
HistoricProcessInstance historicInstance = historyService.createHistoricProcessInstanceQuery()
|
||||
.processInstanceId(processInstanceId)
|
||||
.singleResult();
|
||||
@@ -410,9 +436,22 @@ public class ProcessService implements Iprocess{
|
||||
|
||||
// 计算耗时
|
||||
Long duration = historicInstance.getDurationInMillis();
|
||||
// 如果 duration 为空(说明流程没结束),且流程已开始
|
||||
if (duration == null && historicInstance.getStartTime() != null && isRunning) {
|
||||
duration = System.currentTimeMillis() - historicInstance.getStartTime().getTime();
|
||||
|
||||
if (hasError && context.getEarliestErrorTime() != null) {
|
||||
// 情况 A: 流程报错了,耗时 = 报错时刻 - 开始时刻
|
||||
// 这样时间就“定格”了,不会随着你查询时间而增加
|
||||
duration = context.getEarliestErrorTime().getTime() - historicInstance.getStartTime().getTime();
|
||||
} else {
|
||||
// 情况 B: 正常运行或挂起,耗时 = 当前时刻 - 开始时刻
|
||||
duration = System.currentTimeMillis() - historicInstance.getStartTime().getTime();
|
||||
}
|
||||
}
|
||||
|
||||
// 防止出现负数(极端并发情况下)
|
||||
if (duration != null && duration < 0) duration = 0L;
|
||||
|
||||
info.setDurationInMillis(duration);
|
||||
info.setDurationFormatted(duration != null ? formatDuration(duration) : null);
|
||||
|
||||
@@ -500,7 +539,19 @@ public class ProcessService implements Iprocess{
|
||||
|
||||
if (isActive) {
|
||||
// 只要是 Active,就根据流程整体状态来定颜色
|
||||
node.setStatus(ctx.isSuspended() ? NodeStateEnum.SUSPENDED.getCode() : NodeStateEnum.ACTIVE.getCode());
|
||||
// 如果流程整体被挂起,优先显示挂起
|
||||
if (ctx.isSuspended()) {
|
||||
node.setStatus(NodeStateEnum.SUSPENDED.getCode());
|
||||
} else if (ctx.activeActivityIds.contains(waitUserId)) {
|
||||
// 停留在 _waitUser -> 等待用户操作 (Manual模式)
|
||||
node.setStatus(NodeStateEnum.WAITING_FOR_USER.getCode());
|
||||
} else if (FlowElementTypeEnums.USERTASK.getType().equalsIgnoreCase(node.getType()) && ctx.activeActivityIds.contains(origId)) {
|
||||
// 这是一个普通的 UserTask,且当前正卡在这里
|
||||
node.setStatus(NodeStateEnum.WAITING_FOR_USER.getCode());
|
||||
}else {
|
||||
// 停留在 origId 或 waitId 或 checkId-> 视为通用执行中
|
||||
node.setStatus(NodeStateEnum.ACTIVE.getCode());
|
||||
}
|
||||
calculateAggregatedTime(node, ctx, waitUserId, origId, checkId);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user