From 500a4dedebbe742014e26cf140936fbefbe82bc7 Mon Sep 17 00:00:00 2001 From: byteblogs168 <598092184@qq.com> Date: Fri, 15 Dec 2023 11:08:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=202.6.0=201.=20=E5=AE=8C=E6=88=90DAG?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/sql/easy_retry_mysql.sql | 4 +- .../datasource/persistence/po/Workflow.java | 17 +- .../server/common/lock/JdbcLockProvider.java | 3 +- .../web/controller/WorkflowController.java | 19 +- .../web/model/request/WorkflowQueryVO.java | 16 + .../web/model/request/WorkflowRequestVO.java | 9 + .../response/WorkflowDetailResponseVO.java | 5 + .../model/response/WorkflowResponseVO.java | 62 +++ .../server/web/service/WorkflowService.java | 10 +- .../service/convert/WorkflowConverter.java | 5 +- .../web/service/impl/WorkflowServiceImpl.java | 105 ++++- frontend/src/api/jobApi.js | 17 +- frontend/src/config/router.config.js | 6 + frontend/src/utils/jobEnum.js | 14 +- frontend/src/views/job/WorkflowList.vue | 377 ++++++++++++++++++ 15 files changed, 640 insertions(+), 29 deletions(-) create mode 100644 easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/WorkflowQueryVO.java create mode 100644 easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/WorkflowResponseVO.java create mode 100644 frontend/src/views/job/WorkflowList.vue diff --git a/doc/sql/easy_retry_mysql.sql b/doc/sql/easy_retry_mysql.sql index b57d96da5..0459ae4e7 100644 --- a/doc/sql/easy_retry_mysql.sql +++ b/doc/sql/easy_retry_mysql.sql @@ -443,13 +443,15 @@ CREATE TABLE `retry_summary` CREATE TABLE `workflow` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', + `workflow_name` varchar(64) NOT NULL COMMENT '工作流名称', `namespace_id` varchar(64) NOT NULL DEFAULT '764d604ec6fc45f68cd92514c40e9e1a' COMMENT '命名空间id', `group_name` varchar(64) NOT NULL COMMENT '组名称', `workflow_status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '工作流状态 0、关闭、1、开启', `trigger_type` tinyint(4) NOT NULL COMMENT '触发类型 1.CRON 表达式 2. 固定时间', `trigger_interval` varchar(255) NOT NULL COMMENT '间隔时长', - `execution_at` bigint(13) NOT NULL DEFAULT '0' COMMENT '任务执行时间', + `next_trigger_at` bigint(13) NOT NULL COMMENT '下次触发时间', `executor_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒', + `description` varchar(256) NOT NULL DEFAULT '' COMMENT '描述', `flow_info` text DEFAULT NULL COMMENT '流程信息', `create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', diff --git a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/Workflow.java b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/Workflow.java index 3411f5c31..c33c7a9a6 100644 --- a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/Workflow.java +++ b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/Workflow.java @@ -8,9 +8,6 @@ import java.time.LocalDateTime; import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; - /** *

* 工作流 @@ -33,6 +30,11 @@ public class Workflow implements Serializable { @TableId(value = "id", type = IdType.AUTO) private Long id; + /** + * 工作流名称 + */ + private String workflowName; + /** * 命名空间id */ @@ -66,13 +68,18 @@ public class Workflow implements Serializable { /** * 任务执行时间 */ - private Long executionAt; + private Long nextTriggerAt; /** * 流程信息 */ private String flowInfo; + /** + * 描述 + */ + private String description; + /** * 创建时间 */ @@ -86,7 +93,7 @@ public class Workflow implements Serializable { /** * 逻辑删除 1、删除 */ - private Byte deleted; + private Integer deleted; /** * 扩展字段 diff --git a/easy-retry-server/easy-retry-server-common/src/main/java/com/aizuda/easy/retry/server/common/lock/JdbcLockProvider.java b/easy-retry-server/easy-retry-server-common/src/main/java/com/aizuda/easy/retry/server/common/lock/JdbcLockProvider.java index 6d229f6ab..079a19cd3 100644 --- a/easy-retry-server/easy-retry-server-common/src/main/java/com/aizuda/easy/retry/server/common/lock/JdbcLockProvider.java +++ b/easy-retry-server/easy-retry-server-common/src/main/java/com/aizuda/easy/retry/server/common/lock/JdbcLockProvider.java @@ -45,9 +45,8 @@ public class JdbcLockProvider extends AbstractLockProvider { } @Override - public boolean unlock(final LockConfig lockConfig) { - LocalDateTime now = lockConfig.getCreateDt(); + LocalDateTime now = LocalDateTime.now(); DistributedLock distributedLock = new DistributedLock(); distributedLock.setLockedBy(ServerRegister.CURRENT_CID); LocalDateTime lockAtLeast = lockConfig.getLockAtLeast(); diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/WorkflowController.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/WorkflowController.java index 0b26c9c07..bcd98bc70 100644 --- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/WorkflowController.java +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/WorkflowController.java @@ -1,12 +1,21 @@ package com.aizuda.easy.retry.server.web.controller; +import com.aizuda.easy.retry.server.web.annotation.LoginRequired; +import com.aizuda.easy.retry.server.web.annotation.RoleEnum; +import com.aizuda.easy.retry.server.web.model.base.PageResult; +import com.aizuda.easy.retry.server.web.model.request.WorkflowQueryVO; import com.aizuda.easy.retry.server.web.model.request.WorkflowRequestVO; import com.aizuda.easy.retry.server.web.model.response.WorkflowDetailResponseVO; +import com.aizuda.easy.retry.server.web.model.response.WorkflowResponseVO; import com.aizuda.easy.retry.server.web.service.WorkflowService; import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Role; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.io.IOException; +import java.util.List; + /** * @author xiaowoniu * @date 2023-12-12 21:50:46 @@ -20,17 +29,25 @@ public class WorkflowController { private final WorkflowService workflowService; @PostMapping + @LoginRequired(role = RoleEnum.USER) public Boolean saveWorkflow(@RequestBody @Validated WorkflowRequestVO workflowRequestVO) { return workflowService.saveWorkflow(workflowRequestVO); } + @GetMapping("/page/list") + @LoginRequired(role = RoleEnum.USER) + public PageResult> listPage(WorkflowQueryVO queryVO) { + return workflowService.listPage(queryVO); + } + @PutMapping public void updateWorkflow() { } @GetMapping("{id}") - public WorkflowDetailResponseVO getWorkflowDetail(@PathVariable("id") Long id) { + @LoginRequired(role = RoleEnum.USER) + public WorkflowDetailResponseVO getWorkflowDetail(@PathVariable("id") Long id) throws IOException { return workflowService.getWorkflowDetail(id); } diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/WorkflowQueryVO.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/WorkflowQueryVO.java new file mode 100644 index 000000000..c80a7bd15 --- /dev/null +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/WorkflowQueryVO.java @@ -0,0 +1,16 @@ +package com.aizuda.easy.retry.server.web.model.request; + +import com.aizuda.easy.retry.server.web.model.base.BaseQueryVO; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author: xiaowoniu + * @date : 2023-12-15 12:09 + * @since : 2.6.0 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class WorkflowQueryVO extends BaseQueryVO { + +} diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/WorkflowRequestVO.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/WorkflowRequestVO.java index 7a1ad75d9..4fe26a72a 100644 --- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/WorkflowRequestVO.java +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/WorkflowRequestVO.java @@ -21,6 +21,9 @@ public class WorkflowRequestVO { @Pattern(regexp = "^[A-Za-z0-9_]{1,64}$", message = "仅支持长度为1~64字符且类型为数字、字母和下划线") private String groupName; + @NotBlank(message = "工作流名称不能为空") + private String workflowName; + @NotNull(message = "触发类型不能为空") private Integer triggerType; @@ -36,6 +39,12 @@ public class WorkflowRequestVO { @NotNull(message = "工作流状态") private Integer workflowStatus; + /** + * 描述 + */ + private String description; + + /** * DAG节点配置 */ diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/WorkflowDetailResponseVO.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/WorkflowDetailResponseVO.java index 13a7fe58b..25432295c 100644 --- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/WorkflowDetailResponseVO.java +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/WorkflowDetailResponseVO.java @@ -75,6 +75,11 @@ public class WorkflowDetailResponseVO { */ private Long id; + /** + * 1、任务节点 2、条件节点 3、回调节点 + */ + private Integer nodeType; + /** * 节点名称 */ diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/WorkflowResponseVO.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/WorkflowResponseVO.java new file mode 100644 index 000000000..02dd0221b --- /dev/null +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/WorkflowResponseVO.java @@ -0,0 +1,62 @@ +package com.aizuda.easy.retry.server.web.model.response; + +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * @author: xiaowoniu + * @date : 2023-12-15 12:22 + * @since : 2.6.0 + */ +@Data +public class WorkflowResponseVO { + + private Long id; + + /** + * 工作流名称 + */ + private String workflowName; + + /** + * 组名称 + */ + private String groupName; + + /** + * 触发类型 + */ + private Integer triggerType; + + /** + * 触发间隔 + */ + private String triggerInterval; + + /** + * 执行超时时间 + */ + private Integer executorTimeout; + + /** + * 工作流状态 0、关闭、1、开启 + */ + private Integer workflowStatus; + + /** + * 任务执行时间 + */ + private Long nextTriggerAt; + + /** + * 创建时间 + */ + private LocalDateTime createDt; + + /** + * 修改时间 + */ + private LocalDateTime updateDt; + +} diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/WorkflowService.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/WorkflowService.java index 86f99a262..213365305 100644 --- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/WorkflowService.java +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/WorkflowService.java @@ -1,7 +1,13 @@ package com.aizuda.easy.retry.server.web.service; +import com.aizuda.easy.retry.server.web.model.base.PageResult; +import com.aizuda.easy.retry.server.web.model.request.WorkflowQueryVO; import com.aizuda.easy.retry.server.web.model.request.WorkflowRequestVO; import com.aizuda.easy.retry.server.web.model.response.WorkflowDetailResponseVO; +import com.aizuda.easy.retry.server.web.model.response.WorkflowResponseVO; + +import java.io.IOException; +import java.util.List; /** * @author xiaowoniu @@ -12,5 +18,7 @@ public interface WorkflowService { boolean saveWorkflow(WorkflowRequestVO workflowRequestVO); - WorkflowDetailResponseVO getWorkflowDetail(Long id); + WorkflowDetailResponseVO getWorkflowDetail(Long id) throws IOException; + + PageResult> listPage(WorkflowQueryVO queryVO); } diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/WorkflowConverter.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/WorkflowConverter.java index f425e4ae6..bc20f1ecd 100644 --- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/WorkflowConverter.java +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/WorkflowConverter.java @@ -2,6 +2,7 @@ package com.aizuda.easy.retry.server.web.service.convert; import com.aizuda.easy.retry.server.web.model.request.WorkflowRequestVO; import com.aizuda.easy.retry.server.web.model.response.WorkflowDetailResponseVO; +import com.aizuda.easy.retry.server.web.model.response.WorkflowResponseVO; import com.aizuda.easy.retry.template.datasource.persistence.po.Workflow; import com.aizuda.easy.retry.template.datasource.persistence.po.WorkflowNode; import org.mapstruct.Mapper; @@ -25,5 +26,7 @@ public interface WorkflowConverter { WorkflowDetailResponseVO toWorkflowDetailResponseVO(Workflow workflow); - WorkflowDetailResponseVO.NodeInfo toNodeInfo(WorkflowNode workflowNode); + List toNodeInfo(List workflowNodes); + + List toWorkflowResponseVO(List workflowList); } diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/WorkflowServiceImpl.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/WorkflowServiceImpl.java index 0763ac467..1e8684714 100644 --- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/WorkflowServiceImpl.java +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/WorkflowServiceImpl.java @@ -2,21 +2,32 @@ package com.aizuda.easy.retry.server.web.service.impl; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; +import com.aizuda.easy.retry.common.core.enums.StatusEnum; import com.aizuda.easy.retry.common.core.util.JsonUtil; import com.aizuda.easy.retry.server.common.exception.EasyRetryServerException; +import com.aizuda.easy.retry.server.web.model.base.PageResult; +import com.aizuda.easy.retry.server.web.model.request.UserSessionVO; +import com.aizuda.easy.retry.server.web.model.request.WorkflowQueryVO; import com.aizuda.easy.retry.server.web.model.request.WorkflowRequestVO; import com.aizuda.easy.retry.server.web.model.request.WorkflowRequestVO.NodeConfig; import com.aizuda.easy.retry.server.web.model.request.WorkflowRequestVO.NodeInfo; +import com.aizuda.easy.retry.server.web.model.response.JobResponseVO; import com.aizuda.easy.retry.server.web.model.response.WorkflowDetailResponseVO; +import com.aizuda.easy.retry.server.web.model.response.WorkflowResponseVO; import com.aizuda.easy.retry.server.web.service.WorkflowService; +import com.aizuda.easy.retry.server.web.service.convert.JobResponseVOConverter; import com.aizuda.easy.retry.server.web.service.convert.WorkflowConverter; +import com.aizuda.easy.retry.server.web.util.UserSessionUtils; import com.aizuda.easy.retry.template.datasource.persistence.mapper.WorkflowMapper; import com.aizuda.easy.retry.template.datasource.persistence.mapper.WorkflowNodeMapper; +import com.aizuda.easy.retry.template.datasource.persistence.po.Job; import com.aizuda.easy.retry.template.datasource.persistence.po.Workflow; import com.aizuda.easy.retry.template.datasource.persistence.po.WorkflowNode; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Lists; -import com.google.common.graph.ElementOrder; import com.google.common.graph.GraphBuilder; import com.google.common.graph.MutableGraph; import lombok.RequiredArgsConstructor; @@ -25,6 +36,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; +import java.io.IOException; import java.util.*; import java.util.stream.Collectors; @@ -51,6 +63,8 @@ public class WorkflowServiceImpl implements WorkflowService { // 组装工作流信息 Workflow workflow = WorkflowConverter.INSTANCE.toWorkflow(workflowRequestVO); + // TODO 临时设置值 + workflow.setNextTriggerAt(1L); workflow.setFlowInfo(StrUtil.EMPTY); Assert.isTrue(1 == workflowMapper.insert(workflow), () -> new EasyRetryServerException("新增工作流失败")); @@ -69,34 +83,94 @@ public class WorkflowServiceImpl implements WorkflowService { } @Override - public WorkflowDetailResponseVO getWorkflowDetail(Long id) { + public WorkflowDetailResponseVO getWorkflowDetail(Long id) throws IOException { Workflow workflow = workflowMapper.selectById(id); + if (Objects.isNull(workflow)) { + return null; + } + WorkflowDetailResponseVO responseVO = WorkflowConverter.INSTANCE.toWorkflowDetailResponseVO(workflow); - WorkflowDetailResponseVO.NodeConfig nodeConfig = new WorkflowDetailResponseVO.NodeConfig(); - responseVO.setNodeConfig(nodeConfig); List workflowNodes = workflowNodeMapper.selectList(new LambdaQueryWrapper() .eq(WorkflowNode::getDeleted, 0) .eq(WorkflowNode::getWorkflowId, id)); - Map workflowNodeMap = workflowNodes.stream().collect(Collectors.toMap(WorkflowNode::getId, i -> i)); + List nodeInfos = WorkflowConverter.INSTANCE.toNodeInfo(workflowNodes); + + Map workflowNodeMap = nodeInfos.stream().collect(Collectors.toMap(WorkflowDetailResponseVO.NodeInfo::getId, i -> i)); String flowInfo = workflow.getFlowInfo(); - // 反序列化构建图 - MutableGraph graph = GraphBuilder.directed().allowsSelfLoops(false).build(); - Set successors = graph.successors(root); - for (Long nodeId : successors) { - WorkflowNode workflowNode = workflowNodeMap.get(nodeId); - nodeConfig.setNodeType(workflowNode.getNodeType()); - List nodeInfos = Optional.ofNullable(nodeConfig.getConditionNodes()).orElse(Lists.newArrayList()); - nodeInfos.add(WorkflowConverter.INSTANCE.toNodeInfo(workflowNode)); - nodeConfig.setConditionNodes(nodeInfos); + try { + // 反序列化构建图 + WorkflowDetailResponseVO.NodeConfig config = deserializeJsonToGraph(flowInfo, workflowNodeMap); + responseVO.setNodeConfig(config); + } catch (Exception e) { + log.error("反序列化失败. json:[{}]", flowInfo, e); + throw e; } - return null; + return responseVO; } + @Override + public PageResult> listPage(final WorkflowQueryVO queryVO) { + PageDTO pageDTO = new PageDTO<>(queryVO.getPage(), queryVO.getSize()); + UserSessionVO userSessionVO = UserSessionUtils.currentUserSession(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(Workflow::getDeleted, StatusEnum.NO.getStatus()); + queryWrapper.eq(Workflow::getNamespaceId, userSessionVO.getNamespaceId()); + + PageDTO page = workflowMapper.selectPage(pageDTO, queryWrapper); + + List jobResponseList = WorkflowConverter.INSTANCE.toWorkflowResponseVO(page.getRecords()); + + return new PageResult<>(pageDTO, jobResponseList); + } + + // 从JSON反序列化为Guava图 + private static WorkflowDetailResponseVO.NodeConfig deserializeJsonToGraph(String jsonGraph, + Map workflowNodeMap) throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + + // 将JSON字符串转换为Map> + Map> adjacencyList = objectMapper.readValue( + jsonGraph, new TypeReference>>() {}); + + Map configMap = new HashMap<>(); + WorkflowDetailResponseVO.NodeConfig rootConfig = new WorkflowDetailResponseVO.NodeConfig(); + + // 创建Guava图并添加节点和边 + for (Map.Entry> entry : adjacencyList.entrySet()) { + Long node = entry.getKey(); + Iterable successors = entry.getValue(); + WorkflowDetailResponseVO.NodeConfig previousConfig = configMap.getOrDefault(node, new WorkflowDetailResponseVO.NodeConfig()); + + WorkflowDetailResponseVO.NodeConfig currentConfig = new WorkflowDetailResponseVO.NodeConfig(); + for (Long successor : successors) { + WorkflowDetailResponseVO.NodeInfo nodeInfo = workflowNodeMap.get(successor); + // 第一层节点 + if (node == root) { + rootConfig.setNodeType(nodeInfo.getNodeType()); + List nodeInfos = Optional.ofNullable( + rootConfig.getConditionNodes()).orElse(Lists.newArrayList()); + nodeInfos.add(nodeInfo); + rootConfig.setConditionNodes(nodeInfos); + configMap.put(nodeInfo.getId(), rootConfig); + } else { + currentConfig.setNodeType(nodeInfo.getNodeType()); + List nodeInfos = Optional.ofNullable( + currentConfig.getConditionNodes()).orElse(Lists.newArrayList()); + nodeInfos.add(nodeInfo); + currentConfig.setConditionNodes(nodeInfos); + configMap.put(nodeInfo.getId(), currentConfig); + previousConfig.setChildNode(currentConfig); + } + } + } + + return rootConfig; + } private Map> convertGraphToAdjacencyList(MutableGraph graph) { @@ -123,6 +197,7 @@ public class WorkflowServiceImpl implements WorkflowService { WorkflowNode workflowNode = WorkflowConverter.INSTANCE.toWorkflowNode(nodeInfo); workflowNode.setWorkflowId(workflowId); workflowNode.setGroupName(groupName); + workflowNode.setNodeType(nodeConfig.getNodeType()); Assert.isTrue(1 == workflowNodeMapper.insert(workflowNode), () -> new EasyRetryServerException("新增工作流节点失败")); // 添加节点 graph.addNode(workflowNode.getId()); diff --git a/frontend/src/api/jobApi.js b/frontend/src/api/jobApi.js index ebf5a6a33..428701518 100644 --- a/frontend/src/api/jobApi.js +++ b/frontend/src/api/jobApi.js @@ -27,11 +27,26 @@ const jobApi = { jobTaskList: '/job/task/list', // 日志 - jobLogList: '/job/log/list' + jobLogList: '/job/log/list', + + // DAG + listPage: '/workflow/page/list', + saveWorkflow: '/workflow', + updateWorkflow: '/workflow', + workflowDetail: '/workflow' + } export default jobApi +export function listPage (parameter) { + return request({ + url: jobApi.listPage, + method: 'get', + params: parameter + }) +} + export function triggerJob (id) { return request({ url: jobApi.triggerJob + id, diff --git a/frontend/src/config/router.config.js b/frontend/src/config/router.config.js index 3f1978c28..8b86da92f 100644 --- a/frontend/src/config/router.config.js +++ b/frontend/src/config/router.config.js @@ -209,6 +209,12 @@ export const asyncRouterMap = [ hidden: true, component: () => import('@/views/job/form/JobNotifyForm.vue'), meta: { title: '通知配置', icon: 'profile', keepAlive: true, permission: ['jobNotify'] } + }, + { + path: '/job/workflow/list', + name: 'WorkflowList', + component: () => import('@/views/job/WorkflowList'), + meta: { title: '工作流', icon: 'profile', permission: ['jobBatch'] } } ] }, diff --git a/frontend/src/utils/jobEnum.js b/frontend/src/utils/jobEnum.js index 54e62b25e..2eeb5ded4 100644 --- a/frontend/src/utils/jobEnum.js +++ b/frontend/src/utils/jobEnum.js @@ -172,7 +172,7 @@ const enums = { 'color': '#087da1' } }, -notifyStatus: { + notifyStatus: { '0': { 'name': '停用', 'color': '#9c1f1f' @@ -182,7 +182,7 @@ notifyStatus: { 'color': '#f5a22d' } }, -rateLimiterStatus: { + rateLimiterStatus: { '0': { 'name': '未启用', 'color': '#9c1f1f' @@ -191,6 +191,16 @@ rateLimiterStatus: { 'name': '启用', 'color': '#f5a22d' } + }, + workflowStatus: { + '0': { + 'name': '关闭', + 'color': '#9c1f1f' + }, + '1': { + 'name': '开启', + 'color': '#f5a22d' + } } } diff --git a/frontend/src/views/job/WorkflowList.vue b/frontend/src/views/job/WorkflowList.vue new file mode 100644 index 000000000..43a4ab39a --- /dev/null +++ b/frontend/src/views/job/WorkflowList.vue @@ -0,0 +1,377 @@ + + +