From efbd8cad495f5e5769f3fd551d1cd0e326eae90f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 14 Feb 2021 11:03:13 +0800 Subject: [PATCH] =?UTF-8?q?Job=20=E4=BB=A3=E7=A0=81=E7=9A=84=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi/quartz/config/ScheduleConfig.java | 12 +- .../quartz/service/ISysJobLogService.java | 56 ------ .../ruoyi/quartz/service/ISysJobService.java | 102 ----------- .../service/impl/SysJobServiceImpl.java | 12 -- .../java/com/ruoyi/quartz/task/RyTask.java | 24 --- .../com/ruoyi/quartz/util/JobInvokeUtil.java | 159 ------------------ .../QuartzDisallowConcurrentExecution.java | 18 -- .../ruoyi/quartz/util/QuartzJobExecution.java | 16 -- .../com/ruoyi/quartz/util/ScheduleUtils.java | 59 ------- .../controller/job/InfJobController.java | 99 +++++++++++ .../controller/job/vo/job/InfJobBaseVO.java | 57 +++++++ .../job/vo/job/InfJobCreateReqVO.java | 14 ++ .../controller/job/vo/job/InfJobExcelVO.java | 57 +++++++ .../job/vo/job/InfJobExportReqVO.java | 20 +++ .../job/vo/job/InfJobPageReqVO.java | 25 +++ .../controller/job/vo/job/InfJobRespVO.java | 23 +++ .../job/vo/job/InfJobUpdateReqVO.java | 21 +++ .../infra/convert/job/InfJobConvert.java | 36 ++++ .../infra/dal/dataobject/job/InfJobDO.java | 10 +- .../infra/dal/mysql/job/InfJobMapper.java | 37 ++++ .../modules/infra/dal/mysql/package-info.java | 1 - .../infra/enums/InfErrorCodeConstants.java | 3 + .../infra/service/job/InfJobService.java | 75 +++++++++ .../service/job/impl/InfJobServiceImpl.java | 86 ++++++++++ .../modules/infra/service/package-info.java | 1 - .../system/enums/dict/SysDictTypeEnum.java | 1 + .../codegen/java/controller/vo/baseVO.vm | 10 ++ .../core/scheduler/SchedulerManagerTest.java | 6 + 28 files changed, 578 insertions(+), 462 deletions(-) delete mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java delete mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java delete mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java delete mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java delete mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java delete mode 100644 ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/InfJobController.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobBaseVO.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobCreateReqVO.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobExcelVO.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobExportReqVO.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobPageReqVO.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobRespVO.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobUpdateReqVO.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/convert/job/InfJobConvert.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/dal/mysql/job/InfJobMapper.java delete mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/dal/mysql/package-info.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobService.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java delete mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/service/package-info.java diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java index e3c08fb88..8896ae3e9 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java @@ -14,6 +14,7 @@ import java.util.Properties; */ @Configuration public class ScheduleConfig { + @Bean public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) { SchedulerFactoryBean factory = new SchedulerFactoryBean(); @@ -23,14 +24,7 @@ public class ScheduleConfig { Properties prop = new Properties(); prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler"); prop.put("org.quartz.scheduler.instanceId", "AUTO"); - // 线程池配置 - prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); - prop.put("org.quartz.threadPool.threadCount", "20"); - prop.put("org.quartz.threadPool.threadPriority", "5"); - // JobStore配置 - prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX"); // 集群配置 - prop.put("org.quartz.jobStore.isClustered", "true"); prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); @@ -38,7 +32,6 @@ public class ScheduleConfig { // sqlserver 启用 // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); prop.put("org.quartz.jobStore.misfireThreshold", "12000"); - prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); factory.setQuartzProperties(prop); factory.setSchedulerName("RuoyiScheduler"); @@ -48,8 +41,7 @@ public class ScheduleConfig { // 可选,QuartzScheduler // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 factory.setOverwriteExistingJobs(true); - // 设置自动启动,默认为true - factory.setAutoStartup(true); + return factory; } diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java deleted file mode 100644 index 07d36b959..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ruoyi.quartz.service; - -import java.util.List; - -import com.ruoyi.quartz.domain.SysJobLog; - -/** - * 定时任务调度日志信息信息 服务层 - * - * @author ruoyi - */ -public interface ISysJobLogService { - /** - * 获取quartz调度器日志的计划任务 - * - * @param jobLog 调度日志信息 - * @return 调度任务日志集合 - */ - public List selectJobLogList(SysJobLog jobLog); - - /** - * 通过调度任务日志ID查询调度信息 - * - * @param jobLogId 调度任务日志ID - * @return 调度任务日志对象信息 - */ - public SysJobLog selectJobLogById(Long jobLogId); - - /** - * 新增任务日志 - * - * @param jobLog 调度日志信息 - */ - public void addJobLog(SysJobLog jobLog); - - /** - * 批量删除调度日志信息 - * - * @param logIds 需要删除的日志ID - * @return 结果 - */ - public int deleteJobLogByIds(Long[] logIds); - - /** - * 删除任务日志 - * - * @param jobId 调度日志ID - * @return 结果 - */ - public int deleteJobLogById(Long jobId); - - /** - * 清空任务日志 - */ - public void cleanJobLog(); -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java deleted file mode 100644 index ec68c085a..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.ruoyi.quartz.service; - -import java.util.List; - -import org.quartz.SchedulerException; -import com.ruoyi.common.exception.job.TaskException; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 定时任务调度信息信息 服务层 - * - * @author ruoyi - */ -public interface ISysJobService { - /** - * 获取quartz调度器的计划任务 - * - * @param job 调度信息 - * @return 调度任务集合 - */ - public List selectJobList(SysJob job); - - /** - * 通过调度任务ID查询调度信息 - * - * @param jobId 调度任务ID - * @return 调度任务对象信息 - */ - public SysJob selectJobById(Long jobId); - - /** - * 暂停任务 - * - * @param job 调度信息 - * @return 结果 - */ - public int pauseJob(SysJob job) throws SchedulerException; - - /** - * 恢复任务 - * - * @param job 调度信息 - * @return 结果 - */ - public int resumeJob(SysJob job) throws SchedulerException; - - /** - * 删除任务后,所对应的trigger也将被删除 - * - * @param job 调度信息 - * @return 结果 - */ - public int deleteJob(SysJob job) throws SchedulerException; - - /** - * 批量删除调度信息 - * - * @param jobIds 需要删除的任务ID - * @return 结果 - */ - public void deleteJobByIds(Long[] jobIds) throws SchedulerException; - - /** - * 任务调度状态修改 - * - * @param job 调度信息 - * @return 结果 - */ - public int changeStatus(SysJob job) throws SchedulerException; - - /** - * 立即运行任务 - * - * @param job 调度信息 - * @return 结果 - */ - public void run(SysJob job) throws SchedulerException; - - /** - * 新增任务 - * - * @param job 调度信息 - * @return 结果 - */ - public int insertJob(SysJob job) throws SchedulerException, TaskException; - - /** - * 更新任务 - * - * @param job 调度信息 - * @return 结果 - */ - public int updateJob(SysJob job) throws SchedulerException, TaskException; - - /** - * 校验cron表达式是否有效 - * - * @param cronExpression 表达式 - * @return 结果 - */ - public boolean checkCronExpressionIsValid(String cronExpression); -} 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 index b5ce72c5d..e148822bc 100644 --- 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 @@ -31,18 +31,6 @@ public class SysJobServiceImpl implements ISysJobService { @Autowired private SysJobMapper jobMapper; - /** - * 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据) - */ - @PostConstruct - public void init() throws SchedulerException, TaskException { - scheduler.clear(); - List jobList = jobMapper.selectJobAll(); - for (SysJob job : jobList) { - ScheduleUtils.createScheduleJob(scheduler, job); - } - } - /** * 获取quartz调度器的计划任务列表 * diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java deleted file mode 100644 index 6a6e1fdf1..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.ruoyi.quartz.task; - -import org.springframework.stereotype.Component; -import com.ruoyi.common.utils.StringUtils; - -/** - * 定时任务调度测试 - * - * @author ruoyi - */ -@Component("ryTask") -public class RyTask { - public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) { - System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); - } - - public void ryParams(String params) { - System.out.println("执行有参方法:" + params); - } - - public void ryNoParams() { - System.out.println("执行无参方法"); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java deleted file mode 100644 index ade0f8624..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.ruoyi.quartz.util; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.LinkedList; -import java.util.List; - -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.spring.SpringUtils; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 任务执行工具 - * - * @author ruoyi - */ -public class JobInvokeUtil { - /** - * 执行方法 - * - * @param sysJob 系统任务 - */ - public static void invokeMethod(SysJob sysJob) throws Exception { - String invokeTarget = sysJob.getInvokeTarget(); - String beanName = getBeanName(invokeTarget); - String methodName = getMethodName(invokeTarget); - List methodParams = getMethodParams(invokeTarget); - - if (!isValidClassName(beanName)) { - Object bean = SpringUtils.getBean(beanName); - invokeMethod(bean, methodName, methodParams); - } else { - Object bean = Class.forName(beanName).newInstance(); - invokeMethod(bean, methodName, methodParams); - } - } - - /** - * 调用任务方法 - * - * @param bean 目标对象 - * @param methodName 方法名称 - * @param methodParams 方法参数 - */ - private static void invokeMethod(Object bean, String methodName, List methodParams) - throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, - InvocationTargetException { - if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) { - Method method = bean.getClass().getDeclaredMethod(methodName, getMethodParamsType(methodParams)); - method.invoke(bean, getMethodParamsValue(methodParams)); - } else { - Method method = bean.getClass().getDeclaredMethod(methodName); - method.invoke(bean); - } - } - - /** - * 校验是否为为class包名 - * - * @param str 名称 - * @return true是 false否 - */ - public static boolean isValidClassName(String invokeTarget) { - return StringUtils.countMatches(invokeTarget, ".") > 1; - } - - /** - * 获取bean名称 - * - * @param invokeTarget 目标字符串 - * @return bean名称 - */ - public static String getBeanName(String invokeTarget) { - String beanName = StringUtils.substringBefore(invokeTarget, "("); - return StringUtils.substringBeforeLast(beanName, "."); - } - - /** - * 获取bean方法 - * - * @param invokeTarget 目标字符串 - * @return method方法 - */ - public static String getMethodName(String invokeTarget) { - String methodName = StringUtils.substringBefore(invokeTarget, "("); - return StringUtils.substringAfterLast(methodName, "."); - } - - /** - * 获取method方法参数相关列表 - * - * @param invokeTarget 目标字符串 - * @return method方法相关参数列表 - */ - public static List getMethodParams(String invokeTarget) { - String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")"); - if (StringUtils.isEmpty(methodStr)) { - return null; - } - String[] methodParams = methodStr.split(","); - List classs = new LinkedList<>(); - for (int i = 0; i < methodParams.length; i++) { - String str = StringUtils.trimToEmpty(methodParams[i]); - // String字符串类型,包含' - if (StringUtils.contains(str, "'")) { - classs.add(new Object[]{StringUtils.replace(str, "'", ""), String.class}); - } - // boolean布尔类型,等于true或者false - else if (StringUtils.equals(str, "true") || StringUtils.equalsIgnoreCase(str, "false")) { - classs.add(new Object[]{Boolean.valueOf(str), Boolean.class}); - } - // long长整形,包含L - else if (StringUtils.containsIgnoreCase(str, "L")) { - classs.add(new Object[]{Long.valueOf(StringUtils.replaceIgnoreCase(str, "L", "")), Long.class}); - } - // double浮点类型,包含D - else if (StringUtils.containsIgnoreCase(str, "D")) { - classs.add(new Object[]{Double.valueOf(StringUtils.replaceIgnoreCase(str, "D", "")), Double.class}); - } - // 其他类型归类为整形 - else { - classs.add(new Object[]{Integer.valueOf(str), Integer.class}); - } - } - return classs; - } - - /** - * 获取参数类型 - * - * @param methodParams 参数相关列表 - * @return 参数类型列表 - */ - public static Class[] getMethodParamsType(List methodParams) { - Class[] classs = new Class[methodParams.size()]; - int index = 0; - for (Object[] os : methodParams) { - classs[index] = (Class) os[1]; - index++; - } - return classs; - } - - /** - * 获取参数值 - * - * @param methodParams 参数相关列表 - * @return 参数值列表 - */ - public static Object[] getMethodParamsValue(List methodParams) { - Object[] classs = new Object[methodParams.size()]; - int index = 0; - for (Object[] os : methodParams) { - classs[index] = (Object) os[0]; - index++; - } - return classs; - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java deleted file mode 100644 index d4f5a9861..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.ruoyi.quartz.util; - -import org.quartz.DisallowConcurrentExecution; -import org.quartz.JobExecutionContext; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 定时任务处理(禁止并发执行) - * - * @author ruoyi - */ -@DisallowConcurrentExecution -public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob { - @Override - protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception { - JobInvokeUtil.invokeMethod(sysJob); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java deleted file mode 100644 index 1b8447131..000000000 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.ruoyi.quartz.util; - -import org.quartz.JobExecutionContext; -import com.ruoyi.quartz.domain.SysJob; - -/** - * 定时任务处理(允许并发执行) - * - * @author ruoyi - */ -public class QuartzJobExecution extends AbstractQuartzJob { - @Override - protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception { - JobInvokeUtil.invokeMethod(sysJob); - } -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java index ae2decf57..a72fa96f6 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java @@ -21,65 +21,6 @@ import com.ruoyi.quartz.domain.SysJob; * @author ruoyi */ public class ScheduleUtils { - /** - * 得到quartz任务类 - * - * @param sysJob 执行计划 - * @return 具体执行任务类 - */ - private static Class getQuartzJobClass(SysJob sysJob) { - boolean isConcurrent = "0".equals(sysJob.getConcurrent()); - return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class; - } - - /** - * 构建任务触发对象 - */ - public static TriggerKey getTriggerKey(Long jobId, String jobGroup) { - return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); - } - - /** - * 构建任务键对象 - */ - public static JobKey getJobKey(Long jobId, String jobGroup) { - return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); - } - - /** - * 创建定时任务 - */ - public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException { - Class jobClass = getQuartzJobClass(job); - // 构建job信息 - Long jobId = job.getJobId(); - String jobGroup = job.getJobGroup(); - JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build(); - - // 表达式调度构建器 - CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); - cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); - - // 按新的cronExpression表达式构建一个新的trigger - CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup)) - .withSchedule(cronScheduleBuilder).build(); - - // 放入参数,运行时的方法可以获取 - jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); - - // 判断是否存在 - if (scheduler.checkExists(getJobKey(jobId, jobGroup))) { - // 防止创建时存在数据问题 先移除,然后在执行创建操作 - scheduler.deleteJob(getJobKey(jobId, jobGroup)); - } - - scheduler.scheduleJob(jobDetail, trigger); - - // 暂停任务 - if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) { - scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); - } - } /** * 设置定时任务策略 diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/InfJobController.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/InfJobController.java new file mode 100644 index 000000000..2ee4e865c --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/InfJobController.java @@ -0,0 +1,99 @@ +package cn.iocoder.dashboard.modules.infra.controller.job; + +import cn.iocoder.dashboard.common.pojo.CommonResult; +import cn.iocoder.dashboard.common.pojo.PageResult; +import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils; +import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.*; +import cn.iocoder.dashboard.modules.infra.convert.job.InfJobConvert; +import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobDO; +import cn.iocoder.dashboard.modules.infra.service.job.InfJobService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +import static cn.iocoder.dashboard.common.pojo.CommonResult.success; +import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT; + +@Api(tags = "定时任务") +@RestController +@RequestMapping("/infra/job") +@Validated +public class InfJobController { + + @Resource + private InfJobService jobService; + + @PostMapping("/create") + @ApiOperation("创建定时任务") + @PreAuthorize("@ss.hasPermission('infra:job:create')") + public CommonResult createJob(@Valid @RequestBody InfJobCreateReqVO createReqVO) { + return success(jobService.createJob(createReqVO)); + } + + @PutMapping("/update") + @ApiOperation("更新定时任务") + @PreAuthorize("@ss.hasPermission('infra:job:update')") + public CommonResult updateJob(@Valid @RequestBody InfJobUpdateReqVO updateReqVO) { + jobService.updateJob(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @ApiOperation("删除定时任务") + @ApiImplicitParam(name = "id", value = "编号", required = true) + @PreAuthorize("@ss.hasPermission('infra:job:delete')") + public CommonResult deleteJob(@RequestParam("id") Long id) { + jobService.deleteJob(id); + return success(true); + } + + @GetMapping("/get") + @ApiOperation("获得定时任务") + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('infra:job:query')") + public CommonResult getJob(@RequestParam("id") Long id) { + InfJobDO job = jobService.getJob(id); + return success(InfJobConvert.INSTANCE.convert(job)); + } + + @GetMapping("/list") + @ApiOperation("获得定时任务列表") + @ApiImplicitParam(name = "ids", value = "编号列表", required = true, dataTypeClass = List.class) + @PreAuthorize("@ss.hasPermission('infra:job:query')") + public CommonResult> getJobList(@RequestParam("ids") Collection ids) { + List list = jobService.getJobList(ids); + return success(InfJobConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @ApiOperation("获得定时任务分页") + @PreAuthorize("@ss.hasPermission('infra:job:query')") + public CommonResult> getJobPage(@Valid InfJobPageReqVO pageVO) { + PageResult pageResult = jobService.getJobPage(pageVO); + return success(InfJobConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/export-excel") + @ApiOperation("导出定时任务 Excel") + @PreAuthorize("@ss.hasPermission('infra:job:export')") + @OperateLog(type = EXPORT) + public void exportJobExcel(@Valid InfJobExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List list = jobService.getJobList(exportReqVO); + // 导出 Excel + List datas = InfJobConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "定时任务.xls", "数据", InfJobExcelVO.class, datas); + } + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobBaseVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobBaseVO.java new file mode 100644 index 000000000..0f111fa38 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobBaseVO.java @@ -0,0 +1,57 @@ +package cn.iocoder.dashboard.modules.infra.controller.job.vo.job; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; +import java.util.Date; + +import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** +* 定时任务 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class InfJobBaseVO { + + @ApiModelProperty(value = "任务名称", required = true, example = "测试任务") + @NotNull(message = "任务名称不能为空") + private String name; + + @ApiModelProperty(value = "任务状态", required = true, example = "1", notes = "参见 InfJobStatusEnum 枚举") + @NotNull(message = "任务状态不能为空") + private Integer status; + + @ApiModelProperty(value = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob") + @NotNull(message = "处理器的名字不能为空") + private String handlerName; + + @ApiModelProperty(value = "处理器的参数", example = "yudao") + private String handlerParam; + + @ApiModelProperty(value = "CRON 表达式", required = true, example = "0/10 * * * * ? *") + @NotNull(message = "CRON 表达式不能为空") + private String cronExpression; + + @ApiModelProperty(value = "最后一次执行的开始时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date executeBeginTime; + + @ApiModelProperty(value = "最后一次执行的结束时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date executeEndTime; + + @ApiModelProperty(value = "上一次触发时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date firePrevTime; + + @ApiModelProperty(value = "下一次触发时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date fireNextTime; + + @ApiModelProperty(value = "监控超时时间", example = "1000") + private Integer monitorTimeout; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobCreateReqVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobCreateReqVO.java new file mode 100644 index 000000000..a4c331d03 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.dashboard.modules.infra.controller.job.vo.job; + +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@ApiModel("定时任务创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class InfJobCreateReqVO extends InfJobBaseVO { + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobExcelVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobExcelVO.java new file mode 100644 index 000000000..531dd843d --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobExcelVO.java @@ -0,0 +1,57 @@ +package cn.iocoder.dashboard.modules.infra.controller.job.vo.job; + +import cn.iocoder.dashboard.framework.excel.core.annotations.DictFormat; +import cn.iocoder.dashboard.framework.excel.core.convert.DictConvert; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.util.Date; + +import static cn.iocoder.dashboard.modules.system.enums.dict.SysDictTypeEnum.INF_JOB_STATUS; + +/** + * 定时任务 Excel VO + * + * @author 芋道源码 + */ +@Data +public class InfJobExcelVO { + + @ExcelProperty("任务编号") + private Long id; + + @ExcelProperty("任务名称") + private String name; + + @ExcelProperty(value = "任务状态", converter = DictConvert.class) + @DictFormat(INF_JOB_STATUS) + private Integer status; + + @ExcelProperty("处理器的名字") + private String handlerName; + + @ExcelProperty("处理器的参数") + private String handlerParam; + + @ExcelProperty("CRON 表达式") + private String cronExpression; + + @ExcelProperty("最后一次执行的开始时间") + private Date executeBeginTime; + + @ExcelProperty("最后一次执行的结束时间") + private Date executeEndTime; + + @ExcelProperty("上一次触发时间") + private Date firePrevTime; + + @ExcelProperty("下一次触发时间") + private Date fireNextTime; + + @ExcelProperty("监控超时时间") + private Integer monitorTimeout; + + @ExcelProperty("创建时间") + private Date createTime; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobExportReqVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobExportReqVO.java new file mode 100644 index 000000000..a0fe9f39e --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobExportReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.dashboard.modules.infra.controller.job.vo.job; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@ApiModel(value = "定时任务 Excel 导出 Request VO", description = "参数和 InfJobPageReqVO 是一致的") +@Data +public class InfJobExportReqVO { + + @ApiModelProperty(value = "任务名称", example = "测试任务", notes = "模糊匹配") + private String name; + + @ApiModelProperty(value = "任务状态", example = "1", notes = "参见 InfJobStatusEnum 枚举") + private Integer status; + + @ApiModelProperty(value = "处理器的名字", example = "sysUserSessionTimeoutJob", notes = "模糊匹配") + private String handlerName; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobPageReqVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobPageReqVO.java new file mode 100644 index 000000000..a2e700ee5 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobPageReqVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.dashboard.modules.infra.controller.job.vo.job; + +import cn.iocoder.dashboard.common.pojo.PageParam; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@ApiModel("定时任务分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class InfJobPageReqVO extends PageParam { + + @ApiModelProperty(value = "任务名称", example = "测试任务", notes = "模糊匹配") + private String name; + + @ApiModelProperty(value = "任务状态", example = "1", notes = "参见 InfJobStatusEnum 枚举") + private Integer status; + + @ApiModelProperty(value = "处理器的名字", example = "sysUserSessionTimeoutJob", notes = "模糊匹配") + private String handlerName; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobRespVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobRespVO.java new file mode 100644 index 000000000..543e4c187 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobRespVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.dashboard.modules.infra.controller.job.vo.job; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Date; + +@ApiModel("定时任务 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class InfJobRespVO extends InfJobBaseVO { + + @ApiModelProperty(value = "任务编号", required = true, example = "1024") + private Long id; + + @ApiModelProperty(value = "创建时间", required = true) + private Date createTime; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobUpdateReqVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobUpdateReqVO.java new file mode 100644 index 000000000..1316667a4 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobUpdateReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.dashboard.modules.infra.controller.job.vo.job; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@ApiModel("定时任务更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class InfJobUpdateReqVO extends InfJobBaseVO { + + @ApiModelProperty(value = "任务编号", required = true, example = "1024") + @NotNull(message = "任务编号不能为空") + private Long id; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/convert/job/InfJobConvert.java b/src/main/java/cn/iocoder/dashboard/modules/infra/convert/job/InfJobConvert.java new file mode 100644 index 000000000..2f871361c --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/convert/job/InfJobConvert.java @@ -0,0 +1,36 @@ +package cn.iocoder.dashboard.modules.infra.convert.job; + +import cn.iocoder.dashboard.common.pojo.PageResult; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobCreateReqVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobExcelVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobRespVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobUpdateReqVO; +import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 定时任务 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface InfJobConvert { + + InfJobConvert INSTANCE = Mappers.getMapper(InfJobConvert.class); + + InfJobDO convert(InfJobCreateReqVO bean); + + InfJobDO convert(InfJobUpdateReqVO bean); + + InfJobRespVO convert(InfJobDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobDO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobDO.java index 9830095db..d5884df6e 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobDO.java +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobDO.java @@ -2,6 +2,8 @@ package cn.iocoder.dashboard.modules.infra.dal.dataobject.job; import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.dashboard.modules.infra.enums.job.InfJobStatusEnum; +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -43,6 +45,7 @@ public class InfJobDO extends BaseDO { /** * 处理器的参数 */ + @TableField(updateStrategy = FieldStrategy.IGNORED) private String handlerParam; // ========== 时间相关字段 ========== @@ -75,13 +78,12 @@ public class InfJobDO extends BaseDO { private Date fireNextTime; // ========== 监控相关字段 ========== - /** - * 监控开关 - */ - private Boolean monitorSwitch; /** * 监控超时时间,单位:毫秒 + * + * 注意,这里的超时的目的,不是进行任务的取消,而是告警任务的执行时间过长 */ + @TableField(updateStrategy = FieldStrategy.IGNORED) private Integer monitorTimeout; // TODO misfirePolicy diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/dal/mysql/job/InfJobMapper.java b/src/main/java/cn/iocoder/dashboard/modules/infra/dal/mysql/job/InfJobMapper.java new file mode 100644 index 000000000..4989159ff --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/dal/mysql/job/InfJobMapper.java @@ -0,0 +1,37 @@ +package cn.iocoder.dashboard.modules.infra.dal.mysql.job; + +import cn.iocoder.dashboard.common.pojo.PageResult; +import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.dashboard.framework.mybatis.core.query.QueryWrapperX; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobExportReqVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobPageReqVO; +import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 定时任务 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface InfJobMapper extends BaseMapperX { + + default PageResult selectPage(InfJobPageReqVO reqVO) { + return selectPage(reqVO, new QueryWrapperX() + .likeIfPresent("name", reqVO.getName()) + .eqIfPresent("status", reqVO.getStatus()) + .likeIfPresent("handler_name", reqVO.getHandlerName()) + ); + } + + default List selectList(InfJobExportReqVO reqVO) { + return selectList(new QueryWrapperX() + .likeIfPresent("name", reqVO.getName()) + .eqIfPresent("status", reqVO.getStatus()) + .likeIfPresent("handler_name", reqVO.getHandlerName()) + ); + } + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/dal/mysql/package-info.java b/src/main/java/cn/iocoder/dashboard/modules/infra/dal/mysql/package-info.java deleted file mode 100644 index 5621e3519..000000000 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/dal/mysql/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.dashboard.modules.infra.dal.mysql; diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/enums/InfErrorCodeConstants.java b/src/main/java/cn/iocoder/dashboard/modules/infra/enums/InfErrorCodeConstants.java index 81cc37a70..222da0abe 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/enums/InfErrorCodeConstants.java +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/enums/InfErrorCodeConstants.java @@ -15,4 +15,7 @@ public interface InfErrorCodeConstants { ErrorCode CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE = new ErrorCode(1001000003, "不能删除类型为系统内置的参数配置"); ErrorCode CONFIG_GET_VALUE_ERROR_IF_SENSITIVE = new ErrorCode(1001000004, "不允许获取敏感配置到前端"); + // ========== 定时任务 1001001000 ========== + ErrorCode JOB_NOT_EXISTS = new ErrorCode(1001001000, "定时任务不存在"); + } diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobService.java b/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobService.java new file mode 100644 index 000000000..89c92138a --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobService.java @@ -0,0 +1,75 @@ +package cn.iocoder.dashboard.modules.infra.service.job; + +import cn.iocoder.dashboard.common.pojo.PageResult; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobCreateReqVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobExportReqVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobPageReqVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobUpdateReqVO; +import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobDO; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; + +/** + * 定时任务 Service 接口 + * + * @author 芋道源码 + */ +public interface InfJobService { + + /** + * 创建定时任务 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createJob(@Valid InfJobCreateReqVO createReqVO); + + /** + * 更新定时任务 + * + * @param updateReqVO 更新信息 + */ + void updateJob(@Valid InfJobUpdateReqVO updateReqVO); + + /** + * 删除定时任务 + * + * @param id 编号 + */ + void deleteJob(Long id); + + /** + * 获得定时任务 + * + * @param id 编号 + * @return 定时任务 + */ + InfJobDO getJob(Long id); + + /** + * 获得定时任务列表 + * + * @param ids 编号 + * @return 定时任务列表 + */ + List getJobList(Collection ids); + + /** + * 获得定时任务分页 + * + * @param pageReqVO 分页查询 + * @return 定时任务分页 + */ + PageResult getJobPage(InfJobPageReqVO pageReqVO); + + /** + * 获得定时任务列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 定时任务分页 + */ + List getJobList(InfJobExportReqVO exportReqVO); + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java new file mode 100644 index 000000000..59e3237f6 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java @@ -0,0 +1,86 @@ +package cn.iocoder.dashboard.modules.infra.service.job.impl; + +import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil; +import cn.iocoder.dashboard.common.pojo.PageResult; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobCreateReqVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobExportReqVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobPageReqVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobUpdateReqVO; +import cn.iocoder.dashboard.modules.infra.convert.job.InfJobConvert; +import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobDO; +import cn.iocoder.dashboard.modules.infra.dal.mysql.job.InfJobMapper; +import cn.iocoder.dashboard.modules.infra.service.job.InfJobService; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_NOT_EXISTS; + +/** + * 定时任务 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class InfJobServiceImpl implements InfJobService { + + @Resource + private InfJobMapper jobMapper; + + @Override + public Long createJob(InfJobCreateReqVO createReqVO) { + // 插入 + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO); + jobMapper.insert(job); + // 返回 + return job.getId(); + } + + @Override + public void updateJob(InfJobUpdateReqVO updateReqVO) { + // 校验存在 + this.validateJobExists(updateReqVO.getId()); + // 更新 + InfJobDO updateObj = InfJobConvert.INSTANCE.convert(updateReqVO); + jobMapper.updateById(updateObj); + } + + @Override + public void deleteJob(Long id) { + // 校验存在 + this.validateJobExists(id); + // 更新 + jobMapper.deleteById(id); + } + + private void validateJobExists(Long id) { + if (jobMapper.selectById(id) == null) { + throw ServiceExceptionUtil.exception(JOB_NOT_EXISTS); + } + } + + @Override + public InfJobDO getJob(Long id) { + return jobMapper.selectById(id); + } + + @Override + public List getJobList(Collection ids) { + return jobMapper.selectBatchIds(ids); + } + + @Override + public PageResult getJobPage(InfJobPageReqVO pageReqVO) { + return jobMapper.selectPage(pageReqVO); + } + + @Override + public List getJobList(InfJobExportReqVO exportReqVO) { + return jobMapper.selectList(exportReqVO); + } + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/service/package-info.java b/src/main/java/cn/iocoder/dashboard/modules/infra/service/package-info.java deleted file mode 100644 index 310528922..000000000 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/service/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.dashboard.modules.infra.service; diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/enums/dict/SysDictTypeEnum.java b/src/main/java/cn/iocoder/dashboard/modules/system/enums/dict/SysDictTypeEnum.java index 1aaf69d6a..e1e59f789 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/enums/dict/SysDictTypeEnum.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/enums/dict/SysDictTypeEnum.java @@ -18,6 +18,7 @@ public enum SysDictTypeEnum { SYS_BOOLEAN_STRING("sys_boolean_string"), // Boolean 是否类型 INF_REDIS_TIMEOUT_TYPE("inf_redis_timeout_type"), // Redis 超时类型 + INF_JOB_STATUS("inf_job_status") // 任务状态的枚举 ; diff --git a/src/main/resources/codegen/java/controller/vo/baseVO.vm b/src/main/resources/codegen/java/controller/vo/baseVO.vm index 4eba0097d..bc22b3c94 100644 --- a/src/main/resources/codegen/java/controller/vo/baseVO.vm +++ b/src/main/resources/codegen/java/controller/vo/baseVO.vm @@ -4,6 +4,16 @@ import lombok.*; import java.util.*; import io.swagger.annotations.*; import javax.validation.constraints.*; +## 处理 Date 字段的引入 +#foreach ($column in $columns) +#if (${column.createOperation} && ${column.updateOperation} && ${column.listOperationResult})##通用操作 + && ${column.javaType} == "Date")## 时间类型 +import org.springframework.format.annotation.DateTimeFormat; + +import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +#break +#end +#end /** * ${table.classComment} Base VO,提供给添加、修改、详细的子 VO 使用 diff --git a/src/test/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManagerTest.java b/src/test/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManagerTest.java index fdfe1a241..bae46416d 100644 --- a/src/test/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManagerTest.java +++ b/src/test/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManagerTest.java @@ -29,6 +29,12 @@ class SchedulerManagerTest { schedulerManager.updateJob(jobHandlerName, "hahaha", "0/20 * * * * ? *"); } + @Test + public void testDeleteJob() throws SchedulerException { + String jobHandlerName = StrUtil.lowerFirst(SysUserSessionTimeoutJob.class.getSimpleName()); + schedulerManager.deleteJob(jobHandlerName); + } + @Test public void testPauseJob() throws SchedulerException { String jobHandlerName = StrUtil.lowerFirst(SysUserSessionTimeoutJob.class.getSimpleName());