增加定时任务管理
This commit is contained in:
parent
03d09ca7d7
commit
327f0df6a9
|
|
@ -36,10 +36,16 @@
|
|||
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SaToken-Redis -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-dao-redis-jackson</artifactId>
|
||||
<version>1.32.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Quartz-Scheduler -->
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
package com.mdd.admin.config.quartz;
|
||||
|
||||
import org.quartz.CronExpression;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 表达式工具
|
||||
*/
|
||||
public class CronUtils {
|
||||
|
||||
/**
|
||||
* 验证表达式是否有效
|
||||
*
|
||||
* @param cronExpression 表达式
|
||||
* @return true=有效,false=无效
|
||||
*/
|
||||
public static boolean isValid(String cronExpression) {
|
||||
return CronExpression.isValidExpression(cronExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证表达式消息无效给出有效性
|
||||
*
|
||||
* @param cronExpression 表达式
|
||||
* @return null=有效, 其它=无效时的错误描述
|
||||
*/
|
||||
public static String invalidMessage(String cronExpression) {
|
||||
try {
|
||||
new CronExpression(cronExpression);
|
||||
return null;
|
||||
} catch (ParseException pe) {
|
||||
return pe.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下一个执行时间点
|
||||
*
|
||||
* @param cronExpression n表达式
|
||||
* @return Date下次表达式执行时间
|
||||
*/
|
||||
public static Date nextExecution(String cronExpression)
|
||||
{
|
||||
try {
|
||||
CronExpression cron = new CronExpression(cronExpression);
|
||||
return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis()));
|
||||
} catch (ParseException e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
package com.mdd.admin.config.quartz;
|
||||
|
||||
import com.mdd.common.entity.Crontab;
|
||||
import com.mdd.common.utils.SpringUtil;
|
||||
import com.mdd.common.utils.StringUtil;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 执行工具
|
||||
*/
|
||||
public class InvokeUtils {
|
||||
|
||||
/**
|
||||
* 执行方法
|
||||
*
|
||||
* @param crontab 系统任务
|
||||
*/
|
||||
public static void invokeMethod(Crontab crontab) throws Exception {
|
||||
String invokeTarget = crontab.getCommand();
|
||||
String beanName = getBeanName(invokeTarget);
|
||||
String methodName = getMethodName(invokeTarget);
|
||||
List<Object[]> methodParams = getMethodParams(invokeTarget);
|
||||
|
||||
if (!isValidClassName(beanName)) {
|
||||
Object bean = SpringUtil.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<Object[]> methodParams)
|
||||
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
|
||||
InvocationTargetException {
|
||||
if (StringUtil.isNotNull(methodParams) && methodParams.size() > 0) {
|
||||
Method method = bean.getClass().getMethod(methodName, getMethodParamsType(methodParams));
|
||||
method.invoke(bean, getMethodParamsValue(methodParams));
|
||||
} else {
|
||||
Method method = bean.getClass().getMethod(methodName);
|
||||
method.invoke(bean);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验是否为为class包名
|
||||
*
|
||||
* @param invokeTarget 名称
|
||||
* @return true是 false否
|
||||
*/
|
||||
public static boolean isValidClassName(String invokeTarget) {
|
||||
return StringUtil.countMatches(invokeTarget, ".") > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取bean名称
|
||||
*
|
||||
* @param invokeTarget 目标字符串
|
||||
* @return bean名称
|
||||
*/
|
||||
public static String getBeanName(String invokeTarget) {
|
||||
String beanName = StringUtil.substringBefore(invokeTarget, "(");
|
||||
return StringUtil.substringBeforeLast(beanName, ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取bean方法
|
||||
*
|
||||
* @param invokeTarget 目标字符串
|
||||
* @return method方法
|
||||
*/
|
||||
public static String getMethodName(String invokeTarget) {
|
||||
String methodName = StringUtil.substringBefore(invokeTarget, "(");
|
||||
return StringUtil.substringAfterLast(methodName, ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取method方法参数相关列表
|
||||
*
|
||||
* @param invokeTarget 目标字符串
|
||||
* @return method方法相关参数列表
|
||||
*/
|
||||
public static List<Object[]> getMethodParams(String invokeTarget) {
|
||||
String methodStr = StringUtil.substringBetween(invokeTarget, "(", ")");
|
||||
if (StringUtil.isEmpty(methodStr)) {
|
||||
return null;
|
||||
}
|
||||
String[] methodParams = methodStr.split(",(?=([^\"']*[\"'][^\"']*[\"'])*[^\"']*$)");
|
||||
List<Object[]> clazz = new LinkedList<>();
|
||||
for (String methodParam : methodParams) {
|
||||
String str = StringUtil.trimToEmpty(methodParam);
|
||||
if (StringUtil.startsWithAny(str, "'", "\"")) {
|
||||
clazz.add(new Object[]{StringUtil.substring(str, 1, str.length() - 1), String.class});
|
||||
} else if ("true".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str)) {
|
||||
clazz.add(new Object[]{Boolean.valueOf(str), Boolean.class});
|
||||
} else if (StringUtil.endsWith(str, "L")) {
|
||||
clazz.add(new Object[]{Long.valueOf(StringUtil.substring(str, 0, str.length() - 1)), Long.class});
|
||||
} else if (StringUtil.endsWith(str, "D")) {
|
||||
clazz.add(new Object[]{Double.valueOf(StringUtil.substring(str, 0, str.length() - 1)), Double.class});
|
||||
} else {
|
||||
clazz.add(new Object[]{Integer.valueOf(str), Integer.class});
|
||||
}
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参数类型
|
||||
*
|
||||
* @param methodParams 参数相关列表
|
||||
* @return 参数类型列表
|
||||
*/
|
||||
public static Class<?>[] getMethodParamsType(List<Object[]> methodParams) {
|
||||
Class<?>[] clazz = new Class<?>[methodParams.size()];
|
||||
int index = 0;
|
||||
for (Object[] os : methodParams)
|
||||
{
|
||||
clazz[index] = (Class<?>) os[1];
|
||||
index++;
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参数值
|
||||
*
|
||||
* @param methodParams 参数相关列表
|
||||
* @return 参数值列表
|
||||
*/
|
||||
public static Object[] getMethodParamsValue(List<Object[]> methodParams) {
|
||||
Object[] clazz = new Object[methodParams.size()];
|
||||
int index = 0;
|
||||
for (Object[] os : methodParams) {
|
||||
clazz[index] = os[0];
|
||||
index++;
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
package com.mdd.admin.config.quartz;
|
||||
|
||||
import com.mdd.admin.config.quartz.exceution.QuartzDisExecution;
|
||||
import com.mdd.admin.config.quartz.exceution.QuartzJobExecution;
|
||||
import com.mdd.common.entity.Crontab;
|
||||
import com.mdd.common.utils.StringUtil;
|
||||
import org.quartz.*;
|
||||
|
||||
/**
|
||||
* 计划任务工具
|
||||
*/
|
||||
public class QuartzUtils {
|
||||
|
||||
/**
|
||||
* 得到quartz任务类
|
||||
*
|
||||
* @param crontab 执行计划
|
||||
* @return 具体执行任务类
|
||||
*/
|
||||
private static Class<? extends Job> getQuartzJobClass(Crontab crontab) {
|
||||
boolean isConcurrent = crontab.getConcurrent().equals(0);
|
||||
return isConcurrent ? QuartzJobExecution.class : QuartzDisExecution.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建任务对象Key
|
||||
*
|
||||
* @param jobId (任务ID)
|
||||
* @param jobGroup (任务分组)
|
||||
* @return JobKey
|
||||
*/
|
||||
public static JobKey getJobKey(Integer jobId, String jobGroup) {
|
||||
return JobKey.jobKey(TaskConstants.TASK_CLASS_NAME + jobId, jobGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建触发对象Key
|
||||
*
|
||||
* @param jobId (任务ID)
|
||||
* @param jobGroup (任务分组)
|
||||
* @return TriggerKey
|
||||
*/
|
||||
public static TriggerKey getTriggerKey(Integer jobId, String jobGroup) {
|
||||
return TriggerKey.triggerKey(TaskConstants.TASK_PROPERTIES + jobId, jobGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建定时任务
|
||||
*
|
||||
* @param scheduler 调度器
|
||||
* @param job 任务
|
||||
* @throws SchedulerException 调度异常
|
||||
*/
|
||||
public static void createScheduleJob(Scheduler scheduler, Crontab job) throws SchedulerException {
|
||||
Integer jobId = job.getId();
|
||||
String jobGroup = job.getGroups();
|
||||
String expression = job.getRules();
|
||||
|
||||
// 构建任务
|
||||
Class<? extends Job> jobClass = getQuartzJobClass(job);
|
||||
JobDetail jobDetail = JobBuilder.newJob(jobClass)
|
||||
.withIdentity(getJobKey(jobId, jobGroup))
|
||||
.build();
|
||||
|
||||
// 构建时间
|
||||
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(expression);
|
||||
switch (job.getStrategy()) {
|
||||
case 1: // 立即执行
|
||||
cronScheduleBuilder = cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires();
|
||||
break;
|
||||
case 2: // 执行一次
|
||||
cronScheduleBuilder = cronScheduleBuilder.withMisfireHandlingInstructionFireAndProceed();
|
||||
break;
|
||||
case 3: // 放弃执行
|
||||
cronScheduleBuilder = cronScheduleBuilder.withMisfireHandlingInstructionDoNothing();
|
||||
break;
|
||||
}
|
||||
|
||||
// 注入参数
|
||||
jobDetail.getJobDataMap().put(TaskConstants.TASK_PROPERTIES, job);
|
||||
|
||||
// 构建目标
|
||||
CronTrigger trigger = TriggerBuilder.newTrigger()
|
||||
.withIdentity(getTriggerKey(jobId, jobGroup))
|
||||
.withSchedule(cronScheduleBuilder)
|
||||
.build();
|
||||
|
||||
// 如果存在则删除
|
||||
if (scheduler.checkExists(getJobKey(jobId, jobGroup))) {
|
||||
scheduler.deleteJob(getJobKey(jobId, jobGroup));
|
||||
}
|
||||
|
||||
// 如果过期则调度
|
||||
if (StringUtil.isNotNull(CronUtils.nextExecution(job.getRules()))) {
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
}
|
||||
|
||||
// 如果暂停则停止
|
||||
if (!job.getStatus().equals(TaskConstants.STATUS_RUN)) {
|
||||
scheduler.pauseJob(getJobKey(jobId, jobGroup));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.mdd.admin.config.quartz;
|
||||
|
||||
/**
|
||||
* 计划任务常量
|
||||
*/
|
||||
public class TaskConstants {
|
||||
|
||||
/** 执行任务名 */
|
||||
public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME";
|
||||
|
||||
/** 执行目标键 */
|
||||
public static final String TASK_PROPERTIES = "TASK_PROPERTIES";
|
||||
|
||||
/** 状态: 运行 */
|
||||
public static final Integer STATUS_RUN = 1;
|
||||
|
||||
/** 状态: 停止 */
|
||||
public static final Integer STATUS_STOP = 2;
|
||||
|
||||
/** 状态: 失败 */
|
||||
public static final Integer STATUS_FAIL = 2;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
package com.mdd.admin.config.quartz.exceution;
|
||||
|
||||
import com.mdd.admin.config.quartz.TaskConstants;
|
||||
import com.mdd.common.entity.Crontab;
|
||||
import com.mdd.common.mapper.CrontabMapper;
|
||||
import com.mdd.common.utils.SpringUtil;
|
||||
import com.mdd.common.utils.StringUtil;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
public abstract class AbstractQuartzJob implements Job {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class);
|
||||
|
||||
/**
|
||||
* 线程本地变量
|
||||
*/
|
||||
private static final ThreadLocal<Long> threadLocal = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 执行
|
||||
*
|
||||
* @param context 上下文
|
||||
*/
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) {
|
||||
Crontab crontab = new Crontab();
|
||||
BeanUtils.copyProperties(context.getMergedJobDataMap().get(TaskConstants.TASK_PROPERTIES), crontab);
|
||||
try {
|
||||
before();
|
||||
doExecute(context, crontab);
|
||||
after(crontab, null);
|
||||
} catch (Exception e) {
|
||||
log.error("任务执行异常:", e);
|
||||
after(crontab, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行前
|
||||
*/
|
||||
protected void before() {
|
||||
threadLocal.set(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行后
|
||||
*
|
||||
* @param crontab 系统计划任务
|
||||
*/
|
||||
protected void after(Crontab crontab, Exception e)
|
||||
{
|
||||
long startTime = threadLocal.get();
|
||||
long endTime = System.currentTimeMillis();
|
||||
threadLocal.remove();
|
||||
|
||||
crontab.setError("");
|
||||
crontab.setStartTime(startTime / 1000);
|
||||
crontab.setEndTime(endTime / 1000);
|
||||
crontab.setTaskTime(endTime - startTime);
|
||||
if (StringUtil.isNotNull(e)) {
|
||||
crontab.setError(e.getMessage());
|
||||
crontab.setStatus(TaskConstants.STATUS_FAIL);
|
||||
}
|
||||
|
||||
SpringUtil.getBean(CrontabMapper.class).updateById(crontab);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行方法
|
||||
*
|
||||
* @param context 工作执行上下文对象
|
||||
* @param sysJob 系统计划任务
|
||||
* @throws Exception 执行过程中的异常
|
||||
*/
|
||||
protected abstract void doExecute(JobExecutionContext context, Crontab sysJob) throws Exception;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.mdd.admin.config.quartz.exceution;
|
||||
|
||||
import com.mdd.admin.config.quartz.InvokeUtils;
|
||||
import com.mdd.common.entity.Crontab;
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
import org.quartz.JobExecutionContext;
|
||||
|
||||
/**
|
||||
* 禁止并发任务
|
||||
*/
|
||||
@DisallowConcurrentExecution
|
||||
public class QuartzDisExecution extends AbstractQuartzJob {
|
||||
|
||||
@Override
|
||||
protected void doExecute(JobExecutionContext context, Crontab crontab) throws Exception {
|
||||
InvokeUtils.invokeMethod(crontab);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.mdd.admin.config.quartz.exceution;
|
||||
|
||||
import com.mdd.admin.config.quartz.InvokeUtils;
|
||||
import com.mdd.common.entity.Crontab;
|
||||
import org.quartz.JobExecutionContext;
|
||||
|
||||
/**
|
||||
* 允许并发任务
|
||||
*/
|
||||
public class QuartzJobExecution extends AbstractQuartzJob {
|
||||
|
||||
@Override
|
||||
protected void doExecute(JobExecutionContext context, Crontab crontab) throws Exception {
|
||||
InvokeUtils.invokeMethod(crontab);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import com.mdd.admin.vo.CrontabListedVo;
|
|||
import com.mdd.common.core.AjaxResult;
|
||||
import com.mdd.common.core.PageResult;
|
||||
import com.mdd.common.validator.annotation.IDMust;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
|
@ -56,7 +57,7 @@ public class CrontabController {
|
|||
* @return AjaxResult<Object>
|
||||
*/
|
||||
@PostMapping("/add")
|
||||
public AjaxResult<Object> add(@Validated @RequestBody CrontabCreateValidate createValidate) {
|
||||
public AjaxResult<Object> add(@Validated @RequestBody CrontabCreateValidate createValidate) throws SchedulerException {
|
||||
iCrontabService.add(createValidate);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
|
@ -69,7 +70,7 @@ public class CrontabController {
|
|||
* @return AjaxResult<Object>
|
||||
*/
|
||||
@PostMapping("/edit")
|
||||
public AjaxResult<Object> edit(@Validated @RequestBody CrontabUpdateValidate updateValidate) {
|
||||
public AjaxResult<Object> edit(@Validated @RequestBody CrontabUpdateValidate updateValidate) throws SchedulerException {
|
||||
iCrontabService.edit(updateValidate);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
|
@ -82,7 +83,7 @@ public class CrontabController {
|
|||
* @return AjaxResult<Object>
|
||||
*/
|
||||
@PostMapping("/del")
|
||||
public AjaxResult<Object> del(@Validated @RequestBody IdValidate idValidate) {
|
||||
public AjaxResult<Object> del(@Validated @RequestBody IdValidate idValidate) throws SchedulerException {
|
||||
iCrontabService.del(idValidate.getId());
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
package com.mdd.admin.crontab;
|
||||
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
/**
|
||||
* 工作类的具体实现,即需要定时执行的“某个事件”
|
||||
*/
|
||||
@Component("myJob")
|
||||
public class MyJob {
|
||||
|
||||
public void handle(String s) {
|
||||
System.out.println("执行无参方法: " + s);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import com.mdd.admin.validate.commons.PageValidate;
|
|||
import com.mdd.admin.vo.CrontabDetailVo;
|
||||
import com.mdd.admin.vo.CrontabListedVo;
|
||||
import com.mdd.common.core.PageResult;
|
||||
import org.quartz.SchedulerException;
|
||||
|
||||
/**
|
||||
* 计划任务服务接口类
|
||||
|
|
@ -36,7 +37,7 @@ public interface ICrontabService {
|
|||
* @author fzr
|
||||
* @param createValidate 参数
|
||||
*/
|
||||
void add(CrontabCreateValidate createValidate);
|
||||
void add(CrontabCreateValidate createValidate) throws SchedulerException;
|
||||
|
||||
/**
|
||||
* 计划任务编辑
|
||||
|
|
@ -44,7 +45,7 @@ public interface ICrontabService {
|
|||
* @author fzr
|
||||
* @param updateValidate 参数
|
||||
*/
|
||||
void edit(CrontabUpdateValidate updateValidate);
|
||||
void edit(CrontabUpdateValidate updateValidate) throws SchedulerException;
|
||||
|
||||
/**
|
||||
* 计划任务删除
|
||||
|
|
@ -52,6 +53,6 @@ public interface ICrontabService {
|
|||
* @author fzr
|
||||
* @param id 主键
|
||||
*/
|
||||
void del(Integer id);
|
||||
void del(Integer id) throws SchedulerException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.mdd.admin.service.impl;
|
|||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.mdd.admin.config.quartz.QuartzUtils;
|
||||
import com.mdd.admin.service.ICrontabService;
|
||||
import com.mdd.admin.validate.CrontabCreateValidate;
|
||||
import com.mdd.admin.validate.CrontabUpdateValidate;
|
||||
|
|
@ -11,12 +12,15 @@ import com.mdd.admin.vo.CrontabDetailVo;
|
|||
import com.mdd.admin.vo.CrontabListedVo;
|
||||
import com.mdd.common.core.PageResult;
|
||||
import com.mdd.common.entity.Crontab;
|
||||
import com.mdd.common.entity.server.Sys;
|
||||
import com.mdd.common.mapper.CrontabMapper;
|
||||
import com.mdd.common.utils.TimeUtil;
|
||||
import org.quartz.*;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
|
@ -27,9 +31,27 @@ import java.util.List;
|
|||
@Service
|
||||
public class CrontabServiceImpl implements ICrontabService {
|
||||
|
||||
@Resource
|
||||
Scheduler scheduler;
|
||||
|
||||
@Resource
|
||||
CrontabMapper crontabMapper;
|
||||
|
||||
/**
|
||||
* 项目启动初始化任务
|
||||
*
|
||||
* @author fzr
|
||||
* @throws SchedulerException 异常
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init() throws SchedulerException {
|
||||
scheduler.clear();
|
||||
List<Crontab> jobs = crontabMapper.selectList(new QueryWrapper<Crontab>().eq("is_delete", 0));
|
||||
for (Crontab crontab : jobs) {
|
||||
QuartzUtils.createScheduleJob(scheduler, crontab);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计划任务列表
|
||||
*
|
||||
|
|
@ -52,6 +74,8 @@ public class CrontabServiceImpl implements ICrontabService {
|
|||
CrontabListedVo vo = new CrontabListedVo();
|
||||
BeanUtils.copyProperties(crontab, vo);
|
||||
|
||||
vo.setStartTime(crontab.getStartTime()<=0?"-": TimeUtil.timestampToDate(crontab.getStartTime()));
|
||||
vo.setEndTime(crontab.getEndTime()<=0?"-": TimeUtil.timestampToDate(crontab.getEndTime()));
|
||||
list.add(vo);
|
||||
}
|
||||
|
||||
|
|
@ -87,16 +111,21 @@ public class CrontabServiceImpl implements ICrontabService {
|
|||
* @param createValidate 参数
|
||||
*/
|
||||
@Override
|
||||
public void add(CrontabCreateValidate createValidate) {
|
||||
@Transactional
|
||||
public void add(CrontabCreateValidate createValidate) throws SchedulerException {
|
||||
Crontab crontab = new Crontab();
|
||||
crontab.setName(createValidate.getName());
|
||||
crontab.setCommand(createValidate.getCommand());
|
||||
crontab.setRules(createValidate.getRules());
|
||||
crontab.setStatus(createValidate.getStatus());
|
||||
crontab.setRemark(createValidate.getRemark());
|
||||
crontab.setStrategy(createValidate.getStrategy());
|
||||
crontab.setConcurrent(createValidate.getConcurrent());
|
||||
crontab.setCreateTime(System.currentTimeMillis() / 1000);
|
||||
crontab.setUpdateTime(System.currentTimeMillis() / 1000);
|
||||
crontabMapper.insert(crontab);
|
||||
|
||||
QuartzUtils.createScheduleJob(scheduler, crontab);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -106,7 +135,8 @@ public class CrontabServiceImpl implements ICrontabService {
|
|||
* @param updateValidate 参数
|
||||
*/
|
||||
@Override
|
||||
public void edit(CrontabUpdateValidate updateValidate) {
|
||||
@Transactional
|
||||
public void edit(CrontabUpdateValidate updateValidate) throws SchedulerException {
|
||||
Crontab crontab = crontabMapper.selectOne(
|
||||
new QueryWrapper<Crontab>()
|
||||
.eq("id", updateValidate.getId())
|
||||
|
|
@ -117,15 +147,27 @@ public class CrontabServiceImpl implements ICrontabService {
|
|||
|
||||
crontab.setName(updateValidate.getName());
|
||||
crontab.setCommand(updateValidate.getCommand());
|
||||
crontab.setGroups(updateValidate.getGroups());
|
||||
crontab.setRules(updateValidate.getRules());
|
||||
crontab.setStatus(updateValidate.getStatus());
|
||||
crontab.setRemark(updateValidate.getRemark());
|
||||
crontab.setStrategy(updateValidate.getStrategy());
|
||||
crontab.setConcurrent(updateValidate.getConcurrent());
|
||||
crontab.setUpdateTime(System.currentTimeMillis() / 1000);
|
||||
crontabMapper.updateById(crontab);
|
||||
|
||||
QuartzUtils.createScheduleJob(scheduler, crontab);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计划任务删除
|
||||
*
|
||||
* @author fzr
|
||||
* @param id 主键
|
||||
*/
|
||||
@Override
|
||||
public void del(Integer id) {
|
||||
@Transactional
|
||||
public void del(Integer id) throws SchedulerException {
|
||||
Crontab crontab = crontabMapper.selectOne(
|
||||
new QueryWrapper<Crontab>()
|
||||
.eq("id", id)
|
||||
|
|
@ -137,6 +179,8 @@ public class CrontabServiceImpl implements ICrontabService {
|
|||
crontab.setIsDelete(1);
|
||||
crontab.setDeleteTime(System.currentTimeMillis() / 1000);
|
||||
crontabMapper.updateById(crontab);
|
||||
|
||||
scheduler.deleteJob(QuartzUtils.getJobKey(crontab.getId(), crontab.getGroups()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.mdd.admin.validate;
|
|||
|
||||
import com.mdd.common.validator.annotation.IntegerContains;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
|
@ -20,9 +21,19 @@ public class CrontabCreateValidate implements Serializable {
|
|||
@NotNull(message = "rules参数缺失")
|
||||
private String rules;
|
||||
|
||||
@Length(max = 200, message = "remark参数不能超出200个字符")
|
||||
private String remark;
|
||||
|
||||
@NotNull(message = "status参数缺失")
|
||||
@IntegerContains(values = {1, 2, 3}, message = "status参数取值异常")
|
||||
private Integer status;
|
||||
|
||||
private String remark;
|
||||
@NotNull(message = "strategy参数缺失")
|
||||
@IntegerContains(values = {1, 2, 3}, message = "strategy参数取值异常")
|
||||
private Integer strategy;
|
||||
|
||||
@NotNull(message = "concurrent参数缺失")
|
||||
@IntegerContains(values = {0, 1}, message = "concurrent参数取值异常")
|
||||
private Integer concurrent;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.mdd.admin.validate;
|
|||
import com.mdd.common.validator.annotation.IDMust;
|
||||
import com.mdd.common.validator.annotation.IntegerContains;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
|
@ -15,6 +16,9 @@ public class CrontabUpdateValidate implements Serializable {
|
|||
@IDMust(message = "id参数必传且需大于0")
|
||||
private Integer id;
|
||||
|
||||
@NotNull(message = "groups参数缺失")
|
||||
private String groups;
|
||||
|
||||
@NotNull(message = "name参数缺失")
|
||||
private String name;
|
||||
|
||||
|
|
@ -24,9 +28,19 @@ public class CrontabUpdateValidate implements Serializable {
|
|||
@NotNull(message = "rules参数缺失")
|
||||
private String rules;
|
||||
|
||||
@Length(max = 200, message = "remark参数不能超出200个字符")
|
||||
private String remark;
|
||||
|
||||
@NotNull(message = "status参数缺失")
|
||||
@IntegerContains(values = {1, 2, 3}, message = "status参数取值异常")
|
||||
private Integer status;
|
||||
|
||||
private String remark;
|
||||
@NotNull(message = "strategy参数缺失")
|
||||
@IntegerContains(values = {1, 2, 3}, message = "strategy参数取值异常")
|
||||
private Integer strategy;
|
||||
|
||||
@NotNull(message = "concurrent参数缺失")
|
||||
@IntegerContains(values = {0, 1}, message = "concurrent参数取值异常")
|
||||
private Integer concurrent;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,15 +4,23 @@ import lombok.Data;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 计划任务详情Vo
|
||||
*/
|
||||
@Data
|
||||
public class CrontabDetailVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Integer id;
|
||||
private String name;
|
||||
private String command;
|
||||
private String rules;
|
||||
private Integer status;
|
||||
private Integer id; // 任务主键
|
||||
private String groups; // 任务分组
|
||||
private String name; // 任务名称
|
||||
private String command; // 执行命令
|
||||
private String rules; // 执行规则
|
||||
private String remark; // 备注信息
|
||||
private String error; // 错误信息
|
||||
private Integer status; // 执行状态: 1=正在运行, 2=任务停止, 3=发生错误
|
||||
private Integer strategy; // 执行策略: 1=立即执行, 2=执行一次, 3=放弃执行
|
||||
private Integer concurrent; // 并发执行: 0=否, 1=是
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,15 +4,25 @@ import lombok.Data;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 计划任务列表Vo
|
||||
*/
|
||||
@Data
|
||||
public class CrontabListedVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Integer id;
|
||||
private String name;
|
||||
private String command;
|
||||
private String rules;
|
||||
private Integer status;
|
||||
private Integer id; // 执行ID
|
||||
private String groups; // 执行分组
|
||||
private String name; // 执行名称
|
||||
private String command; // 执行命令
|
||||
private String rules; // 执行规则
|
||||
private String error; // 错误信息
|
||||
private Integer status; // 执行状态: 1=正在运行, 2=任务停止, 3=发生错误
|
||||
private Integer strategy; // 执行策略: 1=立即执行, 2=执行一次, 3=放弃执行
|
||||
private Integer concurrent; // 并发执行: 0=否, 1=是
|
||||
private String startTime; // 开始时间
|
||||
private String endTime; // 结束时间
|
||||
private Long taskTime; // 执行耗时
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,15 +15,22 @@ public class Crontab implements Serializable {
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value="id", type= IdType.AUTO)
|
||||
private Integer id; // 主键
|
||||
private String name; // 任务名称
|
||||
private String command; // 任务命令
|
||||
private String rules; // 任务规则
|
||||
private String remark; // 备注信息
|
||||
private Integer status; // 执行状态:1=运行, 2-停止, 3=错误
|
||||
private Integer isDelete; // 是否删除: 0=否, 1=是
|
||||
private Long createTime; // 创建时间
|
||||
private Long updateTime; // 更新时间
|
||||
private Long deleteTime; // 删除时间
|
||||
private Integer id; // 主键
|
||||
private String name; // 任务名称
|
||||
private String groups; // 任务分组
|
||||
private String command; // 执行命令
|
||||
private String rules; // 执行规则
|
||||
private String remark; // 备注信息
|
||||
private String error; // 错误信息
|
||||
private Integer status; // 执行状态: 1=正在运行, 2=任务停止, 3=发生错误
|
||||
private Integer strategy; // 执行策略: 1=立即执行, 2=执行一次, 3=放弃执行
|
||||
private Integer concurrent; // 并发执行: 0=否, 1=是
|
||||
private Integer isDelete; // 是否删除: 0=否, 1=是
|
||||
private Long startTime; // 开始时间
|
||||
private Long endTime; // 结束时间
|
||||
private Long taskTime; // 任务耗时
|
||||
private Long createTime; // 创建时间
|
||||
private Long updateTime; // 更新时间
|
||||
private Long deleteTime; // 删除时间
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@
|
|||
<bitwalker.version>1.2.4</bitwalker.version>
|
||||
<oshi-core.version>6.1.2</oshi-core.version>
|
||||
<sa-token.version>1.32.0</sa-token.version>
|
||||
<sa-token-redis.version>1.32.0</sa-token-redis.version>
|
||||
<easyexcel.version>3.1.3</easyexcel.version>
|
||||
<quartz-scheduler.version>2.3.2</quartz-scheduler.version>
|
||||
|
||||
<qiniu.version>7.9.5</qiniu.version>
|
||||
<qcloud-version>5.6.54</qcloud-version>
|
||||
|
|
@ -121,6 +123,20 @@
|
|||
<version>${sa-token.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- SaToken-Redis -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-dao-redis-jackson</artifactId>
|
||||
<version>${sa-token-redis.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Quartz-Scheduler -->
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
<version>${quartz-scheduler.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Gson工具 -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
|
|
|
|||
Loading…
Reference in New Issue