diff --git a/easy-retry-common/easy-retry-common-core/src/main/java/com/aizuda/easy/retry/common/core/enums/JobNotifySceneEnum.java b/easy-retry-common/easy-retry-common-core/src/main/java/com/aizuda/easy/retry/common/core/enums/JobNotifySceneEnum.java new file mode 100644 index 00000000..9e1a08b4 --- /dev/null +++ b/easy-retry-common/easy-retry-common-core/src/main/java/com/aizuda/easy/retry/common/core/enums/JobNotifySceneEnum.java @@ -0,0 +1,59 @@ +package com.aizuda.easy.retry.common.core.enums; + +import lombok.Getter; + +/** + * 通知场景枚举 + * + * @author: zuoJunLin + * @date : 2023-12-02 18:18 + */ +@Getter +public enum JobNotifySceneEnum { + + + + JOB_TASK_ERROR(1, "JOB任务执行失败", NodeTypeEnum.SERVER); + + + + /** + * 通知场景 + */ + private final int notifyScene; + + /** + * 触发通知节点类型 + */ + private final NodeTypeEnum nodeType; + + /** + * 描述 + */ + private final String desc; + + JobNotifySceneEnum(int notifyScene, String desc, NodeTypeEnum nodeType) { + this.notifyScene = notifyScene; + this.desc = desc; + this.nodeType = nodeType; + } + + /** + * 获取通知场景 + * + * @param notifyScene 场景 + * @param nodeType 触发通知节点类型 + * @return this + */ + public static JobNotifySceneEnum getJobNotifyScene(int notifyScene, NodeTypeEnum nodeType) { + for (JobNotifySceneEnum sceneEnum : JobNotifySceneEnum.values()) { + if (sceneEnum.getNotifyScene() == notifyScene && sceneEnum.nodeType.getType().equals(nodeType.getType())) { + return sceneEnum; + } + } + + return null; + } + + +} diff --git a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/dataobject/JobBatchResponseDO.java b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/dataobject/JobBatchResponseDO.java index d8aff41a..fc3c75bd 100644 --- a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/dataobject/JobBatchResponseDO.java +++ b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/dataobject/JobBatchResponseDO.java @@ -14,6 +14,11 @@ public class JobBatchResponseDO { private Long id; + /** + * 命名空间 + */ + private String namespaceId; + /** * 组名称 */ @@ -57,12 +62,15 @@ public class JobBatchResponseDO { /** * 执行器名称 */ - private String executorName; + private String executorInfo; private Integer taskType; private Integer blockStrategy; private Integer triggerType; + private String argsStr; + + } diff --git a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/dataobject/JobNotifyConfigQueryDO.java b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/dataobject/JobNotifyConfigQueryDO.java new file mode 100644 index 00000000..4f8af07d --- /dev/null +++ b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/dataobject/JobNotifyConfigQueryDO.java @@ -0,0 +1,21 @@ +package com.aizuda.easy.retry.template.datasource.persistence.dataobject; + +import lombok.Data; + +/** + * @author zuoJunLin + * @date 2023-12-02 23:03:01 + * @since 2.4.0 + */ +@Data +public class JobNotifyConfigQueryDO { + + private String groupName; + + private Long jobId; + /** + * 命名空间id + */ + private String namespaceId; + +} diff --git a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/dataobject/JobNotifyConfigResponseDO.java b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/dataobject/JobNotifyConfigResponseDO.java new file mode 100644 index 00000000..a3cbfc19 --- /dev/null +++ b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/dataobject/JobNotifyConfigResponseDO.java @@ -0,0 +1,44 @@ +package com.aizuda.easy.retry.template.datasource.persistence.dataobject; + +import lombok.Data; +import java.time.LocalDateTime; + +/** + * @author zuoJunLin + * @date 2023-12-02 23:03:01 + * @since 2.4.0 + */ +@Data +public class JobNotifyConfigResponseDO { + + private Long id; + + private String namespaceId; + + private String groupName; + + private Long jobId; + + private String jobName; + + private Integer notifyStatus; + + private Integer notifyType; + + private String notifyAttribute; + + private Integer notifyThreshold; + + private Integer notifyScene; + + private Integer rateLimiterStatus; + + private Integer rateLimiterThreshold; + + private String description; + + private LocalDateTime createDt; + + private LocalDateTime updateDt; + +} diff --git a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/mapper/JobNotifyConfigMapper.java b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/mapper/JobNotifyConfigMapper.java new file mode 100644 index 00000000..9f2d0e4e --- /dev/null +++ b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/mapper/JobNotifyConfigMapper.java @@ -0,0 +1,19 @@ +package com.aizuda.easy.retry.template.datasource.persistence.mapper; + +import com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobNotifyConfigQueryDO; +import com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobNotifyConfigResponseDO; +import com.aizuda.easy.retry.template.datasource.persistence.po.JobNotifyConfig; +import com.aizuda.easy.retry.template.datasource.persistence.po.NotifyConfig; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @author zuoJunLin + */ +public interface JobNotifyConfigMapper extends BaseMapper { + List selectJobNotifyConfigList(IPage iPage, @Param("queryDO") JobNotifyConfigQueryDO queryDO); +} diff --git a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/mapper/JobTaskBatchMapper.java b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/mapper/JobTaskBatchMapper.java index 36c6091e..bc7326de 100644 --- a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/mapper/JobTaskBatchMapper.java +++ b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/mapper/JobTaskBatchMapper.java @@ -23,7 +23,9 @@ import java.util.List; @Mapper public interface JobTaskBatchMapper extends BaseMapper { - List selectJobBatchList(IPage iPage, @Param("queryDO") JobBatchQueryDO queryDO); + List selectJobBatchPageList(IPage iPage, @Param("queryDO") JobBatchQueryDO queryDO); + + List selectJobBatchListByIds( @Param("ids") List ids); List summaryJobBatchList(@Param("from") LocalDateTime todayFrom, @Param("to") LocalDateTime to); } diff --git a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/JobNotifyConfig.java b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/JobNotifyConfig.java new file mode 100644 index 00000000..1c11aa4a --- /dev/null +++ b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/JobNotifyConfig.java @@ -0,0 +1,45 @@ +package com.aizuda.easy.retry.template.datasource.persistence.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +@Data +public class JobNotifyConfig implements Serializable { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private String namespaceId; + + private String groupName; + + private Long jobId; + + private Integer notifyStatus; + + private Integer notifyType; + + private String notifyAttribute; + + private Integer notifyThreshold; + + private Integer notifyScene; + + private Integer rateLimiterStatus; + + private Integer rateLimiterThreshold; + + private String description; + + private LocalDateTime createDt; + + private LocalDateTime updateDt; + + private static final long serialVersionUID = 1L; + + +} diff --git a/easy-retry-datasource/easy-retry-mariadb-datasource/src/main/resources/mariadb/mapper/JobNotifyConfigMapper.xml b/easy-retry-datasource/easy-retry-mariadb-datasource/src/main/resources/mariadb/mapper/JobNotifyConfigMapper.xml new file mode 100644 index 00000000..9fe0f18b --- /dev/null +++ b/easy-retry-datasource/easy-retry-mariadb-datasource/src/main/resources/mariadb/mapper/JobNotifyConfigMapper.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + id,namespace_id, group_name,job_id,notify_status,notify_type, notify_attribute, notify_threshold, notify_scene,rate_limiter_status,rate_limiter_threshold, description, + create_dt, update_dt + + + diff --git a/easy-retry-datasource/easy-retry-mariadb-datasource/src/main/resources/mariadb/mapper/JobTaskBatchMapper.xml b/easy-retry-datasource/easy-retry-mariadb-datasource/src/main/resources/mariadb/mapper/JobTaskBatchMapper.xml index 12cf767f..dbaf4410 100644 --- a/easy-retry-datasource/easy-retry-mariadb-datasource/src/main/resources/mariadb/mapper/JobTaskBatchMapper.xml +++ b/easy-retry-datasource/easy-retry-mariadb-datasource/src/main/resources/mariadb/mapper/JobTaskBatchMapper.xml @@ -13,7 +13,7 @@ - + + diff --git a/easy-retry-datasource/easy-retry-mysql-datasource/src/main/resources/mysql/mapper/JobNotifyConfigMapper.xml b/easy-retry-datasource/easy-retry-mysql-datasource/src/main/resources/mysql/mapper/JobNotifyConfigMapper.xml new file mode 100644 index 00000000..9fe0f18b --- /dev/null +++ b/easy-retry-datasource/easy-retry-mysql-datasource/src/main/resources/mysql/mapper/JobNotifyConfigMapper.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + id,namespace_id, group_name,job_id,notify_status,notify_type, notify_attribute, notify_threshold, notify_scene,rate_limiter_status,rate_limiter_threshold, description, + create_dt, update_dt + + + diff --git a/easy-retry-datasource/easy-retry-mysql-datasource/src/main/resources/mysql/mapper/JobTaskBatchMapper.xml b/easy-retry-datasource/easy-retry-mysql-datasource/src/main/resources/mysql/mapper/JobTaskBatchMapper.xml index 806b6e3f..431cb4f9 100644 --- a/easy-retry-datasource/easy-retry-mysql-datasource/src/main/resources/mysql/mapper/JobTaskBatchMapper.xml +++ b/easy-retry-datasource/easy-retry-mysql-datasource/src/main/resources/mysql/mapper/JobTaskBatchMapper.xml @@ -13,7 +13,7 @@ - + + diff --git a/easy-retry-datasource/easy-retry-postgres-datasource/src/main/resources/postgres/mapper/JobNotifyConfigMapper.xml b/easy-retry-datasource/easy-retry-postgres-datasource/src/main/resources/postgres/mapper/JobNotifyConfigMapper.xml new file mode 100644 index 00000000..77a2ed70 --- /dev/null +++ b/easy-retry-datasource/easy-retry-postgres-datasource/src/main/resources/postgres/mapper/JobNotifyConfigMapper.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + id,namespace_id, group_name,job_id,notify_status,notify_type, notify_attribute, notify_threshold, notify_scene,rate_limiter_status,rate_limiter_threshold, description, + create_dt, update_dt + + + + diff --git a/easy-retry-datasource/easy-retry-postgres-datasource/src/main/resources/postgres/mapper/JobTaskBatchMapper.xml b/easy-retry-datasource/easy-retry-postgres-datasource/src/main/resources/postgres/mapper/JobTaskBatchMapper.xml index 12cf767f..8a9d4bf4 100644 --- a/easy-retry-datasource/easy-retry-postgres-datasource/src/main/resources/postgres/mapper/JobTaskBatchMapper.xml +++ b/easy-retry-datasource/easy-retry-postgres-datasource/src/main/resources/postgres/mapper/JobTaskBatchMapper.xml @@ -13,7 +13,7 @@ - + + diff --git a/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/dispatch/JobExecutorActor.java b/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/dispatch/JobExecutorActor.java index 62d91b22..70592072 100644 --- a/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/dispatch/JobExecutorActor.java +++ b/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/dispatch/JobExecutorActor.java @@ -18,10 +18,12 @@ import com.aizuda.easy.retry.server.job.task.dto.TaskExecuteDTO; import com.aizuda.easy.retry.server.job.task.support.JobExecutor; import com.aizuda.easy.retry.server.job.task.support.JobTaskConverter; import com.aizuda.easy.retry.server.job.task.support.cache.ResidentTaskCache; +import com.aizuda.easy.retry.server.job.task.support.event.JobTaskFailAlarmEvent; import com.aizuda.easy.retry.server.job.task.support.executor.JobExecutorContext; import com.aizuda.easy.retry.server.job.task.support.executor.JobExecutorFactory; import com.aizuda.easy.retry.server.job.task.support.timer.JobTimerWheel; import com.aizuda.easy.retry.server.job.task.support.timer.ResidentJobTimerTask; +import com.aizuda.easy.retry.server.retry.task.support.event.RetryTaskFailMoreThresholdAlarmEvent; import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobMapper; import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobTaskBatchMapper; import com.aizuda.easy.retry.template.datasource.persistence.po.Job; @@ -30,6 +32,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import org.springframework.transaction.TransactionStatus; @@ -58,6 +61,8 @@ public class JobExecutorActor extends AbstractActor { private JobTaskBatchMapper jobTaskBatchMapper; @Autowired private TransactionTemplate transactionTemplate; + @Autowired + private ApplicationContext context; @Override public Receive createReceive() { @@ -74,7 +79,7 @@ public class JobExecutorActor extends AbstractActor { } catch (Exception e) { LogUtils.error(log, "job executor exception. [{}]", taskExecute, e); handlerTaskBatch(taskExecute, JobTaskBatchStatusEnum.FAIL.getStatus(), JobOperationReasonEnum.TASK_EXECUTE_ERROR.getReason()); - // TODO 告警通知 + context.publishEvent(new JobTaskFailAlarmEvent(taskExecute.getTaskBatchId())); } finally { getContext().stop(getSelf()); } diff --git a/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/event/JobTaskFailAlarmEvent.java b/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/event/JobTaskFailAlarmEvent.java new file mode 100644 index 00000000..f4f62cfe --- /dev/null +++ b/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/event/JobTaskFailAlarmEvent.java @@ -0,0 +1,22 @@ +package com.aizuda.easy.retry.server.job.task.support.event; + +import org.springframework.context.ApplicationEvent; + +/** + * job任务失败事件 + * @author: zuoJunLin + * @date : 2023-12-02 21:40 + * @since 2.5.0 + */ +public class JobTaskFailAlarmEvent extends ApplicationEvent { + private Long jobTaskBatchId; + + public JobTaskFailAlarmEvent(Long jobTaskBatchId) { + super(jobTaskBatchId); + this.jobTaskBatchId=jobTaskBatchId; + } + + public Long getJobTaskBatchId() { + return jobTaskBatchId; + } +} diff --git a/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/listener/JobTaskFailAlarmListener.java b/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/listener/JobTaskFailAlarmListener.java new file mode 100644 index 00000000..e33a27ff --- /dev/null +++ b/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/listener/JobTaskFailAlarmListener.java @@ -0,0 +1,178 @@ +package com.aizuda.easy.retry.server.job.task.support.listener; + +import com.aizuda.easy.retry.common.core.alarm.Alarm; +import com.aizuda.easy.retry.common.core.alarm.AlarmContext; +import com.aizuda.easy.retry.common.core.alarm.EasyRetryAlarmFactory; +import com.aizuda.easy.retry.common.core.enums.JobNotifySceneEnum; +import com.aizuda.easy.retry.common.core.enums.StatusEnum; +import com.aizuda.easy.retry.common.core.log.LogUtils; +import com.aizuda.easy.retry.common.core.util.EnvironmentUtils; +import com.aizuda.easy.retry.common.core.util.HostUtils; +import com.aizuda.easy.retry.server.common.Lifecycle; +import com.aizuda.easy.retry.server.common.triple.ImmutableTriple; +import com.aizuda.easy.retry.server.common.triple.Triple; +import com.aizuda.easy.retry.server.common.util.DateUtils; +import com.aizuda.easy.retry.server.job.task.support.event.JobTaskFailAlarmEvent; +import com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobBatchResponseDO; +import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobNotifyConfigMapper; +import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobTaskBatchMapper; +import com.aizuda.easy.retry.template.datasource.persistence.po.*; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.time.LocalDateTime; +import java.util.*; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.stream.Collectors; + + +/** + * JOB任务执行失败告警 + * + * @author: zuoJunLin + * @date : 2023-12-02 21:40 + * @since 2.5.0 + */ +@Component +@Slf4j +public class JobTaskFailAlarmListener implements ApplicationListener, Runnable, Lifecycle { + + + @Autowired + private JobNotifyConfigMapper jobNotifyConfigMapper; + + @Autowired + private JobTaskBatchMapper jobTaskBatchMapper; + + @Autowired + private EasyRetryAlarmFactory easyRetryAlarmFactory; + + /** + * job任务失败数据 + */ + private LinkedBlockingQueue queue = new LinkedBlockingQueue<>(1000); + + private static String jobTaskFailTextMessagesFormatter = + "{}环境 Job任务执行失败 \n" + + "> 组名称:{} \n" + + "> 任务名称:{} \n" + + "> 执行器名称:{} \n" + + "> 方法参数:{} \n" + + "> 时间:{} \n"; + + private Thread thread; + + @Override + public void start() { + thread = new Thread(this); + thread.start(); + } + + @Override + public void close() { + if (Objects.nonNull(thread)) { + thread.interrupt(); + } + } + + @Override + public void run() { + LogUtils.info(log, "JobTaskFailAlarmListener time[{}] ip:[{}]", LocalDateTime.now(), HostUtils.getIp()); + while (!Thread.currentThread().isInterrupted()) { + try { + // 无数据时阻塞线程 + Long jobTaskBatchId = queue.take(); + // 拉取200条 + List jobTaskBatchIds = Lists.newArrayList(jobTaskBatchId); + queue.drainTo(jobTaskBatchIds, 200); + List jobTaskBatchList = jobTaskBatchMapper.selectJobBatchListByIds(jobTaskBatchIds); + Set namespaceIds = new HashSet<>(); + Set groupNames = new HashSet<>(); + Set jobIds = new HashSet<>(); + Map, List> jobTaskBatchMap = getJobTaskBatchMap( + jobTaskBatchList, namespaceIds, groupNames, jobIds); + + Map, List> jobNotifyConfigMap = getJobNotifyConfigMap( + namespaceIds, groupNames, jobIds); + if (jobNotifyConfigMap == null) { + continue; + } + // 循环发送消息 + jobTaskBatchMap.forEach((key, list) -> { + List jobNotifyConfigsList = jobNotifyConfigMap.get(key); + for (JobBatchResponseDO JobBatch : list) { + for (final JobNotifyConfig jobNotifyConfig : jobNotifyConfigsList) { + // 预警 + AlarmContext context = AlarmContext.build() + .text(jobTaskFailTextMessagesFormatter, + EnvironmentUtils.getActiveProfile(), + JobBatch.getGroupName(), + JobBatch.getJobName(), + JobBatch.getExecutorInfo(), + JobBatch.getArgsStr(), + DateUtils.toNowFormat(DateUtils.NORM_DATETIME_PATTERN)) + .title("{}环境 JOB任务失败", EnvironmentUtils.getActiveProfile()) + .notifyAttribute(jobNotifyConfig.getNotifyAttribute()); + Alarm alarmType = easyRetryAlarmFactory.getAlarmType(jobNotifyConfig.getNotifyType()); + alarmType.asyncSendMessage(context); + } + } + }); + } catch (InterruptedException e) { + LogUtils.info(log, "job task fail more alarm stop"); + Thread.currentThread().interrupt(); + } catch (Exception e) { + LogUtils.error(log, "JobTaskFailAlarmListener queue take Exception", e); + } + } + } + + private Map, List> getJobNotifyConfigMap(Set namespaceIds, Set groupNames, Set jobIds) { + // 批量获取所需的通知配置 + List jobNotifyConfigs = jobNotifyConfigMapper.selectList( + new LambdaQueryWrapper() + .eq(JobNotifyConfig::getNotifyStatus, StatusEnum.YES) + .eq(JobNotifyConfig::getNotifyScene, JobNotifySceneEnum.JOB_TASK_ERROR.getNotifyScene()) + .in(JobNotifyConfig::getNamespaceId, namespaceIds) + .in(JobNotifyConfig::getGroupName, groupNames) + .in(JobNotifyConfig::getJobId, jobIds) + ); + if (CollectionUtils.isEmpty(jobNotifyConfigs)) { + return null; + } + return jobNotifyConfigs.stream() + .collect(Collectors.groupingBy(i -> { + + String namespaceId = i.getNamespaceId(); + String groupName = i.getGroupName(); + Long jobId = i.getJobId(); + + return ImmutableTriple.of(namespaceId, groupName, jobId); + })); + } + + private Map, List> getJobTaskBatchMap(List jobTaskBatchList, Set namespaceIds, Set groupNames, Set jobIds) { + return jobTaskBatchList.stream().collect(Collectors.groupingBy(i -> { + String namespaceId = i.getNamespaceId(); + String groupName = i.getGroupName(); + Long jobId = i.getJobId(); + namespaceIds.add(namespaceId); + groupNames.add(groupName); + jobIds.add(jobId); + return ImmutableTriple.of(namespaceId, groupName, jobId); + })); + } + + + @Override + public void onApplicationEvent(JobTaskFailAlarmEvent event) { + if (queue.offer(event.getJobTaskBatchId())) { + LogUtils.warn(log, "JOB任务执行失败告警队列已满"); + } + } +} diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/JobController.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/JobController.java index d9b060b2..6bbc6b4a 100644 --- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/JobController.java +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/JobController.java @@ -27,12 +27,18 @@ public class JobController { @Autowired private JobService jobService; - @GetMapping("/list") + @GetMapping("/page/list") @LoginRequired public PageResult> getJobPage(JobQueryVO jobQueryVO) { return jobService.getJobPage(jobQueryVO); } + @GetMapping("/list") + @LoginRequired + public List getJobList(@RequestParam("groupName") String groupName) { + return jobService.getJobList(groupName); + } + @GetMapping("{id}") @LoginRequired public JobResponseVO getJobDetail(@PathVariable("id") Long id) { diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/JobNotifyConfigController.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/JobNotifyConfigController.java new file mode 100644 index 00000000..0d41c00d --- /dev/null +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/controller/JobNotifyConfigController.java @@ -0,0 +1,53 @@ +package com.aizuda.easy.retry.server.web.controller; + +import com.aizuda.easy.retry.server.web.annotation.LoginRequired; +import com.aizuda.easy.retry.server.web.model.base.PageResult; +import com.aizuda.easy.retry.server.web.model.request.JobNotifyConfigQueryVO; +import com.aizuda.easy.retry.server.web.model.request.JobNotifyConfigRequestVO; +import com.aizuda.easy.retry.server.web.model.response.JobNotifyConfigResponseVO; +import com.aizuda.easy.retry.server.web.service.JobNotifyConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * Job通知配置接口 + * + * @author: zuoJunLin + * @date : 2023-12-02 11:32 + * @since : 2.5.0 + */ +@RestController +@RequestMapping("/job/notify/config") +public class JobNotifyConfigController { + + @Autowired + private JobNotifyConfigService jobNotifyConfigService; + + @LoginRequired + @GetMapping("/page/list") + public PageResult> getNotifyConfigList(JobNotifyConfigQueryVO queryVO) { + return jobNotifyConfigService.getJobNotifyConfigList(queryVO); + } + + @LoginRequired + @GetMapping("{id}") + public JobNotifyConfigResponseVO getJobNotifyConfigDetail(@PathVariable("id") Long id) { + return jobNotifyConfigService.getJobNotifyConfigDetail(id); + } + + + @LoginRequired + @PostMapping + public Boolean saveNotify(@RequestBody @Validated JobNotifyConfigRequestVO requestVO) { + return jobNotifyConfigService.saveJobNotify(requestVO); + } + + @LoginRequired + @PutMapping + public Boolean updateNotify(@RequestBody @Validated JobNotifyConfigRequestVO requestVO) { + return jobNotifyConfigService.updateJobNotify(requestVO); + } +} diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/JobNotifyConfigQueryVO.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/JobNotifyConfigQueryVO.java new file mode 100644 index 00000000..3c4583f7 --- /dev/null +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/JobNotifyConfigQueryVO.java @@ -0,0 +1,17 @@ +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 zuoJunLin + * @date 2023-12-02 11:16:14 + * @since 2.5.0 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class JobNotifyConfigQueryVO extends BaseQueryVO { + private String groupName; + private Long jobId; +} diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/JobNotifyConfigRequestVO.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/JobNotifyConfigRequestVO.java new file mode 100644 index 00000000..21a3d02b --- /dev/null +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/JobNotifyConfigRequestVO.java @@ -0,0 +1,54 @@ +package com.aizuda.easy.retry.server.web.model.request; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * @author zuoJunLin + * @date 2023-11-02 11:40:10 + * @since 2.5.0 + */ +@Data +public class JobNotifyConfigRequestVO { + + private Long id; + + @NotBlank(message = "组名称 不能为空") + @Pattern(regexp = "^[A-Za-z0-9_]{1,64}$", message = "仅支持长度为1~64字符且类型为数字、字母和下划线") + private String groupName; + + @NotNull(message = "任务不能为空") + private Long jobId; + + @NotNull(message = "通知状态不能为空") + private Integer notifyStatus; + + @NotNull(message = "通知类型不能为空") + private Integer notifyType; + + @NotBlank(message = "通知属性不能为空") + private String notifyAttribute; + + private Integer notifyThreshold; + + @NotNull(message = "通知场景不能为空") + private Integer notifyScene; + + @NotNull(message = "限流状态不能为空") + private Integer rateLimiterStatus; + + private Integer rateLimiterThreshold; + /** + * 描述 + */ + private String description; + + /** + * 是否删除 + */ + private Integer isDeleted; + +} diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/JobNotifyConfigResponseVO.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/JobNotifyConfigResponseVO.java new file mode 100644 index 00000000..9ea5272b --- /dev/null +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/JobNotifyConfigResponseVO.java @@ -0,0 +1,51 @@ +package com.aizuda.easy.retry.server.web.model.response; + +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * @author: zuoJunLin + * @date : 2023-12-02 11:22 + * @since : 2.5.0 + */ +@Data +public class JobNotifyConfigResponseVO implements Serializable { + + private Long id; + + private String namespaceId; + + private String groupName; + + private Long jobId; + + private String jobName; + + private Integer notifyStatus; + + private String notifyName; + + private Integer notifyType; + + private String notifyAttribute; + + private Integer notifyThreshold; + + private Integer notifyScene; + + private Integer rateLimiterStatus; + + private Integer rateLimiterThreshold; + + private String description; + + private LocalDateTime createDt; + + private LocalDateTime updateDt; + + private static final long serialVersionUID = 1L; + + +} diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/JobNotifyConfigService.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/JobNotifyConfigService.java new file mode 100644 index 00000000..9d8d086c --- /dev/null +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/JobNotifyConfigService.java @@ -0,0 +1,27 @@ +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.JobNotifyConfigQueryVO; +import com.aizuda.easy.retry.server.web.model.request.JobNotifyConfigRequestVO; +import com.aizuda.easy.retry.server.web.model.request.NotifyConfigQueryVO; +import com.aizuda.easy.retry.server.web.model.request.NotifyConfigRequestVO; +import com.aizuda.easy.retry.server.web.model.response.JobNotifyConfigResponseVO; +import com.aizuda.easy.retry.server.web.model.response.NotifyConfigResponseVO; + +import java.util.List; + +/** + * @author: zuoJunLin + * @date : 2023-12-02 12:54 + * @since :2.5.0 + */ +public interface JobNotifyConfigService { + + PageResult> getJobNotifyConfigList(JobNotifyConfigQueryVO queryVO); + + Boolean saveJobNotify(JobNotifyConfigRequestVO requestVO); + + Boolean updateJobNotify(JobNotifyConfigRequestVO requestVO); + + JobNotifyConfigResponseVO getJobNotifyConfigDetail(Long id); +} diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/JobService.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/JobService.java index 2c87fbf6..63b63a58 100644 --- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/JobService.java +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/JobService.java @@ -35,4 +35,5 @@ public interface JobService { boolean trigger(Long jobId); + List getJobList(String groupName); } diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/JobNotifyConfigConverter.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/JobNotifyConfigConverter.java new file mode 100644 index 00000000..eb9a18d0 --- /dev/null +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/JobNotifyConfigConverter.java @@ -0,0 +1,18 @@ +package com.aizuda.easy.retry.server.web.service.convert; + +import com.aizuda.easy.retry.server.web.model.request.JobNotifyConfigRequestVO; +import com.aizuda.easy.retry.template.datasource.persistence.po.JobNotifyConfig; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author: zuoJunLin + * @date : 2023-12-02 13:43 + */ +@Mapper +public interface JobNotifyConfigConverter { + + JobNotifyConfigConverter INSTANCE = Mappers.getMapper(JobNotifyConfigConverter.class); + + JobNotifyConfig toJobNotifyConfig(JobNotifyConfigRequestVO jobNotifyConfigVO); +} diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/JobNotifyConfigResponseVOConverter.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/JobNotifyConfigResponseVOConverter.java new file mode 100644 index 00000000..88b287e8 --- /dev/null +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/convert/JobNotifyConfigResponseVOConverter.java @@ -0,0 +1,23 @@ +package com.aizuda.easy.retry.server.web.service.convert; + +import com.aizuda.easy.retry.server.web.model.response.JobNotifyConfigResponseVO; +import com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobNotifyConfigResponseDO; +import com.aizuda.easy.retry.template.datasource.persistence.po.JobNotifyConfig; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * @author: www.byteblogs.com + * @date : 2022-03-03 11:20 + */ +@Mapper +public interface JobNotifyConfigResponseVOConverter { + + JobNotifyConfigResponseVOConverter INSTANCE = Mappers.getMapper(JobNotifyConfigResponseVOConverter.class); + + JobNotifyConfigResponseVO convert(JobNotifyConfig jobNotifyConfig); + + List batchConvert(List jobNotifyConfigs); +} diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/JobBatchServiceImpl.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/JobBatchServiceImpl.java index b36869cd..9e795a39 100644 --- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/JobBatchServiceImpl.java +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/JobBatchServiceImpl.java @@ -60,7 +60,7 @@ public class JobBatchServiceImpl implements JobBatchService { jobBatchQueryDO.setTaskBatchStatus(queryVO.getTaskBatchStatus()); jobBatchQueryDO.setGroupName(queryVO.getGroupName()); jobBatchQueryDO.setNamespaceId(UserSessionUtils.currentUserSession().getNamespaceId()); - List batchResponseDOList = jobTaskBatchMapper.selectJobBatchList(pageDTO, jobBatchQueryDO); + List batchResponseDOList = jobTaskBatchMapper.selectJobBatchPageList(pageDTO, jobBatchQueryDO); List batchResponseVOList = JobBatchResponseVOConverter.INSTANCE.toJobBatchResponseVOs( batchResponseDOList); diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/JobNotifyConfigServiceImpl.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/JobNotifyConfigServiceImpl.java new file mode 100644 index 00000000..106da706 --- /dev/null +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/JobNotifyConfigServiceImpl.java @@ -0,0 +1,83 @@ +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.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.JobNotifyConfigQueryVO; +import com.aizuda.easy.retry.server.web.model.request.JobNotifyConfigRequestVO; +import com.aizuda.easy.retry.server.web.model.response.JobNotifyConfigResponseVO; +import com.aizuda.easy.retry.server.web.service.JobNotifyConfigService; +import com.aizuda.easy.retry.server.web.service.convert.JobNotifyConfigConverter; +import com.aizuda.easy.retry.server.web.service.convert.JobNotifyConfigResponseVOConverter; +import com.aizuda.easy.retry.server.web.util.UserSessionUtils; +import com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobBatchQueryDO; +import com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobBatchResponseDO; +import com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobNotifyConfigQueryDO; +import com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobNotifyConfigResponseDO; +import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobNotifyConfigMapper; +import com.aizuda.easy.retry.template.datasource.persistence.po.JobNotifyConfig; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; + +/** + * @author: zuoJunLin + * @date : 2023-12-02 12:54 + * @since :2.5.0 + */ +@Service +public class JobNotifyConfigServiceImpl implements JobNotifyConfigService { + + @Autowired + private JobNotifyConfigMapper jobNotifyConfigMapper; + + @Override + public PageResult> getJobNotifyConfigList(JobNotifyConfigQueryVO queryVO) { + PageDTO pageDTO = new PageDTO<>(); + JobNotifyConfigQueryDO jobNotifyConfigQueryDO = new JobNotifyConfigQueryDO(); + jobNotifyConfigQueryDO.setNamespaceId(UserSessionUtils.currentUserSession().getNamespaceId()); + if (StrUtil.isNotBlank(queryVO.getGroupName())) { + jobNotifyConfigQueryDO.setGroupName(queryVO.getGroupName()); + } + if (Objects.nonNull(queryVO.getJobId())) { + jobNotifyConfigQueryDO.setJobId(queryVO.getJobId()); + } + List batchResponseDOList = jobNotifyConfigMapper.selectJobNotifyConfigList(pageDTO, jobNotifyConfigQueryDO); + return new PageResult<>(pageDTO, JobNotifyConfigResponseVOConverter.INSTANCE.batchConvert(batchResponseDOList)); + } + + @Override + public Boolean saveJobNotify(JobNotifyConfigRequestVO requestVO) { + JobNotifyConfig jobNotifyConfig = JobNotifyConfigConverter.INSTANCE.toJobNotifyConfig(requestVO); + jobNotifyConfig.setCreateDt(LocalDateTime.now()); + jobNotifyConfig.setNamespaceId(UserSessionUtils.currentUserSession().getNamespaceId()); + Assert.isTrue(1 == jobNotifyConfigMapper.insert(jobNotifyConfig), + () -> new EasyRetryServerException("failed to insert jobNotifyConfig. sceneConfig:[{}]", JsonUtil.toJsonString(jobNotifyConfig))); + return Boolean.TRUE; + } + + @Override + public Boolean updateJobNotify(JobNotifyConfigRequestVO requestVO) { + Assert.notNull(requestVO.getId(), () -> new EasyRetryServerException("参数异常")); + JobNotifyConfig jobNotifyConfig = JobNotifyConfigConverter.INSTANCE.toJobNotifyConfig(requestVO); + // 防止被覆盖 + jobNotifyConfig.setNamespaceId(null); + Assert.isTrue(1 == jobNotifyConfigMapper.updateById(jobNotifyConfig), + () -> new EasyRetryServerException("failed to update jobNotifyConfig. sceneConfig:[{}]", JsonUtil.toJsonString(jobNotifyConfig))); + return Boolean.TRUE; + } + + @Override + public JobNotifyConfigResponseVO getJobNotifyConfigDetail(Long id) { + JobNotifyConfig jobNotifyConfig = jobNotifyConfigMapper.selectOne(new LambdaQueryWrapper() + .eq(JobNotifyConfig::getId, id)); + return JobNotifyConfigResponseVOConverter.INSTANCE.convert(jobNotifyConfig); + } +} diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/JobServiceImpl.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/JobServiceImpl.java index 24780744..0c593979 100644 --- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/JobServiceImpl.java +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/JobServiceImpl.java @@ -22,9 +22,11 @@ import com.aizuda.easy.retry.server.web.model.response.JobResponseVO; import com.aizuda.easy.retry.server.web.service.JobService; import com.aizuda.easy.retry.server.web.service.convert.JobConverter; import com.aizuda.easy.retry.server.web.service.convert.JobResponseVOConverter; +import com.aizuda.easy.retry.server.web.service.convert.SceneConfigResponseVOConverter; import com.aizuda.easy.retry.server.web.util.UserSessionUtils; import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobMapper; import com.aizuda.easy.retry.template.datasource.persistence.po.Job; +import com.aizuda.easy.retry.template.datasource.persistence.po.SceneConfig; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO; import lombok.extern.slf4j.Slf4j; @@ -216,4 +218,16 @@ public class JobServiceImpl implements JobService { return Boolean.TRUE; } -} + + @Override + public List getJobList(String groupName) { + String namespaceId = UserSessionUtils.currentUserSession().getNamespaceId(); + List jobs = jobMapper.selectList(new LambdaQueryWrapper() + .select(Job::getId, Job::getJobName) + .eq(Job::getNamespaceId, namespaceId) + .eq(Job::getGroupName, groupName) + .orderByDesc(Job::getCreateDt)); + List jobResponseList = JobResponseVOConverter.INSTANCE.toJobResponseVOs(jobs); + return jobResponseList; + } +} \ No newline at end of file diff --git a/frontend/src/api/jobApi.js b/frontend/src/api/jobApi.js index 71f7c78f..abdc5273 100644 --- a/frontend/src/api/jobApi.js +++ b/frontend/src/api/jobApi.js @@ -1,6 +1,8 @@ import request from '@/utils/request' +import retryApi from "@/api/retryApi"; const jobApi = { // 任务信息 + jobPageList: '/job/page/list', jobList: '/job/list', jobDetail: '/job/', saveJob: '/job/', @@ -16,6 +18,13 @@ const jobApi = { jobBatchDetail: '/job/batch/', stop: '/job/batch/stop/', + //通知 + jobNotifyConfigPageList: '/job/notify/config/page/list', + jobNotifyConfigDetail: '/job/notify/config/', + saveJobNotify: '/job/notify/config/', + updateJobNotify: '/job/notify/config/', + + // 任务 jobTaskList: '/job/task/list', @@ -101,6 +110,14 @@ export function jobBatchDetail (id) { }) } +export function getJobPageList (parameter) { + return request({ + url: jobApi.jobPageList, + method: 'get', + params: parameter + }) +} + export function getJobList (parameter) { return request({ url: jobApi.jobList, @@ -131,3 +148,33 @@ export function updateJob (data) { data }) } + +export function jobNotifyConfigPageList (parameter) { + return request({ + url: jobApi.jobNotifyConfigPageList, + method: 'get', + params: parameter + }) +} +export function getJobNotifyConfigDetail (id) { + return request({ + url: jobApi.jobNotifyConfigDetail + id, + method: 'get' + }) +} + +export function saveJobNotify (data) { + return request({ + url: jobApi.saveJobNotify, + method: 'post', + data + }) +} + +export function updateJobNotify (data) { + return request({ + url: jobApi.updateJobNotify, + method: 'put', + data + }) +} \ No newline at end of file diff --git a/frontend/src/config/router.config.js b/frontend/src/config/router.config.js index 5d4c2be9..3f1978c2 100644 --- a/frontend/src/config/router.config.js +++ b/frontend/src/config/router.config.js @@ -130,9 +130,9 @@ export const asyncRouterMap = [ }, { path: '/retry/scene/config', - name: 'SceneFrom', + name: 'SceneForm', hidden: true, - component: () => import('@/views/task/form/SceneFrom'), + component: () => import('@/views/task/form/SceneForm.vue'), meta: { title: '场景配置', icon: 'profile', keepAlive: true, permission: ['retryTask'] } }, { @@ -143,9 +143,9 @@ export const asyncRouterMap = [ }, { path: '/retry/notify/config', - name: 'NotifyFrom', + name: 'NotifyForm', hidden: true, - component: () => import('@/views/task/form/NotifyFrom'), + component: () => import('@/views/task/form/NotifyForm.vue'), meta: { title: '通知配置', icon: 'profile', keepAlive: true, permission: ['retryTask'] } } ] @@ -172,9 +172,9 @@ export const asyncRouterMap = [ }, { path: '/job/config', - name: 'JobFrom', + name: 'JobForm', hidden: true, - component: () => import('@/views/job/from/JobFrom'), + component: () => import('@/views/job/form/JobForm.vue'), meta: { title: '任务配置', icon: 'profile', permission: ['job'] } }, { @@ -196,6 +196,19 @@ export const asyncRouterMap = [ hidden: true, component: () => import('@/views/job/JobTaskList'), meta: { title: '任务项', icon: 'profile', permission: ['jobBatch'] } + }, + { + path: '/job/notify/list', + name: 'JobNotifyList', + component: () => import('@/views/job/JobNotifyList'), + meta: { title: '通知列表', icon: 'profile', keepAlive: true, permission: ['jobNotify'] } + }, + { + path: '/job/notify/config', + name: 'JobNotifyForm', + hidden: true, + component: () => import('@/views/job/form/JobNotifyForm.vue'), + meta: { title: '通知配置', icon: 'profile', keepAlive: true, permission: ['jobNotify'] } } ] }, diff --git a/frontend/src/utils/jobEnum.js b/frontend/src/utils/jobEnum.js index 30bd6e4e..ae9af4c7 100644 --- a/frontend/src/utils/jobEnum.js +++ b/frontend/src/utils/jobEnum.js @@ -151,7 +151,45 @@ const enums = { 'name': '停止', 'color': '#ac2df5' } - } + }, + notifyScene: { + '1': { + 'name': '任务执行失败', + 'color': '#d06892' + } + }, + notifyType: { + '1': { + 'name': '钉钉通知', + 'color': '#64a6ea' + }, + '2': { + 'name': '邮箱通知', + 'color': '#1b7ee5' + }, + '4': { + 'name': '飞书', + 'color': '#087da1' + } + }, notifyStatus: { + '0': { + 'name': '停用', + 'color': '#9c1f1f' + }, + '1': { + 'name': '启用', + 'color': '#f5a22d' + } + }, rateLimiterStatus: { + '0': { + 'name': '未启用', + 'color': '#9c1f1f' + }, + '1': { + 'name': '启用', + 'color': '#f5a22d' + } + }, } module.exports = enums diff --git a/frontend/src/utils/permissionsConfig.js b/frontend/src/utils/permissionsConfig.js index 3bb1b618..5d7cde20 100644 --- a/frontend/src/utils/permissionsConfig.js +++ b/frontend/src/utils/permissionsConfig.js @@ -111,6 +111,10 @@ const jobAdmin = [ roleId: 1, permissionId: 'jobBatch', permissionName: '任务批次' + },{ + roleId: 1, + permissionId: 'jobNotify', + permissionName: '任务通知' } ] @@ -171,6 +175,11 @@ const jobUser = [ roleId: 1, permissionId: 'jobBatch', permissionName: '任务批次' + }, + { + roleId: 1, + permissionId: 'jobNotify', + permissionName: '任务通知' } ] diff --git a/frontend/src/utils/retryEnum.js b/frontend/src/utils/retryEnum.js index e6f22c84..a79f11ad 100644 --- a/frontend/src/utils/retryEnum.js +++ b/frontend/src/utils/retryEnum.js @@ -55,11 +55,11 @@ const enums = { 'color': '#a127f3' }, '5': { - 'name': '任务重试数量超过阈值', + 'name': '任务重试失败数量超过阈值', 'color': '#f5a22d' }, '6': { - 'name': '任务失败进入死信队列', + 'name': '任务重试失败进入死信队列', 'color': '#f5a22d' } }, diff --git a/frontend/src/views/job/JobList.vue b/frontend/src/views/job/JobList.vue index f3df270c..33a59761 100644 --- a/frontend/src/views/job/JobList.vue +++ b/frontend/src/views/job/JobList.vue @@ -178,7 +178,7 @@ import ATextarea from 'ant-design-vue/es/input/TextArea' import AInput from 'ant-design-vue/es/input/Input' import { STable, Drawer } from '@/components' -import { delJob, getJobList, triggerJob, updateJobStatus } from '@/api/jobApi' +import { delJob, getJobPageList, triggerJob, updateJobStatus } from '@/api/jobApi' import { getAllGroupNameList } from '@/api/manage' import enums from '@/utils/jobEnum' import JobInfo from '@/views/job/JobInfo' @@ -278,7 +278,7 @@ export default { ], // 加载数据方法 必须为 Promise 对象 loadData: (parameter) => { - return getJobList(Object.assign(parameter, this.queryParam)).then((res) => { + return getJobPageList(Object.assign(parameter, this.queryParam)).then((res) => { return res }) }, diff --git a/frontend/src/views/job/JobNotifyList.vue b/frontend/src/views/job/JobNotifyList.vue new file mode 100644 index 00000000..895b8a58 --- /dev/null +++ b/frontend/src/views/job/JobNotifyList.vue @@ -0,0 +1,247 @@ + + + + diff --git a/frontend/src/views/job/from/CronModal.vue b/frontend/src/views/job/form/CronModal.vue similarity index 100% rename from frontend/src/views/job/from/CronModal.vue rename to frontend/src/views/job/form/CronModal.vue diff --git a/frontend/src/views/job/from/JobFrom.vue b/frontend/src/views/job/form/JobForm.vue similarity index 99% rename from frontend/src/views/job/from/JobFrom.vue rename to frontend/src/views/job/form/JobForm.vue index e8b28147..588f9947 100644 --- a/frontend/src/views/job/from/JobFrom.vue +++ b/frontend/src/views/job/form/JobForm.vue @@ -313,7 +313,7 @@ import { getAllGroupNameList } from '@/api/manage' import { getJobDetail, saveJob, updateJob } from '@/api/jobApi' import pick from 'lodash.pick' -import CronModal from '@/views/job/from/CronModal' +import CronModal from '@/views/job/form/CronModal' import AFormModel from 'ant-design-vue/es/form-model/Form' import AFormModelItem from 'ant-design-vue/es/form-model/FormItem' diff --git a/frontend/src/views/job/form/JobNotifyForm.vue b/frontend/src/views/job/form/JobNotifyForm.vue new file mode 100644 index 00000000..27c5b41b --- /dev/null +++ b/frontend/src/views/job/form/JobNotifyForm.vue @@ -0,0 +1,488 @@ + + + diff --git a/frontend/src/views/task/form/NotifyFrom.vue b/frontend/src/views/task/form/NotifyForm.vue similarity index 97% rename from frontend/src/views/task/form/NotifyFrom.vue rename to frontend/src/views/task/form/NotifyForm.vue index d7efc30c..5be28b7b 100644 --- a/frontend/src/views/task/form/NotifyFrom.vue +++ b/frontend/src/views/task/form/NotifyForm.vue @@ -165,7 +165,7 @@ 被@人手机号  - 被@负责人用户id  + 被@人用户id