Commit e34b4ea6 by RuoYi

定时任务支持并发控制

parent 9fc42511
...@@ -22,7 +22,7 @@ public class Global ...@@ -22,7 +22,7 @@ public class Global
/** /**
* 当前对象实例 * 当前对象实例
*/ */
private static Global global = null; private static Global global;
/** /**
* 保存全局属性值 * 保存全局属性值
...@@ -34,19 +34,14 @@ public class Global ...@@ -34,19 +34,14 @@ public class Global
} }
/** /**
* 静态工厂方法 获取当前对象实例 多线程安全单例模式(使用双重同步锁) * 静态工厂方法
*/ */
public static synchronized Global getInstance() public static synchronized Global getInstance()
{ {
if (global == null) if (global == null)
{ {
synchronized (Global.class)
{
if (global == null)
global = new Global(); global = new Global();
} }
}
return global; return global;
} }
......
...@@ -7,9 +7,10 @@ package com.ruoyi.common.constant; ...@@ -7,9 +7,10 @@ package com.ruoyi.common.constant;
*/ */
public interface ScheduleConstants public interface ScheduleConstants
{ {
public static final String TASK_CLASS_NAME = "__TASK_CLASS_NAME__"; public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME";
public static final String TASK_PROPERTIES = "__TASK_PROPERTIES__"; /** 执行目标key */
public static final String TASK_PROPERTIES = "TASK_PROPERTIES";
/** 默认 */ /** 默认 */
public static final String MISFIRE_DEFAULT = "0"; public static final String MISFIRE_DEFAULT = "0";
......
...@@ -223,6 +223,7 @@ public class JSONObject extends LinkedHashMap<String, Object> ...@@ -223,6 +223,7 @@ public class JSONObject extends LinkedHashMap<String, Object>
{ {
return endArray(matcher.group(1), matcher.group(2), new EndArrayCallback<Object>() return endArray(matcher.group(1), matcher.group(2), new EndArrayCallback<Object>()
{ {
@Override
public Object callback(JSONArray arr, int index) public Object callback(JSONArray arr, int index)
{ {
return elementAt(arr, index); return elementAt(arr, index);
...@@ -257,6 +258,7 @@ public class JSONObject extends LinkedHashMap<String, Object> ...@@ -257,6 +258,7 @@ public class JSONObject extends LinkedHashMap<String, Object>
{ {
endArray(matcher.group(1), matcher.group(2), new EndArrayCallback<Void>() endArray(matcher.group(1), matcher.group(2), new EndArrayCallback<Void>()
{ {
@Override
public Void callback(JSONArray arr, int index) public Void callback(JSONArray arr, int index)
{ {
elementAt(arr, index, value); elementAt(arr, index, value);
...@@ -285,6 +287,7 @@ public class JSONObject extends LinkedHashMap<String, Object> ...@@ -285,6 +287,7 @@ public class JSONObject extends LinkedHashMap<String, Object>
{ {
return endArray(matcher.group(1), matcher.group(2), new EndArrayCallback<JSONObject>() return endArray(matcher.group(1), matcher.group(2), new EndArrayCallback<JSONObject>()
{ {
@Override
public JSONObject callback(JSONArray arr, int index) public JSONObject callback(JSONArray arr, int index)
{ {
return objAt(arr, index); return objAt(arr, index);
......
package com.ruoyi.common.utils;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.apache.commons.lang3.exception.ExceptionUtils;
/**
* 错误信息处理类。
*
* @author ruoyi
*/
public class ExceptionUtil
{
/**
* 获取exception的详细错误信息。
*/
public static String getExceptionMessage(Throwable e)
{
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw, true));
String str = sw.toString();
return str;
}
public static String getRootErrorMseeage(Exception e)
{
Throwable root = ExceptionUtils.getRootCause(e);
root = (root == null ? e : root);
if (root == null)
{
return "";
}
String msg = root.getMessage();
if (msg == null)
{
return "null";
}
return StringUtils.defaultString(msg);
}
}
...@@ -40,7 +40,7 @@ public class YamlUtil ...@@ -40,7 +40,7 @@ public class YamlUtil
if (map != null && !map.isEmpty() && qualifiedKey != null) if (map != null && !map.isEmpty() && qualifiedKey != null)
{ {
String input = String.valueOf(qualifiedKey); String input = String.valueOf(qualifiedKey);
if (!input.equals("")) if (!"".equals(input))
{ {
if (input.contains(".")) if (input.contains("."))
{ {
......
...@@ -647,8 +647,10 @@ public class ExcelUtil<T> ...@@ -647,8 +647,10 @@ public class ExcelUtil<T>
{ {
tempClass = tempClass.getSuperclass(); tempClass = tempClass.getSuperclass();
if (tempClass != null) if (tempClass != null)
{
tempFields.addAll(Arrays.asList(tempClass.getDeclaredFields())); tempFields.addAll(Arrays.asList(tempClass.getDeclaredFields()));
} }
}
putToFields(tempFields); putToFields(tempFields);
} }
......
...@@ -2,6 +2,7 @@ package com.ruoyi.quartz.controller; ...@@ -2,6 +2,7 @@ package com.ruoyi.quartz.controller;
import java.util.List; import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
...@@ -15,6 +16,7 @@ import com.ruoyi.common.core.controller.BaseController; ...@@ -15,6 +16,7 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.job.TaskException;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.quartz.domain.SysJob; import com.ruoyi.quartz.domain.SysJob;
import com.ruoyi.quartz.service.ISysJobService; import com.ruoyi.quartz.service.ISysJobService;
...@@ -65,19 +67,11 @@ public class SysJobController extends BaseController ...@@ -65,19 +67,11 @@ public class SysJobController extends BaseController
@RequiresPermissions("monitor:job:remove") @RequiresPermissions("monitor:job:remove")
@PostMapping("/remove") @PostMapping("/remove")
@ResponseBody @ResponseBody
public AjaxResult remove(String ids) public AjaxResult remove(String ids) throws SchedulerException
{
try
{ {
jobService.deleteJobByIds(ids); jobService.deleteJobByIds(ids);
return success(); return success();
} }
catch (Exception e)
{
e.printStackTrace();
return error(e.getMessage());
}
}
@RequiresPermissions("monitor:job:detail") @RequiresPermissions("monitor:job:detail")
@GetMapping("/detail/{jobId}") @GetMapping("/detail/{jobId}")
...@@ -90,14 +84,12 @@ public class SysJobController extends BaseController ...@@ -90,14 +84,12 @@ public class SysJobController extends BaseController
/** /**
* 任务调度状态修改 * 任务调度状态修改
*
* @throws Exception
*/ */
@Log(title = "定时任务", businessType = BusinessType.UPDATE) @Log(title = "定时任务", businessType = BusinessType.UPDATE)
@RequiresPermissions("monitor:job:changeStatus") @RequiresPermissions("monitor:job:changeStatus")
@PostMapping("/changeStatus") @PostMapping("/changeStatus")
@ResponseBody @ResponseBody
public AjaxResult changeStatus(SysJob job) public AjaxResult changeStatus(SysJob job) throws SchedulerException
{ {
return toAjax(jobService.changeStatus(job)); return toAjax(jobService.changeStatus(job));
} }
...@@ -109,9 +101,10 @@ public class SysJobController extends BaseController ...@@ -109,9 +101,10 @@ public class SysJobController extends BaseController
@RequiresPermissions("monitor:job:changeStatus") @RequiresPermissions("monitor:job:changeStatus")
@PostMapping("/run") @PostMapping("/run")
@ResponseBody @ResponseBody
public AjaxResult run(SysJob job) public AjaxResult run(SysJob job) throws SchedulerException
{ {
return toAjax(jobService.run(job)); jobService.run(job);
return success();
} }
/** /**
...@@ -125,7 +118,6 @@ public class SysJobController extends BaseController ...@@ -125,7 +118,6 @@ public class SysJobController extends BaseController
/** /**
* 新增保存调度 * 新增保存调度
* @throws Exception
*/ */
@Log(title = "定时任务", businessType = BusinessType.INSERT) @Log(title = "定时任务", businessType = BusinessType.INSERT)
@RequiresPermissions("monitor:job:add") @RequiresPermissions("monitor:job:add")
...@@ -148,13 +140,12 @@ public class SysJobController extends BaseController ...@@ -148,13 +140,12 @@ public class SysJobController extends BaseController
/** /**
* 修改保存调度 * 修改保存调度
* @throws Exception
*/ */
@Log(title = "定时任务", businessType = BusinessType.UPDATE) @Log(title = "定时任务", businessType = BusinessType.UPDATE)
@RequiresPermissions("monitor:job:edit") @RequiresPermissions("monitor:job:edit")
@PostMapping("/edit") @PostMapping("/edit")
@ResponseBody @ResponseBody
public AjaxResult editSave(SysJob job ) throws Exception public AjaxResult editSave(SysJob job) throws SchedulerException, TaskException
{ {
return toAjax(jobService.updateJobCron(job)); return toAjax(jobService.updateJobCron(job));
} }
......
...@@ -47,6 +47,9 @@ public class SysJob extends BaseEntity implements Serializable ...@@ -47,6 +47,9 @@ public class SysJob extends BaseEntity implements Serializable
@Excel(name = "计划策略 ") @Excel(name = "计划策略 ")
private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT; private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT;
/** 是否并发执行(0允许 1禁止) */
private String concurrent;
/** 任务状态(0正常 1暂停) */ /** 任务状态(0正常 1暂停) */
@Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停") @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停")
private String status; private String status;
...@@ -130,6 +133,16 @@ public class SysJob extends BaseEntity implements Serializable ...@@ -130,6 +133,16 @@ public class SysJob extends BaseEntity implements Serializable
this.misfirePolicy = misfirePolicy; this.misfirePolicy = misfirePolicy;
} }
public String getConcurrent()
{
return concurrent;
}
public void setConcurrent(String concurrent)
{
this.concurrent = concurrent;
}
public String getStatus() public String getStatus()
{ {
return status; return status;
...@@ -151,6 +164,7 @@ public class SysJob extends BaseEntity implements Serializable ...@@ -151,6 +164,7 @@ public class SysJob extends BaseEntity implements Serializable
.append("cronExpression", getCronExpression()) .append("cronExpression", getCronExpression())
.append("nextValidTime", getNextValidTime()) .append("nextValidTime", getNextValidTime())
.append("misfirePolicy", getMisfirePolicy()) .append("misfirePolicy", getMisfirePolicy())
.append("concurrent", getConcurrent())
.append("status", getStatus()) .append("status", getStatus())
.append("createBy", getCreateBy()) .append("createBy", getCreateBy())
.append("createTime", getCreateTime()) .append("createTime", getCreateTime())
......
package com.ruoyi.quartz.domain; package com.ruoyi.quartz.domain;
import java.util.Date;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.BaseEntity;
...@@ -46,6 +48,14 @@ public class SysJobLog extends BaseEntity ...@@ -46,6 +48,14 @@ public class SysJobLog extends BaseEntity
@Excel(name = "异常信息") @Excel(name = "异常信息")
private String exceptionInfo; private String exceptionInfo;
/** 开始时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date startTime;
/** 结束时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
public Long getJobLogId() public Long getJobLogId()
{ {
return jobLogId; return jobLogId;
...@@ -126,6 +136,26 @@ public class SysJobLog extends BaseEntity ...@@ -126,6 +136,26 @@ public class SysJobLog extends BaseEntity
this.exceptionInfo = exceptionInfo; this.exceptionInfo = exceptionInfo;
} }
public Date getStartTime()
{
return startTime;
}
public void setStartTime(Date startTime)
{
this.startTime = startTime;
}
public Date getEndTime()
{
return endTime;
}
public void setEndTime(Date endTime)
{
this.endTime = endTime;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
...@@ -137,7 +167,8 @@ public class SysJobLog extends BaseEntity ...@@ -137,7 +167,8 @@ public class SysJobLog extends BaseEntity
.append("jobMessage", getJobMessage()) .append("jobMessage", getJobMessage())
.append("status", getStatus()) .append("status", getStatus())
.append("exceptionInfo", getExceptionInfo()) .append("exceptionInfo", getExceptionInfo())
.append("createTime", getCreateTime()) .append("startTime", getStartTime())
.append("endTime", getEndTime())
.toString(); .toString();
} }
} }
package com.ruoyi.quartz.service; package com.ruoyi.quartz.service;
import java.util.List; import java.util.List;
import org.quartz.SchedulerException;
import com.ruoyi.common.exception.job.TaskException;
import com.ruoyi.quartz.domain.SysJob; import com.ruoyi.quartz.domain.SysJob;
/** /**
...@@ -32,7 +34,7 @@ public interface ISysJobService ...@@ -32,7 +34,7 @@ public interface ISysJobService
* @param job 调度信息 * @param job 调度信息
* @return 结果 * @return 结果
*/ */
public int pauseJob(SysJob job); public int pauseJob(SysJob job) throws SchedulerException;
/** /**
* 恢复任务 * 恢复任务
...@@ -40,7 +42,7 @@ public interface ISysJobService ...@@ -40,7 +42,7 @@ public interface ISysJobService
* @param job 调度信息 * @param job 调度信息
* @return 结果 * @return 结果
*/ */
public int resumeJob(SysJob job); public int resumeJob(SysJob job) throws SchedulerException;
/** /**
* 删除任务后,所对应的trigger也将被删除 * 删除任务后,所对应的trigger也将被删除
...@@ -48,7 +50,7 @@ public interface ISysJobService ...@@ -48,7 +50,7 @@ public interface ISysJobService
* @param job 调度信息 * @param job 调度信息
* @return 结果 * @return 结果
*/ */
public int deleteJob(SysJob job); public int deleteJob(SysJob job) throws SchedulerException;
/** /**
* 批量删除调度信息 * 批量删除调度信息
...@@ -56,7 +58,7 @@ public interface ISysJobService ...@@ -56,7 +58,7 @@ public interface ISysJobService
* @param ids 需要删除的数据ID * @param ids 需要删除的数据ID
* @return 结果 * @return 结果
*/ */
public void deleteJobByIds(String ids); public void deleteJobByIds(String ids) throws SchedulerException;
/** /**
* 任务调度状态修改 * 任务调度状态修改
...@@ -64,7 +66,7 @@ public interface ISysJobService ...@@ -64,7 +66,7 @@ public interface ISysJobService
* @param job 调度信息 * @param job 调度信息
* @return 结果 * @return 结果
*/ */
public int changeStatus(SysJob job); public int changeStatus(SysJob job) throws SchedulerException;
/** /**
* 立即运行任务 * 立即运行任务
...@@ -72,7 +74,7 @@ public interface ISysJobService ...@@ -72,7 +74,7 @@ public interface ISysJobService
* @param job 调度信息 * @param job 调度信息
* @return 结果 * @return 结果
*/ */
public int run(SysJob job); public void run(SysJob job) throws SchedulerException;
/** /**
* 新增任务表达式 * 新增任务表达式
...@@ -80,7 +82,7 @@ public interface ISysJobService ...@@ -80,7 +82,7 @@ public interface ISysJobService
* @param job 调度信息 * @param job 调度信息
* @return 结果 * @return 结果
*/ */
public int insertJobCron(SysJob job); public int insertJobCron(SysJob job) throws SchedulerException, TaskException;
/** /**
* 更新任务的时间表达式 * 更新任务的时间表达式
...@@ -88,7 +90,7 @@ public interface ISysJobService ...@@ -88,7 +90,7 @@ public interface ISysJobService
* @param job 调度信息 * @param job 调度信息
* @return 结果 * @return 结果
*/ */
public int updateJobCron(SysJob job); public int updateJobCron(SysJob job) throws SchedulerException, TaskException;
/** /**
* 校验cron表达式是否有效 * 校验cron表达式是否有效
......
...@@ -4,11 +4,13 @@ import java.util.List; ...@@ -4,11 +4,13 @@ import java.util.List;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import org.quartz.CronTrigger; import org.quartz.CronTrigger;
import org.quartz.Scheduler; import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.constant.ScheduleConstants; import com.ruoyi.common.constant.ScheduleConstants;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.job.TaskException;
import com.ruoyi.quartz.domain.SysJob; import com.ruoyi.quartz.domain.SysJob;
import com.ruoyi.quartz.mapper.SysJobMapper; import com.ruoyi.quartz.mapper.SysJobMapper;
import com.ruoyi.quartz.service.ISysJobService; import com.ruoyi.quartz.service.ISysJobService;
...@@ -33,7 +35,7 @@ public class SysJobServiceImpl implements ISysJobService ...@@ -33,7 +35,7 @@ public class SysJobServiceImpl implements ISysJobService
* 项目启动时,初始化定时器 * 项目启动时,初始化定时器
*/ */
@PostConstruct @PostConstruct
public void init() public void init() throws SchedulerException, TaskException
{ {
List<SysJob> jobList = jobMapper.selectJobAll(); List<SysJob> jobList = jobMapper.selectJobAll();
for (SysJob job : jobList) for (SysJob job : jobList)
...@@ -82,7 +84,7 @@ public class SysJobServiceImpl implements ISysJobService ...@@ -82,7 +84,7 @@ public class SysJobServiceImpl implements ISysJobService
*/ */
@Override @Override
@Transactional @Transactional
public int pauseJob(SysJob job) public int pauseJob(SysJob job) throws SchedulerException
{ {
job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
int rows = jobMapper.updateJob(job); int rows = jobMapper.updateJob(job);
...@@ -100,7 +102,7 @@ public class SysJobServiceImpl implements ISysJobService ...@@ -100,7 +102,7 @@ public class SysJobServiceImpl implements ISysJobService
*/ */
@Override @Override
@Transactional @Transactional
public int resumeJob(SysJob job) public int resumeJob(SysJob job) throws SchedulerException
{ {
job.setStatus(ScheduleConstants.Status.NORMAL.getValue()); job.setStatus(ScheduleConstants.Status.NORMAL.getValue());
int rows = jobMapper.updateJob(job); int rows = jobMapper.updateJob(job);
...@@ -118,7 +120,7 @@ public class SysJobServiceImpl implements ISysJobService ...@@ -118,7 +120,7 @@ public class SysJobServiceImpl implements ISysJobService
*/ */
@Override @Override
@Transactional @Transactional
public int deleteJob(SysJob job) public int deleteJob(SysJob job) throws SchedulerException
{ {
int rows = jobMapper.deleteJobById(job.getJobId()); int rows = jobMapper.deleteJobById(job.getJobId());
if (rows > 0) if (rows > 0)
...@@ -136,7 +138,7 @@ public class SysJobServiceImpl implements ISysJobService ...@@ -136,7 +138,7 @@ public class SysJobServiceImpl implements ISysJobService
*/ */
@Override @Override
@Transactional @Transactional
public void deleteJobByIds(String ids) public void deleteJobByIds(String ids) throws SchedulerException
{ {
Long[] jobIds = Convert.toLongArray(ids); Long[] jobIds = Convert.toLongArray(ids);
for (Long jobId : jobIds) for (Long jobId : jobIds)
...@@ -153,7 +155,7 @@ public class SysJobServiceImpl implements ISysJobService ...@@ -153,7 +155,7 @@ public class SysJobServiceImpl implements ISysJobService
*/ */
@Override @Override
@Transactional @Transactional
public int changeStatus(SysJob job) public int changeStatus(SysJob job) throws SchedulerException
{ {
int rows = 0; int rows = 0;
String status = job.getStatus(); String status = job.getStatus();
...@@ -175,9 +177,9 @@ public class SysJobServiceImpl implements ISysJobService ...@@ -175,9 +177,9 @@ public class SysJobServiceImpl implements ISysJobService
*/ */
@Override @Override
@Transactional @Transactional
public int run(SysJob job) public void run(SysJob job) throws SchedulerException
{ {
return ScheduleUtils.run(scheduler, selectJobById(job.getJobId())); ScheduleUtils.run(scheduler, selectJobById(job.getJobId()));
} }
/** /**
...@@ -187,7 +189,7 @@ public class SysJobServiceImpl implements ISysJobService ...@@ -187,7 +189,7 @@ public class SysJobServiceImpl implements ISysJobService
*/ */
@Override @Override
@Transactional @Transactional
public int insertJobCron(SysJob job) public int insertJobCron(SysJob job) throws SchedulerException, TaskException
{ {
job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
int rows = jobMapper.insertJob(job); int rows = jobMapper.insertJob(job);
...@@ -205,7 +207,7 @@ public class SysJobServiceImpl implements ISysJobService ...@@ -205,7 +207,7 @@ public class SysJobServiceImpl implements ISysJobService
*/ */
@Override @Override
@Transactional @Transactional
public int updateJobCron(SysJob job) public int updateJobCron(SysJob job) throws SchedulerException, TaskException
{ {
int rows = jobMapper.updateJob(job); int rows = jobMapper.updateJob(job);
if (rows > 0) if (rows > 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<Date> 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 sysScheduleJob 系统计划任务
*/
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.setMethodName(sysJob.getMethodName());
sysJobLog.setMethodParams(sysJob.getMethodParams());
sysJobLog.setStartTime(startTime);
sysJobLog.setEndTime(new Date());
long runMs = sysJobLog.getEndTime().getTime() - sysJobLog.getStartTime().getTime();
sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒");
if (e != null)
{
sysJobLog.setStatus(Constants.FAIL);
String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000);
sysJobLog.setExceptionInfo(errorMsg);
}
else
{
sysJobLog.setStatus(Constants.SUCCESS);
}
// 写入数据库当中
SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog);
}
/**
* 执行方法,由子类重载
*
* @param context 工作执行上下文对象
* @param sysJob 系统计划任务
* @throws Exception 执行过程中的异常
*/
protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception;
}
package com.ruoyi.quartz.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
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
{
Object bean = SpringUtils.getBean(sysJob.getJobName());
String methodName = sysJob.getMethodName();
String methodParams = sysJob.getMethodParams();
invokeSpringBean(bean, methodName, methodParams);
}
/**
* 调用任务方法
*
* @param bean 目标对象
* @param methodName 方法名称
* @param methodParams 方法参数
* @throws InvocationTargetException
* @throws SecurityException
* @throws NoSuchMethodException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
private static void invokeSpringBean(Object bean, String methodName, String methodParams)
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
if (StringUtils.isNotEmpty(methodParams))
{
Method method = bean.getClass().getDeclaredMethod(methodName, String.class);
method.invoke(bean, methodParams);
}
else
{
Method method = bean.getClass().getDeclaredMethod(methodName);
method.invoke(bean);
}
}
}
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);
}
}
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);
}
}
package com.ruoyi.quartz.util;
import java.util.Date;
import java.util.concurrent.Future;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.quartz.QuartzJobBean;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.ScheduleConstants;
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;
/**
* 定时任务处理
*
* @author ruoyi
*
*/
@DisallowConcurrentExecution
public class ScheduleJob extends QuartzJobBean
{
private static final Logger log = LoggerFactory.getLogger(ScheduleJob.class);
private ThreadPoolTaskExecutor executor = SpringUtils.getBean("threadPoolTaskExecutor");
private final static ISysJobLogService jobLogService = SpringUtils.getBean(ISysJobLogService.class);
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException
{
SysJob job = new SysJob();
BeanUtils.copyBeanProp(job, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES));
SysJobLog jobLog = new SysJobLog();
jobLog.setJobName(job.getJobName());
jobLog.setJobGroup(job.getJobGroup());
jobLog.setMethodName(job.getMethodName());
jobLog.setMethodParams(job.getMethodParams());
jobLog.setCreateTime(new Date());
long startTime = System.currentTimeMillis();
try
{
// 执行任务
log.info("任务开始执行 - 名称:{} 方法:{}", job.getJobName(), job.getMethodName());
ScheduleRunnable task = new ScheduleRunnable(job.getJobName(), job.getMethodName(), job.getMethodParams());
Future<?> future = executor.submit(task);
future.get();
long times = System.currentTimeMillis() - startTime;
// 任务状态 0:成功 1:失败
jobLog.setStatus(Constants.SUCCESS);
jobLog.setJobMessage(job.getJobName() + " 总共耗时:" + times + "毫秒");
log.info("任务执行结束 - 名称:{} 耗时:{} 毫秒", job.getJobName(), times);
}
catch (Exception e)
{
log.info("任务执行失败 - 名称:{} 方法:{}", job.getJobName(), job.getMethodName());
log.error("任务执行异常 - :", e);
long times = System.currentTimeMillis() - startTime;
jobLog.setJobMessage(job.getJobName() + " 总共耗时:" + times + "毫秒");
// 任务状态 0:成功 1:失败
jobLog.setStatus(Constants.FAIL);
jobLog.setExceptionInfo(StringUtils.substring(e.getMessage(), 0, 2000));
}
finally
{
jobLogService.addJobLog(jobLog);
}
}
}
package com.ruoyi.quartz.util;
import java.lang.reflect.Method;
import org.springframework.util.ReflectionUtils;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
/**
* 执行定时任务
*
* @author ruoyi
*
*/
public class ScheduleRunnable implements Runnable
{
private Object target;
private Method method;
private String params;
public ScheduleRunnable(String beanName, String methodName, String params)
throws NoSuchMethodException, SecurityException
{
this.target = SpringUtils.getBean(beanName);
this.params = params;
if (StringUtils.isNotEmpty(params))
{
this.method = target.getClass().getDeclaredMethod(methodName, String.class);
}
else
{
this.method = target.getClass().getDeclaredMethod(methodName);
}
}
@Override
public void run()
{
try
{
ReflectionUtils.makeAccessible(method);
if (StringUtils.isNotEmpty(params))
{
method.invoke(target, params);
}
else
{
method.invoke(target);
}
}
catch (Exception e)
{
throw new BusinessException("执行定时任务失败", e);
}
}
}
...@@ -2,6 +2,7 @@ package com.ruoyi.quartz.util; ...@@ -2,6 +2,7 @@ package com.ruoyi.quartz.util;
import org.quartz.CronScheduleBuilder; import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger; import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder; import org.quartz.JobBuilder;
import org.quartz.JobDataMap; import org.quartz.JobDataMap;
import org.quartz.JobDetail; import org.quartz.JobDetail;
...@@ -28,6 +29,18 @@ public class ScheduleUtils ...@@ -28,6 +29,18 @@ public class ScheduleUtils
private static final Logger log = LoggerFactory.getLogger(ScheduleUtils.class); private static final Logger log = LoggerFactory.getLogger(ScheduleUtils.class);
/** /**
* 得到quartz任务类
*
* @param sysJob 执行计划
* @return 具体执行任务类
*/
private static Class<? extends Job> getQuartzJobClass(SysJob sysJob)
{
boolean isConcurrent = "0".equals(sysJob.getConcurrent());
return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class;
}
/**
* 获取触发器key * 获取触发器key
*/ */
public static TriggerKey getTriggerKey(Long jobId) public static TriggerKey getTriggerKey(Long jobId)
...@@ -62,12 +75,11 @@ public class ScheduleUtils ...@@ -62,12 +75,11 @@ public class ScheduleUtils
/** /**
* 创建定时任务 * 创建定时任务
*/ */
public static void createScheduleJob(Scheduler scheduler, SysJob job) public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException
{
try
{ {
Class<? extends Job> jobClass = getQuartzJobClass(job);
// 构建job信息 // 构建job信息
JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(job.getJobId())).build(); JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(job.getJobId())).build();
// 表达式调度构建器 // 表达式调度构建器
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
...@@ -88,122 +100,65 @@ public class ScheduleUtils ...@@ -88,122 +100,65 @@ public class ScheduleUtils
pauseJob(scheduler, job.getJobId()); pauseJob(scheduler, job.getJobId());
} }
} }
catch (SchedulerException e)
{
log.error("createScheduleJob 异常:", e);
}
catch (TaskException e)
{
log.error("createScheduleJob 异常:", e);
}
}
/** /**
* 更新定时任务 * 更新定时任务
*/ */
public static void updateScheduleJob(Scheduler scheduler, SysJob job) public static void updateScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException
{ {
try JobKey jobKey = getJobKey(job.getJobId());
{
TriggerKey triggerKey = getTriggerKey(job.getJobId());
// 表达式调度构建器
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder);
CronTrigger trigger = getCronTrigger(scheduler, job.getJobId());
// 按新的cronExpression表达式重新构建trigger // 判断是否存在
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build(); if (scheduler.checkExists(jobKey))
{
// 参数 // 先移除,然后做更新操作
trigger.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); scheduler.deleteJob(jobKey);
}
scheduler.rescheduleJob(triggerKey, trigger); createScheduleJob(scheduler, job);
// 暂停任务 // 暂停任务
if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue()))
{ {
pauseJob(scheduler, job.getJobId()); pauseJob(scheduler, job.getJobId());
} }
}
catch (SchedulerException e)
{
log.error("SchedulerException 异常:", e);
}
catch (TaskException e)
{
log.error("SchedulerException 异常:", e);
}
} }
/** /**
* 立即执行任务 * 立即执行任务
*/ */
public static int run(Scheduler scheduler, SysJob job) public static void run(Scheduler scheduler, SysJob job) throws SchedulerException
{
int rows = 0;
try
{ {
// 参数 // 参数
JobDataMap dataMap = new JobDataMap(); JobDataMap dataMap = new JobDataMap();
dataMap.put(ScheduleConstants.TASK_PROPERTIES, job); dataMap.put(ScheduleConstants.TASK_PROPERTIES, job);
scheduler.triggerJob(getJobKey(job.getJobId()), dataMap); scheduler.triggerJob(getJobKey(job.getJobId()), dataMap);
rows = 1;
}
catch (SchedulerException e)
{
log.error("run 异常:", e);
}
return rows;
} }
/** /**
* 暂停任务 * 暂停任务
*/ */
public static void pauseJob(Scheduler scheduler, Long jobId) public static void pauseJob(Scheduler scheduler, Long jobId) throws SchedulerException
{
try
{ {
scheduler.pauseJob(getJobKey(jobId)); scheduler.pauseJob(getJobKey(jobId));
} }
catch (SchedulerException e)
{
log.error("pauseJob 异常:", e);
}
}
/** /**
* 恢复任务 * 恢复任务
*/ */
public static void resumeJob(Scheduler scheduler, Long jobId) public static void resumeJob(Scheduler scheduler, Long jobId) throws SchedulerException
{
try
{ {
scheduler.resumeJob(getJobKey(jobId)); scheduler.resumeJob(getJobKey(jobId));
} }
catch (SchedulerException e)
{
log.error("resumeJob 异常:", e);
}
}
/** /**
* 删除定时任务 * 删除定时任务
*/ */
public static void deleteScheduleJob(Scheduler scheduler, Long jobId) public static void deleteScheduleJob(Scheduler scheduler, Long jobId) throws SchedulerException
{
try
{ {
scheduler.deleteJob(getJobKey(jobId)); scheduler.deleteJob(getJobKey(jobId));
} }
catch (SchedulerException e)
{
log.error("deleteScheduleJob 异常:", e);
}
}
public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb)
throws TaskException throws TaskException
...@@ -219,7 +174,8 @@ public class ScheduleUtils ...@@ -219,7 +174,8 @@ public class ScheduleUtils
case ScheduleConstants.MISFIRE_DO_NOTHING: case ScheduleConstants.MISFIRE_DO_NOTHING:
return cb.withMisfireHandlingInstructionDoNothing(); return cb.withMisfireHandlingInstructionDoNothing();
default: default:
throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); throw new TaskException("The task misfire policy '" + job.getMisfirePolicy()
+ "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR);
} }
} }
} }
...@@ -12,6 +12,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ...@@ -12,6 +12,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="methodParams" column="method_params" /> <result property="methodParams" column="method_params" />
<result property="cronExpression" column="cron_expression" /> <result property="cronExpression" column="cron_expression" />
<result property="misfirePolicy" column="misfire_policy" /> <result property="misfirePolicy" column="misfire_policy" />
<result property="concurrent" column="concurrent" />
<result property="status" column="status" /> <result property="status" column="status" />
<result property="createBy" column="create_by" /> <result property="createBy" column="create_by" />
<result property="createTime" column="create_time" /> <result property="createTime" column="create_time" />
...@@ -21,7 +22,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ...@@ -21,7 +22,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap> </resultMap>
<sql id="selectJobVo"> <sql id="selectJobVo">
select job_id, job_name, job_group, method_name, method_params, cron_expression, misfire_policy, status, create_by, create_time, remark select job_id, job_name, job_group, method_name, method_params, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark
from sys_job from sys_job
</sql> </sql>
...@@ -69,6 +70,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ...@@ -69,6 +70,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="methodParams != null">method_params = #{methodParams},</if> <if test="methodParams != null">method_params = #{methodParams},</if>
<if test="cronExpression != null and cronExpression != ''">cron_expression = #{cronExpression},</if> <if test="cronExpression != null and cronExpression != ''">cron_expression = #{cronExpression},</if>
<if test="misfirePolicy != null and misfirePolicy != ''">misfire_policy = #{misfirePolicy},</if> <if test="misfirePolicy != null and misfirePolicy != ''">misfire_policy = #{misfirePolicy},</if>
<if test="concurrent != null and concurrent != ''">concurrent = #{concurrent},</if>
<if test="status !=null">status = #{status},</if> <if test="status !=null">status = #{status},</if>
<if test="remark != null and remark != ''">remark = #{remark},</if> <if test="remark != null and remark != ''">remark = #{remark},</if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
...@@ -86,6 +88,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ...@@ -86,6 +88,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="methodParams != null and methodParams != ''">method_params,</if> <if test="methodParams != null and methodParams != ''">method_params,</if>
<if test="cronExpression != null and cronExpression != ''">cron_expression,</if> <if test="cronExpression != null and cronExpression != ''">cron_expression,</if>
<if test="misfirePolicy != null and misfirePolicy != ''">misfire_policy,</if> <if test="misfirePolicy != null and misfirePolicy != ''">misfire_policy,</if>
<if test="concurrent != null and concurrent != ''">concurrent,</if>
<if test="status != null and status != ''">status,</if> <if test="status != null and status != ''">status,</if>
<if test="remark != null and remark != ''">remark,</if> <if test="remark != null and remark != ''">remark,</if>
<if test="createBy != null and createBy != ''">create_by,</if> <if test="createBy != null and createBy != ''">create_by,</if>
...@@ -98,6 +101,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ...@@ -98,6 +101,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="methodParams != null and methodParams != ''">#{methodParams},</if> <if test="methodParams != null and methodParams != ''">#{methodParams},</if>
<if test="cronExpression != null and cronExpression != ''">#{cronExpression},</if> <if test="cronExpression != null and cronExpression != ''">#{cronExpression},</if>
<if test="misfirePolicy != null and misfirePolicy != ''">#{misfirePolicy},</if> <if test="misfirePolicy != null and misfirePolicy != ''">#{misfirePolicy},</if>
<if test="concurrent != null and concurrent != ''">#{concurrent},</if>
<if test="status != null and status != ''">#{status},</if> <if test="status != null and status != ''">#{status},</if>
<if test="remark != null and remark != ''">#{remark},</if> <if test="remark != null and remark != ''">#{remark},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if> <if test="createBy != null and createBy != ''">#{createBy},</if>
......
...@@ -44,6 +44,13 @@ ...@@ -44,6 +44,13 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">并发执行:</label>
<div class="col-sm-8">
<label class="radio-box"> <input type="radio" name="concurrent" value="0"/> 允许 </label>
<label class="radio-box"> <input type="radio" name="concurrent" value="1" th:checked="true"/> 禁止 </label>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">状态:</label> <label class="col-sm-3 control-label">状态:</label>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_job_status')}"> <div class="radio-box" th:each="dict : ${@dict.getType('sys_job_status')}">
......
...@@ -83,6 +83,11 @@ ...@@ -83,6 +83,11 @@
<div class="form-control-static" th:if="${job.misfirePolicy == '3'}">放弃执行</div> <div class="form-control-static" th:if="${job.misfirePolicy == '3'}">放弃执行</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">并发执行:</label>
<div class="form-control-static" th:class="${job.concurrent == '0' ? 'label label-primary' : 'label label-danger'}" th:text="${job.concurrent == '0' ? '允许' : '禁止'}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">执行状态:</label> <label class="col-sm-3 control-label">执行状态:</label>
<div class="form-control-static" th:class="${job.status == '0' ? 'label label-primary' : 'label label-danger'}" th:text="${job.status == '0' ? '正常' : '暂停'}"> <div class="form-control-static" th:class="${job.status == '0' ? 'label label-primary' : 'label label-danger'}" th:text="${job.status == '0' ? '正常' : '暂停'}">
</div> </div>
......
...@@ -45,6 +45,13 @@ ...@@ -45,6 +45,13 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">并发执行:</label>
<div class="col-sm-8">
<label class="radio-box"> <input type="radio" th:field="*{concurrent}" name="concurrent" value="0"/> 允许 </label>
<label class="radio-box"> <input type="radio" th:field="*{concurrent}" name="concurrent" value="1"/> 禁止 </label>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">状态:</label> <label class="col-sm-3 control-label">状态:</label>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_job_status')}"> <div class="radio-box" th:each="dict : ${@dict.getType('sys_job_status')}">
......
...@@ -122,7 +122,7 @@ ...@@ -122,7 +122,7 @@
align: 'center', align: 'center',
formatter: function(value, row, index) { formatter: function(value, row, index) {
var actions = []; var actions = [];
actions.push('<a class="btn btn-primary btn-xs ' + statusFlag + '" href="#" onclick="run(\'' + row.jobId + '\')"><i class="fa fa-play-circle-o"></i> 执行</a> '); actions.push('<a class="btn btn-primary btn-xs ' + statusFlag + '" href="#" onclick="run(\'' + row.jobId + '\')"><i class="fa fa-play-circle-o"></i> 执行一次</a> ');
actions.push('<a class="btn btn-warning btn-xs ' + detailFlag + '" href="#" onclick="$.operate.detail(\'' + row.jobId + '\')"><i class="fa fa-search"></i>详细</a> '); actions.push('<a class="btn btn-warning btn-xs ' + detailFlag + '" href="#" onclick="$.operate.detail(\'' + row.jobId + '\')"><i class="fa fa-search"></i>详细</a> ');
return actions.join(''); return actions.join('');
} }
...@@ -142,7 +142,7 @@ ...@@ -142,7 +142,7 @@
/* 立即执行一次 */ /* 立即执行一次 */
function run(jobId) { function run(jobId) {
$.modal.confirm("确认要立即执行任务吗?", function() { $.modal.confirm("确认要立即执行一次任务吗?", function() {
$.operate.post(prefix + "/run", { "jobId": jobId}); $.operate.post(prefix + "/run", { "jobId": jobId});
}) })
} }
......
...@@ -568,6 +568,7 @@ create table sys_job ( ...@@ -568,6 +568,7 @@ create table sys_job (
method_params varchar(50) default null comment '方法参数', method_params varchar(50) default null comment '方法参数',
cron_expression varchar(255) default '' comment 'cron执行表达式', cron_expression varchar(255) default '' comment 'cron执行表达式',
misfire_policy varchar(20) default '3' comment '计划执行错误策略(1立即执行 2执行一次 3放弃执行)', misfire_policy varchar(20) default '3' comment '计划执行错误策略(1立即执行 2执行一次 3放弃执行)',
concurrent char default '1' comment '是否并发执行(0允许 1禁止)',
status char(1) default '0' comment '状态(0正常 1暂停)', status char(1) default '0' comment '状态(0正常 1暂停)',
create_by varchar(64) default '' comment '创建者', create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间', create_time datetime comment '创建时间',
...@@ -577,8 +578,8 @@ create table sys_job ( ...@@ -577,8 +578,8 @@ create table sys_job (
primary key (job_id, job_name, job_group) primary key (job_id, job_name, job_group)
) engine=innodb auto_increment=100 default charset=utf8 comment = '定时任务调度表'; ) engine=innodb auto_increment=100 default charset=utf8 comment = '定时任务调度表';
insert into sys_job values(1, 'ryTask', '系统默认(无参)', 'ryNoParams', '', '0/10 * * * * ?', '3', '1', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); insert into sys_job values(1, 'ryTask', '系统默认(无参)', 'ryNoParams', '', '0/10 * * * * ?', '3', '1', '1', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
insert into sys_job values(2, 'ryTask', '系统默认(有参)', 'ryParams', 'ry', '0/20 * * * * ?', '3', '1', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); insert into sys_job values(2, 'ryTask', '系统默认(有参)', 'ryParams', 'ry', '0/20 * * * * ?', '3', '1', '1', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-- ---------------------------- -- ----------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment