diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/controller/WorkflowController.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/controller/WorkflowController.java index e3eb409e..27d06ecb 100644 --- a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/controller/WorkflowController.java +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/controller/WorkflowController.java @@ -7,6 +7,7 @@ import com.aizuda.snailjob.server.common.dto.DecisionConfig; import com.aizuda.snailjob.server.web.annotation.LoginRequired; import com.aizuda.snailjob.server.web.annotation.RoleEnum; import com.aizuda.snailjob.server.web.model.base.PageResult; +import com.aizuda.snailjob.server.web.model.request.ExportWorkflowVO; import com.aizuda.snailjob.server.web.model.request.WorkflowQueryVO; import com.aizuda.snailjob.server.web.model.request.WorkflowRequestVO; import com.aizuda.snailjob.server.web.model.response.WorkflowDetailResponseVO; @@ -96,10 +97,6 @@ public class WorkflowController { @LoginRequired @PostMapping(value = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public void importScene(@RequestPart("file") MultipartFile file) throws IOException { - if (file.isEmpty()) { - throw new SnailJobCommonException("请选择一个文件上传"); - } - // 写入数据 workflowService.importWorkflowTask(ImportUtils.parseList(file, WorkflowRequestVO.class)); } @@ -107,8 +104,8 @@ public class WorkflowController { @LoginRequired @PostMapping("/export") @OriginalControllerReturnValue - public ResponseEntity export(@RequestBody Set workflowIds) { - return ExportUtils.doExport(workflowService.exportWorkflowTask(workflowIds)); + public ResponseEntity export(@RequestBody ExportWorkflowVO exportWorkflowVO) { + return ExportUtils.doExport(workflowService.exportWorkflowTask(exportWorkflowVO)); } } diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/request/ExportWorkflowVO.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/request/ExportWorkflowVO.java new file mode 100644 index 00000000..7893e4db --- /dev/null +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/request/ExportWorkflowVO.java @@ -0,0 +1,22 @@ +package com.aizuda.snailjob.server.web.model.request; + +import lombok.Data; + +import java.util.Set; + +/** + * @author: opensnail + * @date : 2024-05-30 + * @since : sj_1.0.0 + */ +@Data +public class ExportWorkflowVO { + + private Set workflowIds; + + private String groupName; + + private String workflowName; + + private Integer workflowStatus; +} diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/WorkflowService.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/WorkflowService.java index 5a94ec95..1fbc6560 100644 --- a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/WorkflowService.java +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/WorkflowService.java @@ -3,6 +3,7 @@ package com.aizuda.snailjob.server.web.service; import cn.hutool.core.lang.Pair; import com.aizuda.snailjob.server.common.dto.DecisionConfig; import com.aizuda.snailjob.server.web.model.base.PageResult; +import com.aizuda.snailjob.server.web.model.request.ExportWorkflowVO; import com.aizuda.snailjob.server.web.model.request.WorkflowQueryVO; import com.aizuda.snailjob.server.web.model.request.WorkflowRequestVO; import com.aizuda.snailjob.server.web.model.response.WorkflowDetailResponseVO; @@ -12,7 +13,6 @@ import jakarta.validation.constraints.NotEmpty; import java.io.IOException; import java.util.List; -import java.util.Set; /** * @author xiaowoniu @@ -41,5 +41,6 @@ public interface WorkflowService { void importWorkflowTask(@Valid @NotEmpty(message = "导入数据不能为空") List requests); - String exportWorkflowTask(Set workflowIds); + String exportWorkflowTask(ExportWorkflowVO exportWorkflowVO + ); } diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/impl/WorkflowServiceImpl.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/impl/WorkflowServiceImpl.java index 68353fea..be9d09a9 100644 --- a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/impl/WorkflowServiceImpl.java +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/impl/WorkflowServiceImpl.java @@ -16,6 +16,7 @@ import com.aizuda.snailjob.server.common.WaitStrategy; import com.aizuda.snailjob.server.common.config.SystemProperties; import com.aizuda.snailjob.server.common.dto.DecisionConfig; import com.aizuda.snailjob.server.common.dto.JobTaskConfig; +import com.aizuda.snailjob.server.common.dto.PartitionTask; import com.aizuda.snailjob.server.common.enums.ExpressionTypeEnum; import com.aizuda.snailjob.server.common.enums.JobTaskExecutorSceneEnum; import com.aizuda.snailjob.server.common.exception.SnailJobServerException; @@ -23,12 +24,13 @@ import com.aizuda.snailjob.server.common.strategy.WaitStrategies; import com.aizuda.snailjob.server.common.util.CronUtils; import com.aizuda.snailjob.server.common.util.DateUtils; import com.aizuda.snailjob.server.common.util.GraphUtils; +import com.aizuda.snailjob.server.common.util.PartitionTaskUtils; import com.aizuda.snailjob.server.job.task.dto.WorkflowTaskPrepareDTO; import com.aizuda.snailjob.server.job.task.support.WorkflowPrePareHandler; import com.aizuda.snailjob.server.job.task.support.WorkflowTaskConverter; import com.aizuda.snailjob.server.job.task.support.expression.ExpressionInvocationHandler; import com.aizuda.snailjob.server.web.model.base.PageResult; -import com.aizuda.snailjob.server.web.model.request.SceneConfigRequestVO; +import com.aizuda.snailjob.server.web.model.request.ExportWorkflowVO; import com.aizuda.snailjob.server.web.model.request.UserSessionVO; import com.aizuda.snailjob.server.web.model.request.WorkflowQueryVO; import com.aizuda.snailjob.server.web.model.request.WorkflowRequestVO; @@ -36,12 +38,10 @@ import com.aizuda.snailjob.server.web.model.request.WorkflowRequestVO.NodeConfig import com.aizuda.snailjob.server.web.model.response.WorkflowDetailResponseVO; import com.aizuda.snailjob.server.web.model.response.WorkflowResponseVO; import com.aizuda.snailjob.server.web.service.WorkflowService; -import com.aizuda.snailjob.server.web.service.convert.SceneConfigConverter; import com.aizuda.snailjob.server.web.service.convert.WorkflowConverter; import com.aizuda.snailjob.server.web.service.handler.WorkflowHandler; import com.aizuda.snailjob.server.web.util.UserSessionUtils; import com.aizuda.snailjob.template.datasource.access.AccessTemplate; -import com.aizuda.snailjob.template.datasource.access.ConfigAccess; import com.aizuda.snailjob.template.datasource.persistence.mapper.JobMapper; import com.aizuda.snailjob.template.datasource.persistence.mapper.WorkflowMapper; import com.aizuda.snailjob.template.datasource.persistence.mapper.WorkflowNodeMapper; @@ -53,13 +53,15 @@ import com.google.common.collect.Sets; import com.google.common.graph.ElementOrder; import com.google.common.graph.GraphBuilder; import com.google.common.graph.MutableGraph; +import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.LinkedBlockingDeque; import java.util.stream.Collectors; @@ -95,8 +97,8 @@ public class WorkflowServiceImpl implements WorkflowService { private static void checkExecuteInterval(WorkflowRequestVO requestVO) { if (Lists.newArrayList(WaitStrategies.WaitStrategyEnum.FIXED.getType(), - WaitStrategies.WaitStrategyEnum.RANDOM.getType()) - .contains(requestVO.getTriggerType())) { + WaitStrategies.WaitStrategyEnum.RANDOM.getType()) + .contains(requestVO.getTriggerType())) { if (Integer.parseInt(requestVO.getTriggerInterval()) < 10) { throw new SnailJobServerException("触发间隔不得小于10"); } @@ -122,8 +124,8 @@ public class WorkflowServiceImpl implements WorkflowService { workflow.setNextTriggerAt(calculateNextTriggerAt(workflowRequestVO, DateUtils.toNowMilli())); workflow.setFlowInfo(StrUtil.EMPTY); workflow.setBucketIndex( - HashUtil.bkdrHash(workflowRequestVO.getGroupName() + workflowRequestVO.getWorkflowName()) - % systemProperties.getBucketTotal()); + HashUtil.bkdrHash(workflowRequestVO.getGroupName() + workflowRequestVO.getWorkflowName()) + % systemProperties.getBucketTotal()); workflow.setNamespaceId(UserSessionUtils.currentUserSession().getNamespaceId()); Assert.isTrue(1 == workflowMapper.insert(workflow), () -> new SnailJobServerException("新增工作流失败")); @@ -132,10 +134,10 @@ public class WorkflowServiceImpl implements WorkflowService { // 递归构建图 workflowHandler.buildGraph(Lists.newArrayList(SystemConstants.ROOT), - new LinkedBlockingDeque<>(), - workflowRequestVO.getGroupName(), - workflow.getId(), nodeConfig, graph, - workflow.getVersion()); + new LinkedBlockingDeque<>(), + workflowRequestVO.getGroupName(), + workflow.getId(), nodeConfig, graph, + workflow.getVersion()); log.info("图构建完成. graph:[{}]", graph); // 保存图信息 @@ -147,61 +149,25 @@ public class WorkflowServiceImpl implements WorkflowService { private MutableGraph createGraph() { return GraphBuilder.directed() - .nodeOrder(ElementOrder.sorted(Long::compare)) - .incidentEdgeOrder(ElementOrder.stable()) - .allowsSelfLoops(false) - .build(); + .nodeOrder(ElementOrder.sorted(Long::compare)) + .incidentEdgeOrder(ElementOrder.stable()) + .allowsSelfLoops(false) + .build(); } @Override public WorkflowDetailResponseVO getWorkflowDetail(Long id) { Workflow workflow = workflowMapper.selectOne( - new LambdaQueryWrapper() - .eq(Workflow::getId, id) - .eq(Workflow::getNamespaceId, UserSessionUtils.currentUserSession().getNamespaceId()) + new LambdaQueryWrapper() + .eq(Workflow::getId, id) + .eq(Workflow::getNamespaceId, UserSessionUtils.currentUserSession().getNamespaceId()) ); if (Objects.isNull(workflow)) { return null; } - WorkflowDetailResponseVO responseVO = WorkflowConverter.INSTANCE.convert(workflow); - List workflowNodes = workflowNodeMapper.selectList(new LambdaQueryWrapper() - .eq(WorkflowNode::getDeleted, 0) - .eq(WorkflowNode::getVersion, workflow.getVersion()) - .eq(WorkflowNode::getWorkflowId, id) - .orderByAsc(WorkflowNode::getPriorityLevel)); - - List jobIds = StreamUtils.toList(workflowNodes, WorkflowNode::getJobId); - List jobs = jobMapper.selectList(new LambdaQueryWrapper() - .in(Job::getId, new HashSet<>(jobIds))); - - Map jobMap = StreamUtils.toIdentityMap(jobs, Job::getId); - - List nodeInfos = WorkflowConverter.INSTANCE.convertList(workflowNodes); - - Map workflowNodeMap = nodeInfos.stream() - .peek(nodeInfo -> { - JobTaskConfig jobTask = nodeInfo.getJobTask(); - if (Objects.nonNull(jobTask)) { - jobTask.setJobName(jobMap.getOrDefault(jobTask.getJobId(), new Job()).getJobName()); - } - }).collect(Collectors.toMap(WorkflowDetailResponseVO.NodeInfo::getId, i -> i)); - - String flowInfo = workflow.getFlowInfo(); - try { - MutableGraph graph = GraphUtils.deserializeJsonToGraph(flowInfo); - // 反序列化构建图 - WorkflowDetailResponseVO.NodeConfig config = workflowHandler.buildNodeConfig(graph, SystemConstants.ROOT, - new HashMap<>(), - workflowNodeMap); - responseVO.setNodeConfig(config); - } catch (Exception e) { - log.error("反序列化失败. json:[{}]", flowInfo, e); - throw new SnailJobServerException("查询工作流详情失败"); - } - - return responseVO; + return doGetWorkflowDetail(workflow); } @Override @@ -210,15 +176,18 @@ public class WorkflowServiceImpl implements WorkflowService { UserSessionVO userSessionVO = UserSessionUtils.currentUserSession(); PageDTO page = workflowMapper.selectPage(pageDTO, - new LambdaQueryWrapper() - .eq(Workflow::getDeleted, StatusEnum.NO.getStatus()) - .eq(Workflow::getNamespaceId, userSessionVO.getNamespaceId()) - .eq(StrUtil.isNotBlank(queryVO.getGroupName()), Workflow::getGroupName, queryVO.getGroupName()) - .like(StrUtil.isNotBlank(queryVO.getWorkflowName()), Workflow::getWorkflowName, queryVO.getWorkflowName()) - .eq(Objects.nonNull(queryVO.getWorkflowStatus()), Workflow::getWorkflowStatus, queryVO.getWorkflowStatus()) - .orderByDesc(Workflow::getId)); + new LambdaQueryWrapper() + .eq(Workflow::getDeleted, StatusEnum.NO.getStatus()) + .eq(Workflow::getNamespaceId, userSessionVO.getNamespaceId()) + .eq(StrUtil.isNotBlank(queryVO.getGroupName()), Workflow::getGroupName, queryVO.getGroupName()) + .like(StrUtil.isNotBlank(queryVO.getWorkflowName()), Workflow::getWorkflowName, + queryVO.getWorkflowName()) + .eq(Objects.nonNull(queryVO.getWorkflowStatus()), Workflow::getWorkflowStatus, + queryVO.getWorkflowStatus()) + .orderByDesc(Workflow::getId)); - List jobResponseList = WorkflowConverter.INSTANCE.convertListToWorkflowList(page.getRecords()); + List jobResponseList = WorkflowConverter.INSTANCE.convertListToWorkflowList( + page.getRecords()); return new PageResult<>(pageDTO, jobResponseList); } @@ -243,7 +212,7 @@ public class WorkflowServiceImpl implements WorkflowService { int version = workflow.getVersion(); // 递归构建图 workflowHandler.buildGraph(Lists.newArrayList(SystemConstants.ROOT), new LinkedBlockingDeque<>(), - workflowRequestVO.getGroupName(), workflowRequestVO.getId(), nodeConfig, graph, version + 1); + workflowRequestVO.getGroupName(), workflowRequestVO.getId(), nodeConfig, graph, version + 1); log.info("图构建完成. graph:[{}]", graph); @@ -254,11 +223,11 @@ public class WorkflowServiceImpl implements WorkflowService { workflow.setNextTriggerAt(calculateNextTriggerAt(workflowRequestVO, DateUtils.toNowMilli())); workflow.setFlowInfo(JsonUtil.toJsonString(GraphUtils.serializeGraphToJson(graph))); Assert.isTrue( - workflowMapper.update(workflow, - new LambdaQueryWrapper() - .eq(Workflow::getId, workflow.getId()) - .eq(Workflow::getVersion, version)) > 0, - () -> new SnailJobServerException("更新失败")); + workflowMapper.update(workflow, + new LambdaQueryWrapper() + .eq(Workflow::getId, workflow.getId()) + .eq(Workflow::getVersion, version)) > 0, + () -> new SnailJobServerException("更新失败")); return Boolean.TRUE; } @@ -266,9 +235,9 @@ public class WorkflowServiceImpl implements WorkflowService { @Override public Boolean updateStatus(Long id) { Workflow workflow = workflowMapper.selectOne( - new LambdaQueryWrapper() - .select(Workflow::getId, Workflow::getWorkflowStatus) - .eq(Workflow::getId, id)); + new LambdaQueryWrapper() + .select(Workflow::getId, Workflow::getWorkflowStatus) + .eq(Workflow::getId, id)); Assert.notNull(workflow, () -> new SnailJobServerException("工作流不存在")); if (Objects.equals(workflow.getWorkflowStatus(), StatusEnum.NO.getStatus())) { @@ -294,13 +263,14 @@ public class WorkflowServiceImpl implements WorkflowService { Assert.notNull(workflow, () -> new SnailJobServerException("workflow can not be null.")); long count = accessTemplate.getGroupConfigAccess().count( - new LambdaQueryWrapper() - .eq(GroupConfig::getGroupName, workflow.getGroupName()) - .eq(GroupConfig::getNamespaceId, workflow.getNamespaceId()) - .eq(GroupConfig::getGroupStatus, StatusEnum.YES.getStatus()) + new LambdaQueryWrapper() + .eq(GroupConfig::getGroupName, workflow.getGroupName()) + .eq(GroupConfig::getNamespaceId, workflow.getNamespaceId()) + .eq(GroupConfig::getGroupStatus, StatusEnum.YES.getStatus()) ); - Assert.isTrue(count > 0, () -> new SnailJobServerException("组:[{}]已经关闭,不支持手动执行.", workflow.getGroupName())); + Assert.isTrue(count > 0, + () -> new SnailJobServerException("组:[{}]已经关闭,不支持手动执行.", workflow.getGroupName())); WorkflowTaskPrepareDTO prepareDTO = WorkflowTaskConverter.INSTANCE.toWorkflowTaskPrepareDTO(workflow); // 设置now表示立即执行 @@ -315,13 +285,13 @@ public class WorkflowServiceImpl implements WorkflowService { @Override public List getWorkflowNameList(String keywords, Long workflowId) { PageDTO selectPage = workflowMapper.selectPage( - new PageDTO<>(1, 20), - new LambdaQueryWrapper() - .select(Workflow::getId, Workflow::getWorkflowName) - .likeRight(StrUtil.isNotBlank(keywords), Workflow::getWorkflowName, StrUtil.trim(keywords)) - .eq(Objects.nonNull(workflowId), Workflow::getId, workflowId) - .eq(Workflow::getDeleted, StatusEnum.NO.getStatus()) - .orderByAsc(Workflow::getId)); + new PageDTO<>(1, 20), + new LambdaQueryWrapper() + .select(Workflow::getId, Workflow::getWorkflowName) + .likeRight(StrUtil.isNotBlank(keywords), Workflow::getWorkflowName, StrUtil.trim(keywords)) + .eq(Objects.nonNull(workflowId), Workflow::getId, workflowId) + .eq(Workflow::getDeleted, StatusEnum.NO.getStatus()) + .orderByAsc(Workflow::getId)); return WorkflowConverter.INSTANCE.convertListToWorkflowList(selectPage.getRecords()); } @@ -349,33 +319,48 @@ public class WorkflowServiceImpl implements WorkflowService { } @Override - public String exportWorkflowTask(Set workflowIds) { - List workflowList = workflowMapper.selectList(new LambdaQueryWrapper() - .eq(Workflow::getNamespaceId, UserSessionUtils.currentUserSession().getNamespaceId()) - .eq(Workflow::getDeleted, StatusEnum.NO.getStatus()) - // TODO 若导出全部需要分页查询,避免一次拉取太多数据 - .in(CollUtil.isNotEmpty(workflowIds), Workflow::getId, workflowIds) - ); + public String exportWorkflowTask(ExportWorkflowVO exportVO) { - List workflowDetailResponseVOList = workflowList.stream().map(i -> getWorkflowDetail(i.getId())).collect(Collectors.toList()); - return JsonUtil.toJsonString(workflowDetailResponseVOList); + List resultList = new ArrayList<>(); + PartitionTaskUtils.process(startId -> { + List workflowList = workflowMapper.selectPage(new PageDTO<>(0, 100), + new LambdaQueryWrapper() + .eq(Workflow::getNamespaceId, UserSessionUtils.currentUserSession().getNamespaceId()) + .eq(Workflow::getDeleted, StatusEnum.NO.getStatus()) + .eq(StrUtil.isNotBlank(exportVO.getGroupName()), Workflow::getGroupName, exportVO.getGroupName()) + .eq(Objects.nonNull(exportVO.getWorkflowStatus()), Workflow::getWorkflowStatus, exportVO.getWorkflowStatus()) + .likeRight(StrUtil.isNotBlank(exportVO.getWorkflowName()), Workflow::getWorkflowName, exportVO.getWorkflowName()) + .in(CollUtil.isNotEmpty(exportVO.getWorkflowIds()), Workflow::getId, exportVO.getWorkflowIds()) + .ge(Workflow::getId, startId) + .orderByAsc(Workflow::getId) + ).getRecords(); + return workflowList.stream() + .map(this::doGetWorkflowDetail) + .map(WorkflowPartitionTask::new) + .collect(Collectors.toList()); + }, partitionTasks -> { + List workflowPartitionTasks = (List) partitionTasks; + resultList.addAll(StreamUtils.toList(workflowPartitionTasks, WorkflowPartitionTask::getResponseVO)); + }, 0); + + return JsonUtil.toJsonString(resultList); } private void batchSaveWorkflowTask(final List workflowRequestVOList, final String namespaceId) { - Set groupNameSet = workflowRequestVOList.stream().map(i -> i.getGroupName()).collect(Collectors.toSet()); + Set groupNameSet =StreamUtils.toSet(workflowRequestVOList, WorkflowRequestVO::getGroupName); List groupConfigs = accessTemplate.getGroupConfigAccess() - .list(new LambdaQueryWrapper() - .select(GroupConfig::getGroupName) - .eq(GroupConfig::getNamespaceId, namespaceId) - .in(GroupConfig::getGroupName, groupNameSet) - ); + .list(new LambdaQueryWrapper() + .select(GroupConfig::getGroupName) + .eq(GroupConfig::getNamespaceId, namespaceId) + .in(GroupConfig::getGroupName, groupNameSet) + ); Sets.SetView notExistedGroupNameSet = Sets.difference(groupNameSet, - StreamUtils.toSet(groupConfigs, GroupConfig::getGroupName)); + StreamUtils.toSet(groupConfigs, GroupConfig::getGroupName)); Assert.isTrue(CollUtil.isEmpty(notExistedGroupNameSet), - () -> new SnailJobServerException("导入失败. 原因: 组{}不存在", notExistedGroupNameSet)); + () -> new SnailJobServerException("导入失败. 原因: 组{}不存在", notExistedGroupNameSet)); for (final WorkflowRequestVO workflowRequestVO : workflowRequestVOList) { checkExecuteInterval(workflowRequestVO); @@ -383,4 +368,54 @@ public class WorkflowServiceImpl implements WorkflowService { saveWorkflow(workflowRequestVO); } } + + private WorkflowDetailResponseVO doGetWorkflowDetail(final Workflow workflow) { + WorkflowDetailResponseVO responseVO = WorkflowConverter.INSTANCE.convert(workflow); + List workflowNodes = workflowNodeMapper.selectList(new LambdaQueryWrapper() + .eq(WorkflowNode::getDeleted, 0) + .eq(WorkflowNode::getVersion, workflow.getVersion()) + .eq(WorkflowNode::getWorkflowId, workflow.getId()) + .orderByAsc(WorkflowNode::getPriorityLevel)); + + List jobIds = StreamUtils.toList(workflowNodes, WorkflowNode::getJobId); + List jobs = jobMapper.selectList(new LambdaQueryWrapper() + .in(Job::getId, new HashSet<>(jobIds))); + + Map jobMap = StreamUtils.toIdentityMap(jobs, Job::getId); + + List nodeInfos = WorkflowConverter.INSTANCE.convertList(workflowNodes); + + Map workflowNodeMap = nodeInfos.stream() + .peek(nodeInfo -> { + JobTaskConfig jobTask = nodeInfo.getJobTask(); + if (Objects.nonNull(jobTask)) { + jobTask.setJobName(jobMap.getOrDefault(jobTask.getJobId(), new Job()).getJobName()); + } + }).collect(Collectors.toMap(WorkflowDetailResponseVO.NodeInfo::getId, i -> i)); + + String flowInfo = workflow.getFlowInfo(); + try { + MutableGraph graph = GraphUtils.deserializeJsonToGraph(flowInfo); + // 反序列化构建图 + WorkflowDetailResponseVO.NodeConfig config = workflowHandler.buildNodeConfig(graph, SystemConstants.ROOT, + new HashMap<>(), + workflowNodeMap); + responseVO.setNodeConfig(config); + } catch (Exception e) { + log.error("反序列化失败. json:[{}]", flowInfo, e); + throw new SnailJobServerException("查询工作流详情失败"); + } + return responseVO; + } + + + @EqualsAndHashCode(callSuper = true) + @Getter + private static class WorkflowPartitionTask extends PartitionTask { + private final WorkflowDetailResponseVO responseVO; + public WorkflowPartitionTask(@NotNull WorkflowDetailResponseVO responseVO) { + this.responseVO = responseVO; + setId(responseVO.getId()); + } + } } diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/util/ExportUtils.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/util/ExportUtils.java index 2e11d40a..3f0870bf 100644 --- a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/util/ExportUtils.java +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/util/ExportUtils.java @@ -6,7 +6,9 @@ import org.springframework.http.ResponseEntity; import java.nio.charset.StandardCharsets; -public class ExportUtils { + +public final class ExportUtils { + private ExportUtils() {} public static ResponseEntity doExport(String json) { HttpHeaders headers = new HttpHeaders(); diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/util/ImportUtils.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/util/ImportUtils.java index b9610226..c78af4d4 100644 --- a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/util/ImportUtils.java +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/util/ImportUtils.java @@ -10,9 +10,10 @@ import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.List; -public class ImportUtils { +public final class ImportUtils { private static final List FILE_EXTENSIONS = List.of("json"); + private ImportUtils() {} public static @NotNull List parseList(MultipartFile file, Class clazz) throws IOException { if (file.isEmpty()) { @@ -26,9 +27,7 @@ public class ImportUtils { } JsonNode node = JsonUtil.toJson(file.getBytes()); - List requestList = JsonUtil.parseList(JsonUtil.toJsonString(node), clazz); - - return requestList; + return JsonUtil.parseList(JsonUtil.toJsonString(node), clazz); } }