From 3959aadae2bec0eecaf4e31fe0c018d5cfe869db Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 18 Feb 2021 21:26:59 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E4=BC=98=E5=8C=96=20JobHandlerInvoker=20?= =?UTF-8?q?=E7=9A=84=E5=AE=9E=E7=8E=B0=EF=BC=8C=E5=A2=9E=E5=8A=A0=E9=87=8D?= =?UTF-8?q?=E8=AF=95=E6=9C=BA=E5=88=B6=202.=20=E5=8E=BB=E9=99=A4=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A=E5=BC=82=E5=B8=B8=EF=BC=8C=E8=87=AA=E5=8A=A8=E6=9A=82?= =?UTF-8?q?=E6=97=B6=E4=BD=9C=E4=B8=9A=E7=9A=84=E6=9C=BA=E5=88=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/constant/ScheduleConstants.java | 56 -- .../service/impl/SysJobLogServiceImpl.java | 54 -- .../ruoyi/quartz/util/AbstractQuartzJob.java | 97 --- .../com/ruoyi/quartz/util/ScheduleUtils.java | 44 -- ruoyi-ui/src/utils/constants.js | 5 +- ruoyi-ui/src/views/index.vue | 668 +++--------------- ruoyi-ui/src/views/index_old.vue | 570 +++++++++++++++ ruoyi-ui/src/views/index_v1.vue | 98 --- ruoyi-ui/src/views/infra/job/index.vue | 23 +- .../mybatis/core/query/QueryWrapperX.java | 14 + .../quartz/core/enums/JobDataKeyEnum.java | 4 +- .../core/handler/JobHandlerInvoker.java | 64 +- .../core/scheduler/SchedulerManager.java | 23 +- .../core/service/JobLogFrameworkService.java | 40 +- .../{dbdoc => doc}/InfDbDocController.java | 2 +- .../controller/job/vo/job/InfJobBaseVO.java | 8 + .../job/vo/log/InfJobLogBaseVO.java | 53 ++ .../job/vo/log/InfJobLogExcelVO.java | 49 ++ .../job/vo/log/InfJobLogExportReqVO.java | 30 + .../job/vo/log/InfJobLogPageReqVO.java | 35 + .../job/vo/log/InfJobLogRespVO.java | 23 + .../infra/dal/dataobject/job/InfJobDO.java | 12 + .../infra/dal/dataobject/job/InfJobLogDO.java | 6 + .../infra/enums/job/InfJobStatusEnum.java | 10 +- .../job/impl/InfJobLogServiceImpl.java | 22 +- .../service/job/impl/InfJobServiceImpl.java | 8 +- .../job/auth/SysUserSessionTimeoutJob.java | 3 + .../codegen/impl/ToolCodegenServiceImpl.java | 6 +- src/main/resources/codegen/java/dal/mapper.vm | 5 +- .../core/scheduler/SchedulerManagerTest.java | 4 +- 30 files changed, 1019 insertions(+), 1017 deletions(-) delete mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java delete mode 100644 ruoyi-common/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java delete mode 100644 ruoyi-common/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java delete mode 100644 ruoyi-common/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java create mode 100644 ruoyi-ui/src/views/index_old.vue delete mode 100644 ruoyi-ui/src/views/index_v1.vue rename src/main/java/cn/iocoder/dashboard/modules/infra/controller/{dbdoc => doc}/InfDbDocController.java (98%) create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogBaseVO.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogExcelVO.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogExportReqVO.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogPageReqVO.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogRespVO.java diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java deleted file mode 100644 index cb984558c..000000000 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ruoyi.common.constant; - -/** - * 任务调度通用常量 - * - * @author ruoyi - */ -public class ScheduleConstants { - public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME"; - - /** - * 执行目标key - */ - public static final String TASK_PROPERTIES = "TASK_PROPERTIES"; - - /** - * 默认 - */ - public static final String MISFIRE_DEFAULT = "0"; - - /** - * 立即触发执行 - */ - public static final String MISFIRE_IGNORE_MISFIRES = "1"; - - /** - * 触发一次执行 - */ - public static final String MISFIRE_FIRE_AND_PROCEED = "2"; - - /** - * 不触发立即执行 - */ - public static final String MISFIRE_DO_NOTHING = "3"; - - public enum Status { - /** - * 正常 - */ - NORMAL("0"), - /** - * 暂停 - */ - PAUSE("1"); - - private String value; - - private Status(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - } -} diff --git a/ruoyi-common/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java b/ruoyi-common/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java deleted file mode 100644 index 443d830e4..000000000 --- a/ruoyi-common/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java +++ /dev/null @@ -1,54 +0,0 @@ -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-common/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java b/ruoyi-common/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java deleted file mode 100644 index f3db6aa10..000000000 --- a/ruoyi-common/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java +++ /dev/null @@ -1,97 +0,0 @@ -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-common/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java b/ruoyi-common/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java deleted file mode 100644 index 7aca21ddd..000000000 --- a/ruoyi-common/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java +++ /dev/null @@ -1,44 +0,0 @@ -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-ui/src/utils/constants.js b/ruoyi-ui/src/utils/constants.js index 8dc1492b1..e608fc77d 100644 --- a/ruoyi-ui/src/utils/constants.js +++ b/ruoyi-ui/src/utils/constants.js @@ -54,7 +54,6 @@ export const ToolCodegenTemplateTypeEnum = { */ export const InfJobStatusEnum = { INIT: 0, // 初始化中 - NORMAL: 1, // 开启运行 - EXCEPTION: 2, // 异常运行 - STOP: 3, // 暂停运行 + NORMAL: 1, // 运行中 + STOP: 2, // 暂停运行 } diff --git a/ruoyi-ui/src/views/index.vue b/ruoyi-ui/src/views/index.vue index 3f20fe95c..d2d2ec633 100644 --- a/ruoyi-ui/src/views/index.vue +++ b/ruoyi-ui/src/views/index.vue @@ -1,570 +1,98 @@ - - - - - - + + + + + diff --git a/ruoyi-ui/src/views/index_old.vue b/ruoyi-ui/src/views/index_old.vue new file mode 100644 index 000000000..71fb9803a --- /dev/null +++ b/ruoyi-ui/src/views/index_old.vue @@ -0,0 +1,570 @@ + + + + + + diff --git a/ruoyi-ui/src/views/index_v1.vue b/ruoyi-ui/src/views/index_v1.vue deleted file mode 100644 index 4828d8806..000000000 --- a/ruoyi-ui/src/views/index_v1.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - - - diff --git a/ruoyi-ui/src/views/infra/job/index.vue b/ruoyi-ui/src/views/infra/job/index.vue index fd0b3b7ae..8e64be107 100644 --- a/ruoyi-ui/src/views/infra/job/index.vue +++ b/ruoyi-ui/src/views/infra/job/index.vue @@ -30,7 +30,7 @@ 日志 + v-hasPermi="['infra:job:query']">日志 @@ -53,9 +53,9 @@ 修改 开启 + v-if="scope.row.status === InfJobStatusEnum.STOP" v-hasPermi="['infra:job:update']">开启 暂停 + v-if="scope.row.status === InfJobStatusEnum.NORMAL" v-hasPermi="['infra:job:update']">暂停 执行一次 + + + + + + @@ -107,6 +113,8 @@ {{ parseTime(form.executeEndTime) }} {{ parseTime(form.firePrevTime) }} {{ parseTime(form.fireNextTime) }} + {{ form.retryCount }} + {{ form.retryInterval + " 毫秒" }} {{ form.monitorTimeout > 0 ? form.monitorTimeout + " 毫秒" : "未开启" }} @@ -158,7 +166,12 @@ export default { name: [{ required: true, message: "任务名称不能为空", trigger: "blur" }], handlerName: [{ required: true, message: "处理器的名字不能为空", trigger: "blur" }], cronExpression: [{ required: true, message: "CRON 表达式不能为空", trigger: "blur" }], - } + retryCount: [{ required: true, message: "重试次数不能为空", trigger: "blur" }], + retryInterval: [{ required: true, message: "重试间隔不能为空", trigger: "blur" }], + }, + + // 枚举 + InfJobStatusEnum: InfJobStatusEnum }; }, created() { @@ -187,6 +200,8 @@ export default { handlerName: undefined, handlerParam: undefined, cronExpression: undefined, + retryCount: undefined, + retryInterval: undefined, monitorTimeout: undefined, }; this.resetForm("form"); diff --git a/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/query/QueryWrapperX.java b/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/query/QueryWrapperX.java index d44c86a8f..ff2e1555d 100644 --- a/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/query/QueryWrapperX.java +++ b/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/query/QueryWrapperX.java @@ -65,6 +65,20 @@ public class QueryWrapperX extends QueryWrapper { return this; } + public QueryWrapperX ltIfPresent(String column, Object val) { + if (val != null) { + return (QueryWrapperX) super.lt(column, val); + } + return this; + } + + public QueryWrapperX leIfPresent(String column, Object val) { + if (val != null) { + return (QueryWrapperX) super.le(column, val); + } + return this; + } + public QueryWrapperX betweenIfPresent(String column, Object val1, Object val2) { if (val1 != null && val2 != null) { return (QueryWrapperX) super.between(column, val1, val2); diff --git a/src/main/java/cn/iocoder/dashboard/framework/quartz/core/enums/JobDataKeyEnum.java b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/enums/JobDataKeyEnum.java index 53fad1c5a..2849d1aa0 100644 --- a/src/main/java/cn/iocoder/dashboard/framework/quartz/core/enums/JobDataKeyEnum.java +++ b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/enums/JobDataKeyEnum.java @@ -7,6 +7,8 @@ public enum JobDataKeyEnum { JOB_ID, JOB_HANDLER_NAME, - JOB_HANDLER_PARAM + JOB_HANDLER_PARAM, + JOB_RETRY_COUNT, // 最大重试次数 + JOB_RETRY_INTERVAL, // 每次重试间隔 } diff --git a/src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandlerInvoker.java b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandlerInvoker.java index 94464e8df..f7fad193f 100644 --- a/src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandlerInvoker.java +++ b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandlerInvoker.java @@ -1,7 +1,7 @@ package cn.iocoder.dashboard.framework.quartz.core.handler; import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.StrUtil; +import cn.hutool.core.thread.ThreadUtil; import cn.iocoder.dashboard.framework.quartz.core.enums.JobDataKeyEnum; import cn.iocoder.dashboard.framework.quartz.core.service.JobLogFrameworkService; import lombok.extern.slf4j.Slf4j; @@ -38,8 +38,11 @@ public class JobHandlerInvoker extends QuartzJobBean { protected void executeInternal(JobExecutionContext executionContext) throws JobExecutionException { // 第一步,获得 Job 数据 Long jobId = executionContext.getMergedJobDataMap().getLong(JobDataKeyEnum.JOB_ID.name()); - String jobHandlerName = getJobHandlerName(executionContext); + String jobHandlerName = executionContext.getMergedJobDataMap().getString(JobDataKeyEnum.JOB_HANDLER_NAME.name()); String jobHandlerParam = executionContext.getMergedJobDataMap().getString(JobDataKeyEnum.JOB_HANDLER_PARAM.name()); + int refireCount = executionContext.getRefireCount(); + int retryCount = (Integer) executionContext.getMergedJobDataMap().getOrDefault(JobDataKeyEnum.JOB_RETRY_COUNT.name(), 0); + int retryInterval = (Integer) executionContext.getMergedJobDataMap().getOrDefault(JobDataKeyEnum.JOB_RETRY_INTERVAL.name(), 0); // 第二步,执行任务 Long jobLogId = null; @@ -48,7 +51,7 @@ public class JobHandlerInvoker extends QuartzJobBean { Throwable exception = null; try { // 记录 Job 日志(初始) - jobLogId = jobLogFrameworkService.createJobLog(jobId, startTime, jobHandlerName, jobHandlerParam); + jobLogId = jobLogFrameworkService.createJobLog(jobId, startTime, jobHandlerName, jobHandlerParam, refireCount + 1); // 执行任务 data = this.executeInternal(jobHandlerName, jobHandlerParam); } catch (Throwable ex) { @@ -58,21 +61,8 @@ public class JobHandlerInvoker extends QuartzJobBean { // 第三步,记录执行日志 this.updateJobLogResultAsync(jobLogId, startTime, data, exception, executionContext); - // 最终还是抛出异常,用于停止任务 - if (exception != null) { - throw new JobExecutionException(exception); - } - } - - private static String getJobHandlerName(JobExecutionContext executionContext) { - String jobHandlerName = executionContext.getMergedJobDataMap().getString(JobDataKeyEnum.JOB_HANDLER_NAME.name()); - if (StrUtil.isEmpty(jobHandlerName)) { - log.error("[executeInternal][Job({}) 获取不到正确的 jobHandlerName({})]", - executionContext.getJobDetail().getKey(), jobHandlerName); - throw new IllegalStateException(StrUtil.format("Job({}) 获取不到正确的 jobHandlerName({})", - executionContext.getJobDetail().getKey(), jobHandlerName)); - } - return jobHandlerName; + // 第四步,处理有异常的情况 + handleException(exception, refireCount, retryCount, retryInterval); } private String executeInternal(String jobHandlerName, String jobHandlerParam) throws Exception { @@ -86,18 +76,38 @@ public class JobHandlerInvoker extends QuartzJobBean { private void updateJobLogResultAsync(Long jobLogId, Date startTime, String data, Throwable exception, JobExecutionContext executionContext) { Date endTime = new Date(); + // 处理是否成功 + boolean success = exception == null; + if (!success) { + data = getRootCauseMessage(exception); + } + // 更新日志 try { - if (data != null) { // 成功 - jobLogFrameworkService.updateJobLogSuccessAsync(jobLogId, endTime, (int) diff(endTime, startTime), data); - } else { // 失败 - jobLogFrameworkService.updateJobLogErrorAsync(jobLogId, endTime, (int) diff(endTime, startTime), - getRootCauseMessage(exception)); - } + jobLogFrameworkService.updateJobLogResultAsync(jobLogId, endTime, (int) diff(endTime, startTime), success, data); } catch (Exception ex) { - log.error("[executeInternal][Job({}) logId({}) 记录执行日志失败({})]", - executionContext.getJobDetail().getKey(), jobLogId, - data != null ? data : getRootCauseMessage(exception)); + log.error("[executeInternal][Job({}) logId({}) 记录执行日志失败({}/{})]", + executionContext.getJobDetail().getKey(), jobLogId, success, data); } } + private void handleException(Throwable exception, + int refireCount, int retryCount, int retryInterval) throws JobExecutionException { + // 如果有异常,则进行重试 + if (exception == null) { + return; + } + // 情况一:如果到达重试上限,则直接抛出异常即可 + if (refireCount >= retryCount) { + throw new JobExecutionException(exception); + } + + // 情况二:如果未到达重试上限,则 sleep 一定间隔时间,然后重试 + // 这里使用 sleep 来实现,主要还是希望实现比较简单。因为,同一时间,不会存在大量失败的 Job。 + if (retryInterval > 0) { + ThreadUtil.sleep(retryInterval); + } + // 第二个参数,refireImmediately = true,表示立即重试 + throw new JobExecutionException(exception, true); + } + } diff --git a/src/main/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManager.java b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManager.java index e5b38505d..e72c90931 100644 --- a/src/main/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManager.java +++ b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManager.java @@ -30,9 +30,12 @@ public class SchedulerManager { * @param jobHandlerName 任务处理器的名字 * @param jobHandlerParam 任务处理器的参数 * @param cronExpression CRON 表达式 + * @param retryCount 重试次数 + * @param retryInterval 重试间隔 * @throws SchedulerException 添加异常 */ - public void addJob(Long jobId, String jobHandlerName, String jobHandlerParam, String cronExpression) + public void addJob(Long jobId, String jobHandlerName, String jobHandlerParam, String cronExpression, + Integer retryCount, Integer retryInterval) throws SchedulerException { // 创建 JobDetail 对象 JobDetail jobDetail = JobBuilder.newJob(JobHandlerInvoker.class) @@ -40,7 +43,7 @@ public class SchedulerManager { .usingJobData(JobDataKeyEnum.JOB_HANDLER_NAME.name(), jobHandlerName) .withIdentity(jobHandlerName).build(); // 创建 Trigger 对象 - Trigger trigger = this.buildTrigger(jobHandlerName, jobHandlerParam, cronExpression); + Trigger trigger = this.buildTrigger(jobHandlerName, jobHandlerParam, cronExpression, retryCount, retryInterval); // 新增调度 scheduler.scheduleJob(jobDetail, trigger); } @@ -51,12 +54,15 @@ public class SchedulerManager { * @param jobHandlerName 任务处理器的名字 * @param jobHandlerParam 任务处理器的参数 * @param cronExpression CRON 表达式 + * @param retryCount 重试次数 + * @param retryInterval 重试间隔 * @throws SchedulerException 更新异常 */ - public void updateJob(String jobHandlerName, String jobHandlerParam, String cronExpression) + public void updateJob(String jobHandlerName, String jobHandlerParam, String cronExpression, + Integer retryCount, Integer retryInterval) throws SchedulerException { // 创建新 Trigger 对象 - Trigger newTrigger = this.buildTrigger(jobHandlerName, jobHandlerParam, cronExpression); + Trigger newTrigger = this.buildTrigger(jobHandlerName, jobHandlerParam, cronExpression, retryCount, retryInterval); // 修改调度 scheduler.rescheduleJob(new TriggerKey(jobHandlerName), newTrigger); } @@ -102,7 +108,7 @@ public class SchedulerManager { */ public void triggerJob(Long jobId, String jobHandlerName, String jobHandlerParam) throws SchedulerException { - JobDataMap data = new JobDataMap(); + JobDataMap data = new JobDataMap(); // 无需重试,所以不设置 retryCount 和 retryInterval data.put(JobDataKeyEnum.JOB_ID.name(), jobId); data.put(JobDataKeyEnum.JOB_HANDLER_NAME.name(), jobHandlerName); data.put(JobDataKeyEnum.JOB_HANDLER_PARAM.name(), jobHandlerParam); @@ -110,11 +116,14 @@ public class SchedulerManager { scheduler.triggerJob(new JobKey(jobHandlerName), data); } - private Trigger buildTrigger(String jobHandlerName, String jobHandlerParam, String cronExpression) { + private Trigger buildTrigger(String jobHandlerName, String jobHandlerParam, String cronExpression, + Integer retryCount, Integer retryInterval) { return TriggerBuilder.newTrigger() .withIdentity(jobHandlerName) - .usingJobData(JobDataKeyEnum.JOB_HANDLER_PARAM.name(), jobHandlerParam) .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)) + .usingJobData(JobDataKeyEnum.JOB_HANDLER_PARAM.name(), jobHandlerParam) + .usingJobData(JobDataKeyEnum.JOB_RETRY_COUNT.name(), retryCount) + .usingJobData(JobDataKeyEnum.JOB_RETRY_INTERVAL.name(), retryInterval) .build(); } diff --git a/src/main/java/cn/iocoder/dashboard/framework/quartz/core/service/JobLogFrameworkService.java b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/service/JobLogFrameworkService.java index a62333a40..a93dfdf08 100644 --- a/src/main/java/cn/iocoder/dashboard/framework/quartz/core/service/JobLogFrameworkService.java +++ b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/service/JobLogFrameworkService.java @@ -14,41 +14,31 @@ public interface JobLogFrameworkService { /** * 创建 Job 日志 * - * @param jobId 任务编号 - * @param beginTime 开始时间 - * @param jobHandlerName Job 处理器的名字 + * @param jobId 任务编号 + * @param beginTime 开始时间 + * @param jobHandlerName Job 处理器的名字 * @param jobHandlerParam Job 处理器的参数 + * @param executeIndex 第几次执行 * @return Job 日志的编号 */ Long createJobLog(@NotNull(message = "任务编号不能为空") Long jobId, @NotNull(message = "开始时间") Date beginTime, @NotEmpty(message = "Job 处理器的名字不能为空") String jobHandlerName, - String jobHandlerParam); + String jobHandlerParam, + @NotNull(message = "第几次执行不能为空") Integer executeIndex); /** - * 更新 Job 日志成功 + * 更新 Job 日志的执行结果 * - * @param logId 日志编号 - * @param endTime 结束时间。因为是异步,避免记录时间不准去 + * @param logId 日志编号 + * @param endTime 结束时间。因为是异步,避免记录时间不准去 * @param duration 运行时长,单位:毫秒 - * @param result 成功数据 + * @param success 是否成功 + * @param result 成功数据 */ - void updateJobLogSuccessAsync(@NotNull(message = "日志编号不能为空") Long logId, - @NotNull(message = "结束时间不能为空") Date endTime, - @NotNull(message = "运行时长不能为空") Integer duration, - String result); - - /** - * 更新 Job 日志失败 - * - * @param logId 日志编号 - * @param endTime 结束时间。因为是异步,避免记录时间不准去 - * @param duration 运行时长,单位:毫秒 - * @param result 异常提示 - */ - void updateJobLogErrorAsync(@NotNull(message = "日志编号不能为空") Long logId, - @NotNull(message = "结束时间不能为空") Date endTime, - @NotNull(message = "运行时长不能为空") Integer duration, - String result); + void updateJobLogResultAsync(@NotNull(message = "日志编号不能为空") Long logId, + @NotNull(message = "结束时间不能为空") Date endTime, + @NotNull(message = "运行时长不能为空") Integer duration, + boolean success, String result); } diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/dbdoc/InfDbDocController.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/doc/InfDbDocController.java similarity index 98% rename from src/main/java/cn/iocoder/dashboard/modules/infra/controller/dbdoc/InfDbDocController.java rename to src/main/java/cn/iocoder/dashboard/modules/infra/controller/doc/InfDbDocController.java index 114efa266..394809670 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/dbdoc/InfDbDocController.java +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/doc/InfDbDocController.java @@ -1,4 +1,4 @@ -package cn.iocoder.dashboard.modules.infra.controller.dbdoc; +package cn.iocoder.dashboard.modules.infra.controller.doc; import cn.hutool.extra.servlet.ServletUtil; import cn.smallbun.screw.core.Configuration; 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 index 103778dd3..bbbdf4f40 100644 --- 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 @@ -23,6 +23,14 @@ public class InfJobBaseVO { @NotNull(message = "CRON 表达式不能为空") private String cronExpression; + @ApiModelProperty(value = "重试次数", required = true) + @NotNull(message = "重试次数不能为空") + private Integer retryCount; + + @ApiModelProperty(value = "重试间隔", required = true) + @NotNull(message = "重试间隔不能为空") + private Integer retryInterval; + @ApiModelProperty(value = "监控超时时间", example = "1000") private Integer monitorTimeout; diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogBaseVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogBaseVO.java new file mode 100644 index 000000000..ea58f4112 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogBaseVO.java @@ -0,0 +1,53 @@ +package cn.iocoder.dashboard.modules.infra.controller.job.vo.log; + +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 InfJobLogBaseVO { + + @ApiModelProperty(value = "任务编号", required = true) + @NotNull(message = "任务编号不能为空") + private Long jobId; + + @ApiModelProperty(value = "处理器的名字", required = true) + @NotNull(message = "处理器的名字不能为空") + private String handlerName; + + @ApiModelProperty(value = "处理器的参数") + private String handlerParam; + + @ApiModelProperty(value = "第几次执行", required = true) + @NotNull(message = "第几次执行不能为空") + private Integer executeIndex; + + @ApiModelProperty(value = "开始执行时间", required = true) + @NotNull(message = "开始执行时间不能为空") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date beginTime; + + @ApiModelProperty(value = "结束执行时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date endTime; + + @ApiModelProperty(value = "执行时长") + private Integer duration; + + @ApiModelProperty(value = "任务状态", required = true) + @NotNull(message = "任务状态不能为空") + private Integer status; + + @ApiModelProperty(value = "结果数据") + private String result; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogExcelVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogExcelVO.java new file mode 100644 index 000000000..92775e8b6 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogExcelVO.java @@ -0,0 +1,49 @@ +package cn.iocoder.dashboard.modules.infra.controller.job.vo.log; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * 定时任务 Excel VO + * + * @author 芋艿 + */ +@Data +public class InfJobLogExcelVO { + + @ExcelProperty("日志编号") + private Long id; + + @ExcelProperty("任务编号") + private Long jobId; + + @ExcelProperty("处理器的名字") + private String handlerName; + + @ExcelProperty("处理器的参数") + private String handlerParam; + + @ExcelProperty("第几次执行") + private Integer executeIndex; + + @ExcelProperty("开始执行时间") + private Date beginTime; + + @ExcelProperty("结束执行时间") + private Date endTime; + + @ExcelProperty("执行时长") + private Integer duration; + + @ExcelProperty("任务状态") + private Integer status; + + @ExcelProperty("结果数据") + private String result; + + @ExcelProperty("创建时间") + private Date createTime; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogExportReqVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogExportReqVO.java new file mode 100644 index 000000000..80cdbfb58 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogExportReqVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.dashboard.modules.infra.controller.job.vo.log; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel(value = "定时任务 Excel 导出 Request VO", description = "参数和 InfJobLogPageReqVO 是一致的") +@Data +public class InfJobLogExportReqVO { + + @ApiModelProperty(value = "处理器的名字") + private String handlerName; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始执行时间") + private Date beginTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束执行时间") + private Date endTime; + + @ApiModelProperty(value = "任务状态") + private Integer status; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogPageReqVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogPageReqVO.java new file mode 100644 index 000000000..6e007f9a2 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogPageReqVO.java @@ -0,0 +1,35 @@ +package cn.iocoder.dashboard.modules.infra.controller.job.vo.log; + +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; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel("定时任务日志分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class InfJobLogPageReqVO extends PageParam { + + @ApiModelProperty(value = "处理器的名字") + private String handlerName; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始执行时间") + private Date beginTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束执行时间") + private Date endTime; + + @ApiModelProperty(value = "任务状态") + private Integer status; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogRespVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogRespVO.java new file mode 100644 index 000000000..c50b86710 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/log/InfJobLogRespVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.dashboard.modules.infra.controller.job.vo.log; + +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 InfJobLogRespVO extends InfJobLogBaseVO { + + @ApiModelProperty(value = "日志编号", required = true) + private Long id; + + @ApiModelProperty(value = "创建时间", required = true) + private Date createTime; + +} 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 5375e8791..430c97f5e 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 @@ -75,6 +75,18 @@ public class InfJobDO extends BaseDO { */ private Date fireNextTime; + // ========== 重试相关字段 ========== + /** + * 重试次数 + * 如果不重试,则设置为 0 + */ + private Integer retryCount; + /** + * 重试间隔,单位:毫秒 + * 如果没有间隔,则设置为 0 + */ + private Integer retryInterval; + // ========== 监控相关字段 ========== /** * 监控超时时间,单位:毫秒 diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLogDO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLogDO.java index ef4ab1289..31be9a7be 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLogDO.java +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLogDO.java @@ -44,6 +44,12 @@ public class InfJobLogDO extends BaseDO { * 冗余字段 {@link InfJobDO#getHandlerParam()} */ private String handlerParam; + /** + * 第几次执行 + * + * 用于区分是不是重试执行。如果是重试执行,则 index 大于 1 + */ + private Integer executeIndex; /** * 开始执行时间 diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/enums/job/InfJobStatusEnum.java b/src/main/java/cn/iocoder/dashboard/modules/infra/enums/job/InfJobStatusEnum.java index 542091340..0fb1a39db 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/enums/job/InfJobStatusEnum.java +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/enums/job/InfJobStatusEnum.java @@ -23,17 +23,13 @@ public enum InfJobStatusEnum { */ INIT(0, Collections.emptySet()), /** - * 开启运行 + * 开启 */ NORMAL(1, Sets.newHashSet(STATE_WAITING, STATE_ACQUIRED, STATE_BLOCKED)), /** - * 异常运行 + * 暂停 */ - EXCEPTION(2, Sets.newHashSet(STATE_COMPLETE)), - /** - * 暂停运行 - */ - STOP(3, Sets.newHashSet(STATE_PAUSED, STATE_PAUSED_BLOCKED)); + STOP(2, Sets.newHashSet(STATE_PAUSED, STATE_PAUSED_BLOCKED)); /** * 状态 diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobLogServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobLogServiceImpl.java index 0303369b0..a473170b0 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobLogServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobLogServiceImpl.java @@ -26,8 +26,8 @@ public class InfJobLogServiceImpl implements InfJobLogService { private InfJobLogMapper jobLogMapper; @Override - public Long createJobLog(Long jobId, Date beginTime, String jobHandlerName, String jobHandlerParam) { - InfJobLogDO log = InfJobLogDO.builder().jobId(jobId).handlerName(jobHandlerName).handlerParam(jobHandlerParam) + public Long createJobLog(Long jobId, Date beginTime, String jobHandlerName, String jobHandlerParam, Integer executeIndex) { + InfJobLogDO log = InfJobLogDO.builder().jobId(jobId).handlerName(jobHandlerName).handlerParam(jobHandlerParam).executeIndex(executeIndex) .beginTime(beginTime).status(InfJobLogStatusEnum.RUNNING.getStatus()).build(); jobLogMapper.insert(log); return log.getId(); @@ -35,24 +35,14 @@ public class InfJobLogServiceImpl implements InfJobLogService { @Override @Async - public void updateJobLogSuccessAsync(Long logId, Date endTime, Integer duration, String result) { - updateJobLogResult(logId, endTime, duration, result, InfJobLogStatusEnum.SUCCESS); - } - - @Override - @Async - public void updateJobLogErrorAsync(Long logId, Date endTime, Integer duration, String result) { - updateJobLogResult(logId, endTime, duration, result, InfJobLogStatusEnum.FAILURE); - } - - private void updateJobLogResult(Long logId, Date endTime, Integer duration, String result, InfJobLogStatusEnum status) { + public void updateJobLogResultAsync(Long logId, Date endTime, Integer duration, boolean success, String result) { try { InfJobLogDO updateObj = InfJobLogDO.builder().id(logId).endTime(endTime).duration(duration) - .status(status.getStatus()).result(result).build(); + .status(success ? InfJobLogStatusEnum.SUCCESS.getStatus() : InfJobLogStatusEnum.FAILURE.getStatus()).result(result).build(); jobLogMapper.updateById(updateObj); } catch (Exception ex) { - log.error("[updateJobLogResult][logId({}) endTime({}) duration({}) result({}) status({})]", - logId, endTime, duration, result, status); + log.error("[updateJobLogResultAsync][logId({}) endTime({}) duration({}) success({}) result({})]", + logId, endTime, duration, success, result); } } 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 index b78408de3..d82207de1 100644 --- 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 @@ -55,7 +55,8 @@ public class InfJobServiceImpl implements InfJobService { jobMapper.insert(job); // 添加 Job 到 Quartz 中 - schedulerManager.addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression()); + schedulerManager.addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression(), + createReqVO.getRetryCount(), createReqVO.getRetryInterval()); // 更新 InfJobDO updateObj = InfJobDO.builder().id(job.getId()).status(InfJobStatusEnum.NORMAL.getStatus()).build(); jobMapper.updateById(updateObj); @@ -80,7 +81,8 @@ public class InfJobServiceImpl implements InfJobService { jobMapper.updateById(updateObj); // 更新 Job 到 Quartz 中 - schedulerManager.updateJob(job.getHandlerName(), updateReqVO.getHandlerParam(), updateReqVO.getCronExpression()); + schedulerManager.updateJob(job.getHandlerName(), updateReqVO.getHandlerParam(), updateReqVO.getCronExpression(), + updateReqVO.getRetryCount(), updateReqVO.getRetryInterval()); } @Override @@ -138,7 +140,7 @@ public class InfJobServiceImpl implements InfJobService { } private void validateCronExpression(String cronExpression) { - if (CronUtils.isValid(cronExpression)) { + if (!CronUtils.isValid(cronExpression)) { throw exception(JOB_CRON_EXPRESSION_VALID); } } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/job/auth/SysUserSessionTimeoutJob.java b/src/main/java/cn/iocoder/dashboard/modules/system/job/auth/SysUserSessionTimeoutJob.java index ceb697afa..a3e132765 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/job/auth/SysUserSessionTimeoutJob.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/job/auth/SysUserSessionTimeoutJob.java @@ -15,6 +15,9 @@ public class SysUserSessionTimeoutJob implements JobHandler { @Override public String execute(String param) throws Exception { + if (true) { + throw new RuntimeException("测试异常"); + } // System.out.println("执行了一次任务"); log.info("[execute][执行任务:{}]", param); return null; diff --git a/src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenServiceImpl.java index 5d4c094bb..b17d59b9b 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenServiceImpl.java @@ -134,6 +134,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService { } @Override + @Transactional public void syncCodegenFromDB(Long tableId) { // 校验是否已经存在 ToolCodegenTableDO table = codegenTableMapper.selectById(tableId); @@ -148,6 +149,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService { } @Override + @Transactional public void syncCodegenFromSQL(Long tableId, String sql) { // 校验是否已经存在 ToolCodegenTableDO table = codegenTableMapper.selectById(tableId); @@ -193,7 +195,9 @@ public class ToolCodegenServiceImpl implements ToolCodegenService { codegenColumnMapper.insert(column); // TODO 批量插入 }); // 删除不存在的字段 - codegenColumnMapper.deleteBatchIds(deleteColumnIds); + if (CollUtil.isNotEmpty(deleteColumnIds)) { + codegenColumnMapper.deleteBatchIds(deleteColumnIds); + } } @Override diff --git a/src/main/resources/codegen/java/dal/mapper.vm b/src/main/resources/codegen/java/dal/mapper.vm index 57228264c..8d3a81ddd 100644 --- a/src/main/resources/codegen/java/dal/mapper.vm +++ b/src/main/resources/codegen/java/dal/mapper.vm @@ -27,7 +27,10 @@ import ${basePackage}.${table.moduleName}.controller.${table.businessName}.vo.*; .geIfPresent("${column.columnName}", reqVO.get${JavaField}()) #end #if (${column.listOperationCondition} == "<")##情况五,< 的时候 - .gtIfPresent("${column.columnName}", reqVO.get${JavaField}()) + .ltIfPresent("${column.columnName}", reqVO.get${JavaField}()) +#end +#if (${column.listOperationCondition} == "<=")##情况五,<= 的时候 + .leIfPresent("${column.columnName}", reqVO.get${JavaField}()) #end #if (${column.listOperationCondition} == "LIKE")##情况七,Like 的时候 .likeIfPresent("${column.columnName}", reqVO.get${JavaField}()) 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 bae46416d..8a92b81a7 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 @@ -20,13 +20,13 @@ class SchedulerManagerTest { @Test public void testAddJob() throws SchedulerException { String jobHandlerName = StrUtil.lowerFirst(SysUserSessionTimeoutJob.class.getSimpleName()); - schedulerManager.addJob(1L, jobHandlerName, "test", "0/10 * * * * ? *"); + schedulerManager.addJob(1L, jobHandlerName, "test", "0/10 * * * * ? *", 0, 0); } @Test public void testUpdateJob() throws SchedulerException { String jobHandlerName = StrUtil.lowerFirst(SysUserSessionTimeoutJob.class.getSimpleName()); - schedulerManager.updateJob(jobHandlerName, "hahaha", "0/20 * * * * ? *"); + schedulerManager.updateJob(jobHandlerName, "hahaha", "0/20 * * * * ? *", 0, 0); } @Test