From f60855faa03ef21a49bb3532337e0b4d4d004405 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 14 Feb 2021 23:01:21 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E5=AE=8C=E6=88=90=20Job=20=E7=9A=84=20CRU?= =?UTF-8?q?D=20=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi/quartz/config/ScheduleConfig.java | 96 +-- .../controller/SysJobLogController.java | 149 ++--- .../service/impl/SysJobLogServiceImpl.java | 135 ++-- .../ruoyi/quartz/util/AbstractQuartzJob.java | 194 +++--- .../com/ruoyi/quartz/util/ScheduleUtils.java | 88 +-- .../quartz/controller/SysJobController.java | 132 ---- .../service/impl/SysJobServiceImpl.java | 218 ------- .../java/com/ruoyi/quartz/util/CronUtils.java | 53 -- ruoyi-ui/src/api/{monitor => infra}/job.js | 29 +- ruoyi-ui/src/router/index.js | 2 +- ruoyi-ui/src/utils/constants.js | 10 + .../views/{monitor => infra}/druid/index.vue | 52 +- .../views/{monitor => infra}/job/index.vue | 613 +++++++++--------- .../src/views/{monitor => infra}/job/log.vue | 0 .../views/{monitor => infra}/server/index.vue | 418 ++++++------ sql/ruoyi-vue-pro.sql | 185 +++++- .../mybatis/core/mapper/BaseMapperX.java | 4 + .../core/scheduler/SchedulerManager.java | 49 ++ .../framework/quartz/core/util/CronUtils.java | 22 + .../controller/job/InfJobController.java | 37 +- .../infra/dal/dataobject/job/InfJobDO.java | 10 +- .../infra/dal/mysql/job/InfJobMapper.java | 4 + .../infra/enums/InfErrorCodeConstants.java | 5 + .../infra/service/job/InfJobService.java | 22 +- .../service/job/impl/InfJobServiceImpl.java | 116 +++- .../util/collection/CollectionUtils.java | 4 + .../codegen/java/controller/controller.vm | 4 +- 27 files changed, 1277 insertions(+), 1374 deletions(-) rename {ruoyi-quartz => ruoyi-common}/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java (97%) rename {ruoyi-quartz => ruoyi-common}/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java (74%) rename {ruoyi-quartz => ruoyi-common}/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java (66%) rename {ruoyi-quartz => ruoyi-common}/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java (97%) rename {ruoyi-quartz => ruoyi-common}/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java (97%) delete mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java delete mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java delete mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java rename ruoyi-ui/src/api/{monitor => infra}/job.js (72%) rename ruoyi-ui/src/views/{monitor => infra}/druid/index.vue (96%) rename ruoyi-ui/src/views/{monitor => infra}/job/index.vue (84%) rename ruoyi-ui/src/views/{monitor => infra}/job/log.vue (100%) rename ruoyi-ui/src/views/{monitor => infra}/server/index.vue (97%) create mode 100644 src/main/java/cn/iocoder/dashboard/framework/quartz/core/util/CronUtils.java diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java b/ruoyi-common/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java similarity index 97% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java rename to ruoyi-common/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java index 8896ae3e9..f17c7a577 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java +++ b/ruoyi-common/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java @@ -1,48 +1,48 @@ -package com.ruoyi.quartz.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; - -import javax.sql.DataSource; -import java.util.Properties; - -/** - * 定时任务配置 - * - * @author ruoyi - */ -@Configuration -public class ScheduleConfig { - - @Bean - public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) { - SchedulerFactoryBean factory = new SchedulerFactoryBean(); - factory.setDataSource(dataSource); - - // quartz参数 - Properties prop = new Properties(); - prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler"); - prop.put("org.quartz.scheduler.instanceId", "AUTO"); - // 集群配置 - prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); - prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); - prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); - - // sqlserver 启用 - // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); - prop.put("org.quartz.jobStore.misfireThreshold", "12000"); - factory.setQuartzProperties(prop); - - factory.setSchedulerName("RuoyiScheduler"); - // 延时启动 - factory.setStartupDelay(1); - factory.setApplicationContextSchedulerContextKey("applicationContextKey"); - // 可选,QuartzScheduler - // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 - factory.setOverwriteExistingJobs(true); - - - return factory; - } -} +package com.ruoyi.quartz.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.quartz.SchedulerFactoryBean; + +import javax.sql.DataSource; +import java.util.Properties; + +/** + * 定时任务配置 + * + * @author ruoyi + */ +@Configuration +public class ScheduleConfig { + + @Bean + public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) { + SchedulerFactoryBean factory = new SchedulerFactoryBean(); + factory.setDataSource(dataSource); + + // quartz参数 + Properties prop = new Properties(); + prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler"); + prop.put("org.quartz.scheduler.instanceId", "AUTO"); + // 集群配置 + prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); + prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); + prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); + + // sqlserver 启用 + // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); + prop.put("org.quartz.jobStore.misfireThreshold", "12000"); + factory.setQuartzProperties(prop); + + factory.setSchedulerName("RuoyiScheduler"); + // 延时启动 + factory.setStartupDelay(1); + factory.setApplicationContextSchedulerContextKey("applicationContextKey"); + // 可选,QuartzScheduler + // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 + factory.setOverwriteExistingJobs(true); + + + return factory; + } +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java b/ruoyi-common/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java similarity index 74% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java rename to ruoyi-common/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java index f1b4e9564..477e35e24 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java +++ b/ruoyi-common/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java @@ -1,85 +1,64 @@ -package com.ruoyi.quartz.controller; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.quartz.domain.SysJobLog; -import com.ruoyi.quartz.service.ISysJobLogService; - -/** - * 调度日志操作处理 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/monitor/jobLog") -public class SysJobLogController extends BaseController { - @Autowired - private ISysJobLogService jobLogService; - - /** - * 查询定时任务调度日志列表 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:list')") - @GetMapping("/list") - public TableDataInfo list(SysJobLog sysJobLog) { - startPage(); - List list = jobLogService.selectJobLogList(sysJobLog); - return getDataTable(list); - } - - /** - * 导出定时任务调度日志列表 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:export')") - @Log(title = "任务调度日志", businessType = BusinessType.EXPORT) - @GetMapping("/export") - public AjaxResult export(SysJobLog sysJobLog) { - List list = jobLogService.selectJobLogList(sysJobLog); - ExcelUtil util = new ExcelUtil(SysJobLog.class); - return util.exportExcel(list, "调度日志"); - } - - /** - * 根据调度编号获取详细信息 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:query')") - @GetMapping(value = "/{configId}") - public AjaxResult getInfo(@PathVariable Long jobLogId) { - return AjaxResult.success(jobLogService.selectJobLogById(jobLogId)); - } - - - /** - * 删除定时任务调度日志 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:remove')") - @Log(title = "定时任务调度日志", businessType = BusinessType.DELETE) - @DeleteMapping("/{jobLogIds}") - public AjaxResult remove(@PathVariable Long[] jobLogIds) { - return toAjax(jobLogService.deleteJobLogByIds(jobLogIds)); - } - - /** - * 清空定时任务调度日志 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:remove')") - @Log(title = "调度日志", businessType = BusinessType.CLEAN) - @DeleteMapping("/clean") - public AjaxResult clean() { - jobLogService.cleanJobLog(); - return AjaxResult.success(); - } -} +package com.ruoyi.quartz.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.quartz.domain.SysJobLog; +import com.ruoyi.quartz.service.ISysJobLogService; + +/** + * 调度日志操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/jobLog") +public class SysJobLogController extends BaseController { + @Autowired + private ISysJobLogService jobLogService; + + /** + * 查询定时任务调度日志列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:list')") + @GetMapping("/list") + public TableDataInfo list(SysJobLog sysJobLog) { + startPage(); + List list = jobLogService.selectJobLogList(sysJobLog); + return getDataTable(list); + } + + /** + * 导出定时任务调度日志列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:export')") + @Log(title = "任务调度日志", businessType = BusinessType.EXPORT) + @GetMapping("/export") + public AjaxResult export(SysJobLog sysJobLog) { + List list = jobLogService.selectJobLogList(sysJobLog); + ExcelUtil util = new ExcelUtil(SysJobLog.class); + return util.exportExcel(list, "调度日志"); + } + + /** + * 根据调度编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:query')") + @GetMapping(value = "/{configId}") + public AjaxResult getInfo(@PathVariable Long jobLogId) { + return AjaxResult.success(jobLogService.selectJobLogById(jobLogId)); + } + +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java b/ruoyi-common/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java similarity index 66% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java rename to ruoyi-common/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java index 9ce6d8230..443d830e4 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java +++ b/ruoyi-common/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java @@ -1,81 +1,54 @@ -package com.ruoyi.quartz.service.impl; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import com.ruoyi.quartz.domain.SysJobLog; -import com.ruoyi.quartz.mapper.SysJobLogMapper; -import com.ruoyi.quartz.service.ISysJobLogService; - -/** - * 定时任务调度日志信息 服务层 - * - * @author ruoyi - */ -@Service -public class SysJobLogServiceImpl implements ISysJobLogService { - @Autowired - private SysJobLogMapper jobLogMapper; - - /** - * 获取quartz调度器日志的计划任务 - * - * @param jobLog 调度日志信息 - * @return 调度任务日志集合 - */ - @Override - public List selectJobLogList(SysJobLog jobLog) { - return jobLogMapper.selectJobLogList(jobLog); - } - - /** - * 通过调度任务日志ID查询调度信息 - * - * @param jobLogId 调度任务日志ID - * @return 调度任务日志对象信息 - */ - @Override - public SysJobLog selectJobLogById(Long jobLogId) { - return jobLogMapper.selectJobLogById(jobLogId); - } - - /** - * 新增任务日志 - * - * @param jobLog 调度日志信息 - */ - @Override - public void addJobLog(SysJobLog jobLog) { - jobLogMapper.insertJobLog(jobLog); - } - - /** - * 批量删除调度日志信息 - * - * @param logIds 需要删除的数据ID - * @return 结果 - */ - @Override - public int deleteJobLogByIds(Long[] logIds) { - return jobLogMapper.deleteJobLogByIds(logIds); - } - - /** - * 删除任务日志 - * - * @param jobId 调度日志ID - */ - @Override - public int deleteJobLogById(Long jobId) { - return jobLogMapper.deleteJobLogById(jobId); - } - - /** - * 清空任务日志 - */ - @Override - public void cleanJobLog() { - jobLogMapper.cleanJobLog(); - } -} +package com.ruoyi.quartz.service.impl; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.quartz.domain.SysJobLog; +import com.ruoyi.quartz.mapper.SysJobLogMapper; +import com.ruoyi.quartz.service.ISysJobLogService; + +/** + * 定时任务调度日志信息 服务层 + * + * @author ruoyi + */ +@Service +public class SysJobLogServiceImpl implements ISysJobLogService { + + @Autowired + private SysJobLogMapper jobLogMapper; + + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + @Override + public List selectJobLogList(SysJobLog jobLog) { + return jobLogMapper.selectJobLogList(jobLog); + } + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + @Override + public SysJobLog selectJobLogById(Long jobLogId) { + return jobLogMapper.selectJobLogById(jobLogId); + } + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + @Override + public void addJobLog(SysJobLog jobLog) { + jobLogMapper.insertJobLog(jobLog); + } + +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java b/ruoyi-common/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java similarity index 97% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java rename to ruoyi-common/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java index 0b2fe9d28..f3db6aa10 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java +++ b/ruoyi-common/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java @@ -1,97 +1,97 @@ -package com.ruoyi.quartz.util; - -import java.util.Date; - -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.constant.ScheduleConstants; -import com.ruoyi.common.utils.ExceptionUtil; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.bean.BeanUtils; -import com.ruoyi.common.utils.spring.SpringUtils; -import com.ruoyi.quartz.domain.SysJob; -import com.ruoyi.quartz.domain.SysJobLog; -import com.ruoyi.quartz.service.ISysJobLogService; - -/** - * 抽象quartz调用 - * - * @author ruoyi - */ -public abstract class AbstractQuartzJob implements Job { - private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class); - - /** - * 线程本地变量 - */ - private static ThreadLocal threadLocal = new ThreadLocal<>(); - - @Override - public void execute(JobExecutionContext context) throws JobExecutionException { - SysJob sysJob = new SysJob(); - BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); - try { - before(context, sysJob); - if (sysJob != null) { - doExecute(context, sysJob); - } - after(context, sysJob, null); - } catch (Exception e) { - log.error("任务执行异常 - :", e); - after(context, sysJob, e); - } - } - - /** - * 执行前 - * - * @param context 工作执行上下文对象 - * @param sysJob 系统计划任务 - */ - protected void before(JobExecutionContext context, SysJob sysJob) { - threadLocal.set(new Date()); - } - - /** - * 执行后 - * - * @param context 工作执行上下文对象 - * @param sysJob 系统计划任务 - */ - protected void after(JobExecutionContext context, SysJob sysJob, Exception e) { - Date startTime = threadLocal.get(); - threadLocal.remove(); - - final SysJobLog sysJobLog = new SysJobLog(); - sysJobLog.setJobName(sysJob.getJobName()); - sysJobLog.setJobGroup(sysJob.getJobGroup()); - sysJobLog.setInvokeTarget(sysJob.getInvokeTarget()); - sysJobLog.setStartTime(startTime); - sysJobLog.setStopTime(new Date()); - long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime(); - sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒"); - if (e != null) { - sysJobLog.setStatus(Constants.FAIL); - String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000); - sysJobLog.setExceptionInfo(errorMsg); - } else { - sysJobLog.setStatus(Constants.SUCCESS); - } - - // 写入数据库当中 - SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog); - } - - /** - * 执行方法,由子类重载 - * - * @param context 工作执行上下文对象 - * @param sysJob 系统计划任务 - * @throws Exception 执行过程中的异常 - */ - protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception; -} +package com.ruoyi.quartz.util; + +import java.util.Date; + +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.ScheduleConstants; +import com.ruoyi.common.utils.ExceptionUtil; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.quartz.domain.SysJob; +import com.ruoyi.quartz.domain.SysJobLog; +import com.ruoyi.quartz.service.ISysJobLogService; + +/** + * 抽象quartz调用 + * + * @author ruoyi + */ +public abstract class AbstractQuartzJob implements Job { + private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class); + + /** + * 线程本地变量 + */ + private static ThreadLocal threadLocal = new ThreadLocal<>(); + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + SysJob sysJob = new SysJob(); + BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); + try { + before(context, sysJob); + if (sysJob != null) { + doExecute(context, sysJob); + } + after(context, sysJob, null); + } catch (Exception e) { + log.error("任务执行异常 - :", e); + after(context, sysJob, e); + } + } + + /** + * 执行前 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void before(JobExecutionContext context, SysJob sysJob) { + threadLocal.set(new Date()); + } + + /** + * 执行后 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void after(JobExecutionContext context, SysJob sysJob, Exception e) { + Date startTime = threadLocal.get(); + threadLocal.remove(); + + final SysJobLog sysJobLog = new SysJobLog(); + sysJobLog.setJobName(sysJob.getJobName()); + sysJobLog.setJobGroup(sysJob.getJobGroup()); + sysJobLog.setInvokeTarget(sysJob.getInvokeTarget()); + sysJobLog.setStartTime(startTime); + sysJobLog.setStopTime(new Date()); + long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime(); + sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒"); + if (e != null) { + sysJobLog.setStatus(Constants.FAIL); + String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000); + sysJobLog.setExceptionInfo(errorMsg); + } else { + sysJobLog.setStatus(Constants.SUCCESS); + } + + // 写入数据库当中 + SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog); + } + + /** + * 执行方法,由子类重载 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + * @throws Exception 执行过程中的异常 + */ + protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception; +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java b/ruoyi-common/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java similarity index 97% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java rename to ruoyi-common/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java index a72fa96f6..7aca21ddd 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java @@ -1,44 +1,44 @@ -package com.ruoyi.quartz.util; - -import org.quartz.CronScheduleBuilder; -import org.quartz.CronTrigger; -import org.quartz.Job; -import org.quartz.JobBuilder; -import org.quartz.JobDetail; -import org.quartz.JobKey; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.TriggerBuilder; -import org.quartz.TriggerKey; -import com.ruoyi.common.constant.ScheduleConstants; -import com.ruoyi.common.exception.job.TaskException; -import com.ruoyi.common.exception.job.TaskException.Code; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 定时任务工具类 - * - * @author ruoyi - */ -public class ScheduleUtils { - - /** - * 设置定时任务策略 - */ - public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) - throws TaskException { - switch (job.getMisfirePolicy()) { - case ScheduleConstants.MISFIRE_DEFAULT: - return cb; - case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: - return cb.withMisfireHandlingInstructionIgnoreMisfires(); - case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: - return cb.withMisfireHandlingInstructionFireAndProceed(); - case ScheduleConstants.MISFIRE_DO_NOTHING: - return cb.withMisfireHandlingInstructionDoNothing(); - default: - throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() - + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); - } - } -} +package com.ruoyi.quartz.util; + +import org.quartz.CronScheduleBuilder; +import org.quartz.CronTrigger; +import org.quartz.Job; +import org.quartz.JobBuilder; +import org.quartz.JobDetail; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.TriggerBuilder; +import org.quartz.TriggerKey; +import com.ruoyi.common.constant.ScheduleConstants; +import com.ruoyi.common.exception.job.TaskException; +import com.ruoyi.common.exception.job.TaskException.Code; +import com.ruoyi.quartz.domain.SysJob; + +/** + * 定时任务工具类 + * + * @author ruoyi + */ +public class ScheduleUtils { + + /** + * 设置定时任务策略 + */ + public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) + throws TaskException { + switch (job.getMisfirePolicy()) { + case ScheduleConstants.MISFIRE_DEFAULT: + return cb; + case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: + return cb.withMisfireHandlingInstructionIgnoreMisfires(); + case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: + return cb.withMisfireHandlingInstructionFireAndProceed(); + case ScheduleConstants.MISFIRE_DO_NOTHING: + return cb.withMisfireHandlingInstructionDoNothing(); + default: + throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() + + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); + } + } +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java deleted file mode 100644 index 289e8b283..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.ruoyi.quartz.controller; - -import java.util.List; - -import org.quartz.SchedulerException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import com.ruoyi.common.annotation.Log; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.exception.job.TaskException; -import com.ruoyi.common.utils.SecurityUtils; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.quartz.domain.SysJob; -import com.ruoyi.quartz.service.ISysJobService; -import com.ruoyi.quartz.util.CronUtils; - -/** - * 调度任务信息操作处理 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/monitor/job") -public class SysJobController extends BaseController { - @Autowired - private ISysJobService jobService; - - /** - * 查询定时任务列表 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:list')") - @GetMapping("/list") - public TableDataInfo list(SysJob sysJob) { - startPage(); - List list = jobService.selectJobList(sysJob); - return getDataTable(list); - } - - /** - * 导出定时任务列表 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:export')") - @Log(title = "定时任务", businessType = BusinessType.EXPORT) - @GetMapping("/export") - public AjaxResult export(SysJob sysJob) { - List list = jobService.selectJobList(sysJob); - ExcelUtil util = new ExcelUtil(SysJob.class); - return util.exportExcel(list, "定时任务"); - } - - /** - * 获取定时任务详细信息 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:query')") - @GetMapping(value = "/{jobId}") - public AjaxResult getInfo(@PathVariable("jobId") Long jobId) { - return AjaxResult.success(jobService.selectJobById(jobId)); - } - - /** - * 新增定时任务 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:add')") - @Log(title = "定时任务", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@RequestBody SysJob sysJob) throws SchedulerException, TaskException { - if (!CronUtils.isValid(sysJob.getCronExpression())) { - return AjaxResult.error("cron表达式不正确"); - } - sysJob.setCreateBy(SecurityUtils.getUsername()); - return toAjax(jobService.insertJob(sysJob)); - } - - /** - * 修改定时任务 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:edit')") - @Log(title = "定时任务", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@RequestBody SysJob sysJob) throws SchedulerException, TaskException { - if (!CronUtils.isValid(sysJob.getCronExpression())) { - return AjaxResult.error("cron表达式不正确"); - } - sysJob.setUpdateBy(SecurityUtils.getUsername()); - return toAjax(jobService.updateJob(sysJob)); - } - - /** - * 定时任务状态修改 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") - @Log(title = "定时任务", businessType = BusinessType.UPDATE) - @PutMapping("/changeStatus") - public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException { - SysJob newJob = jobService.selectJobById(job.getJobId()); - newJob.setStatus(job.getStatus()); - return toAjax(jobService.changeStatus(newJob)); - } - - /** - * 定时任务立即执行一次 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") - @Log(title = "定时任务", businessType = BusinessType.UPDATE) - @PutMapping("/run") - public AjaxResult run(@RequestBody SysJob job) throws SchedulerException { - jobService.run(job); - return AjaxResult.success(); - } - - /** - * 删除定时任务 - */ - @PreAuthorize("@ss.hasPermi('monitor:job:remove')") - @Log(title = "定时任务", businessType = BusinessType.DELETE) - @DeleteMapping("/{jobIds}") - public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException { - jobService.deleteJobByIds(jobIds); - return AjaxResult.success(); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java deleted file mode 100644 index e148822bc..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java +++ /dev/null @@ -1,218 +0,0 @@ -package com.ruoyi.quartz.service.impl; - -import java.util.List; -import javax.annotation.PostConstruct; - -import org.quartz.JobDataMap; -import org.quartz.JobKey; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import com.ruoyi.common.constant.ScheduleConstants; -import com.ruoyi.common.exception.job.TaskException; -import com.ruoyi.quartz.domain.SysJob; -import com.ruoyi.quartz.mapper.SysJobMapper; -import com.ruoyi.quartz.service.ISysJobService; -import com.ruoyi.quartz.util.CronUtils; -import com.ruoyi.quartz.util.ScheduleUtils; - -/** - * 定时任务调度信息 服务层 - * - * @author ruoyi - */ -@Service -public class SysJobServiceImpl implements ISysJobService { - @Autowired - private Scheduler scheduler; - - @Autowired - private SysJobMapper jobMapper; - - /** - * 获取quartz调度器的计划任务列表 - * - * @param job 调度信息 - * @return - */ - @Override - public List selectJobList(SysJob job) { - return jobMapper.selectJobList(job); - } - - /** - * 通过调度任务ID查询调度信息 - * - * @param jobId 调度任务ID - * @return 调度任务对象信息 - */ - @Override - public SysJob selectJobById(Long jobId) { - return jobMapper.selectJobById(jobId); - } - - /** - * 暂停任务 - * - * @param job 调度信息 - */ - @Override - @Transactional - public int pauseJob(SysJob job) throws SchedulerException { - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); - int rows = jobMapper.updateJob(job); - if (rows > 0) { - scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); - } - return rows; - } - - /** - * 恢复任务 - * - * @param job 调度信息 - */ - @Override - @Transactional - public int resumeJob(SysJob job) throws SchedulerException { - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - job.setStatus(ScheduleConstants.Status.NORMAL.getValue()); - int rows = jobMapper.updateJob(job); - if (rows > 0) { - scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup)); - } - return rows; - } - - /** - * 删除任务后,所对应的trigger也将被删除 - * - * @param job 调度信息 - */ - @Override - @Transactional - public int deleteJob(SysJob job) throws SchedulerException { - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - int rows = jobMapper.deleteJobById(jobId); - if (rows > 0) { - scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup)); - } - return rows; - } - - /** - * 批量删除调度信息 - * - * @param jobIds 需要删除的任务ID - * @return 结果 - */ - @Override - @Transactional - public void deleteJobByIds(Long[] jobIds) throws SchedulerException { - for (Long jobId : jobIds) { - SysJob job = jobMapper.selectJobById(jobId); - deleteJob(job); - } - } - - /** - * 任务调度状态修改 - * - * @param job 调度信息 - */ - @Override - @Transactional - public int changeStatus(SysJob job) throws SchedulerException { - int rows = 0; - String status = job.getStatus(); - if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) { - rows = resumeJob(job); - } else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) { - rows = pauseJob(job); - } - return rows; - } - - /** - * 立即运行任务 - * - * @param job 调度信息 - */ - @Override - @Transactional - public void run(SysJob job) throws SchedulerException { - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - SysJob properties = selectJobById(job.getJobId()); - // 参数 - JobDataMap dataMap = new JobDataMap(); - dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties); - scheduler.triggerJob(ScheduleUtils.getJobKey(jobId, jobGroup), dataMap); - } - - /** - * 新增任务 - * - * @param job 调度信息 调度信息 - */ - @Override - @Transactional - public int insertJob(SysJob job) throws SchedulerException, TaskException { - job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); - int rows = jobMapper.insertJob(job); - if (rows > 0) { - ScheduleUtils.createScheduleJob(scheduler, job); - } - return rows; - } - - /** - * 更新任务的时间表达式 - * - * @param job 调度信息 - */ - @Override - @Transactional - public int updateJob(SysJob job) throws SchedulerException, TaskException { - SysJob properties = selectJobById(job.getJobId()); - int rows = jobMapper.updateJob(job); - if (rows > 0) { - updateSchedulerJob(job, properties.getJobGroup()); - } - return rows; - } - - /** - * 更新任务 - * - * @param job 任务对象 - * @param jobGroup 任务组名 - */ - public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException { - Long jobId = job.getJobId(); - // 判断是否存在 - JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); - if (scheduler.checkExists(jobKey)) { - // 防止创建时存在数据问题 先移除,然后在执行创建操作 - scheduler.deleteJob(jobKey); - } - ScheduleUtils.createScheduleJob(scheduler, job); - } - - /** - * 校验cron表达式是否有效 - * - * @param cronExpression 表达式 - * @return 结果 - */ - @Override - public boolean checkCronExpressionIsValid(String cronExpression) { - return CronUtils.isValid(cronExpression); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java deleted file mode 100644 index 31c4e819b..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.ruoyi.quartz.util; - -import java.text.ParseException; -import java.util.Date; - -import org.quartz.CronExpression; - -/** - * cron表达式工具类 - * - * @author ruoyi - */ -public class CronUtils { - /** - * 返回一个布尔值代表一个给定的Cron表达式的有效性 - * - * @param cronExpression Cron表达式 - * @return boolean 表达式是否有效 - */ - public static boolean isValid(String cronExpression) { - return CronExpression.isValidExpression(cronExpression); - } - - /** - * 返回一个字符串值,表示该消息无效Cron表达式给出有效性 - * - * @param cronExpression Cron表达式 - * @return String 无效时返回表达式错误描述,如果有效返回null - */ - public static String getInvalidMessage(String cronExpression) { - try { - new CronExpression(cronExpression); - return null; - } catch (ParseException pe) { - return pe.getMessage(); - } - } - - /** - * 返回下一个执行时间根据给定的Cron表达式 - * - * @param cronExpression Cron表达式 - * @return Date 下次Cron表达式执行时间 - */ - public static Date getNextExecution(String cronExpression) { - try { - CronExpression cron = new CronExpression(cronExpression); - return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis())); - } catch (ParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } - } -} diff --git a/ruoyi-ui/src/api/monitor/job.js b/ruoyi-ui/src/api/infra/job.js similarity index 72% rename from ruoyi-ui/src/api/monitor/job.js rename to ruoyi-ui/src/api/infra/job.js index c46a46f25..48196cf99 100644 --- a/ruoyi-ui/src/api/monitor/job.js +++ b/ruoyi-ui/src/api/infra/job.js @@ -46,35 +46,30 @@ export function delJob(jobId) { // 导出定时任务调度 export function exportJob(query) { return request({ - url: '/infra/job/export', + url: '/infra/job/export-excel', method: 'get', - params: query + params: query, + responseType: 'blob' }) } // 任务状态修改 -export function changeJobStatus(jobId, status) { - const data = { - jobId, - status - } +export function updateJobStatus(jobId, status) { return request({ - url: '/monitor/job/changeStatus', + url: '/infra/job/update-status', method: 'put', - data: data + headers:{ + 'Content-type': 'application/x-www-form-urlencoded' + }, + data: 'id=' + jobId + "&status=" + status, }) } // 定时任务立即执行一次 -export function runJob(jobId, jobGroup) { - const data = { - jobId, - jobGroup - } +export function runJob(jobId) { return request({ - url: '/monitor/job/run', - method: 'put', - data: data + url: '/infra/job/trigger?id=' + jobId, + method: 'put' }) } diff --git a/ruoyi-ui/src/router/index.js b/ruoyi-ui/src/router/index.js index 25d9251fa..b4216c0db 100644 --- a/ruoyi-ui/src/router/index.js +++ b/ruoyi-ui/src/router/index.js @@ -100,7 +100,7 @@ export const constantRoutes = [ children: [ { path: 'log', - component: (resolve) => require(['@/views/monitor/job/log'], resolve), + component: (resolve) => require(['@/views/infra/job/log'], resolve), name: 'JobLog', meta: { title: '调度日志' } } diff --git a/ruoyi-ui/src/utils/constants.js b/ruoyi-ui/src/utils/constants.js index 586e2de1d..8dc1492b1 100644 --- a/ruoyi-ui/src/utils/constants.js +++ b/ruoyi-ui/src/utils/constants.js @@ -48,3 +48,13 @@ export const ToolCodegenTemplateTypeEnum = { TREE: 2, // 树形 CRUD SUB: 3, // 主子表 CRUD } + +/** + * 任务状态的枚举 + */ +export const InfJobStatusEnum = { + INIT: 0, // 初始化中 + NORMAL: 1, // 开启运行 + EXCEPTION: 2, // 异常运行 + STOP: 3, // 暂停运行 +} diff --git a/ruoyi-ui/src/views/monitor/druid/index.vue b/ruoyi-ui/src/views/infra/druid/index.vue similarity index 96% rename from ruoyi-ui/src/views/monitor/druid/index.vue rename to ruoyi-ui/src/views/infra/druid/index.vue index 9e8e1e75b..da5b08f39 100644 --- a/ruoyi-ui/src/views/monitor/druid/index.vue +++ b/ruoyi-ui/src/views/infra/druid/index.vue @@ -1,26 +1,26 @@ -