jeesite4作业监控调度模块属于个人版的内容,免费版是不能用的。所以自己写一个这种类似的定时任务调度模块来代替他。
这个定时任务模块大部分是参考的jeecg的开源部分代码,Quartz定时任务部分。
先看一下管理界面:
用法应该和jeesite自带的作业监控调度模块类似,列表界面可以随时修改cron表达式和进行停启操作。
没有集群等功能,后期学习了再补上吧…
设定好后台就开始执行了
这里有我集成好的包,复制到项目应该就可以用了
大概?ヽ(ー_ー)ノ
度盘:
链接:https://pan.baidu.com/s/1nD7aC90Zomn5wv3DJHinSg
提取码:gv26
复制这段内容后打开百度网盘手机App,操作更方便哦
下面就开始讲解表格式和代码部分了
定时任务调度表
表结构基本和geecg相同
建表sql:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for quartz_job
-- ----------------------------
DROP TABLE IF EXISTS `quartz_job`;
CREATE TABLE `quartz_job` (
`ID` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '主键',
`CREATE_BY` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人',
`CREATE_TIME` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`DEL_FLAG` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '删除状态',
`UPDATE_BY` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '修改人',
`UPDATE_TIME` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
`JOB_CLASS_NAME` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任务类名',
`CRON_EXPRESSION` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'cron表达式',
`PARAMETER` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '参数',
`DESCRIPTION` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述',
`STATUS` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '状态',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 'quartz定时任务表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of quartz_job
-- ----------------------------
INSERT INTO `quartz_job` VALUES ('1234446564624400384', 'system', '2020-03-02 19:52:50', NULL, 'system', '2020-03-03 09:45:08', 'com.jeesite.modules.autoRun.SampleParamJob', '0/10 * * * * ?', '内存辣鸡太多啦..', '定时回收内存垃圾(范例)', '0');
SET FOREIGN_KEY_CHECKS = 1;
任务类名和cron表达式都储存在表里的,状态STATUS和jeesite4定义的一致,0启动,2停用。1好像是删除
后台代码部分
其实有了表结构,大家都可以靠jeesite4一键生成增删改查代码了(我也是)。主要是在增删改查的流程里插入对Quartz定时任务的调度
首先是Controller层
主要是新增一个切换定时任务的方法,方便前台按钮启动/暂停定时任务
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.quartz.web;
import com.jeesite.common.config.Global;
import com.jeesite.common.entity.Page;
import com.jeesite.common.web.BaseController;
import com.jeesite.modules.quartz.entity.QuartzJob;
import com.jeesite.modules.quartz.service.QuartzJobService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
* Quartz定时任务表Controller
* @author 淡梦如烟
* @version 2020-03-02
*/
@Controller
@RequestMapping(value = "${adminPath}/quartz/quartzJob")
public class QuartzJobController extends BaseController {
@Autowired
private QuartzJobService quartzJobService;
/**
* 获取数据
*/
@ModelAttribute
public QuartzJob get(String id, boolean isNewRecord) {
return quartzJobService.get(id, isNewRecord);
}
/**
* 查询列表
*/
@RequiresPermissions("quartz:quartzJob:view")
@RequestMapping(value = {"list", ""})
public String list(QuartzJob quartzJob, Model model) {
model.addAttribute("quartzJob", quartzJob);
return "modules/quartz/quartzJobList";
}
/**
* 查询列表数据
*/
@RequiresPermissions("quartz:quartzJob:view")
@RequestMapping(value = "listData")
@ResponseBody
public Page<QuartzJob> listData(QuartzJob quartzJob, HttpServletRequest request, HttpServletResponse response) {
quartzJob.setPage(new Page<>(request, response));
Page<QuartzJob> page = quartzJobService.findPage(quartzJob);
return page;
}
/**
* 查看编辑表单
*/
@RequiresPermissions("quartz:quartzJob:view")
@RequestMapping(value = "form")
public String form(QuartzJob quartzJob, Model model) {
model.addAttribute("quartzJob", quartzJob);
return "modules/quartz/quartzJobForm";
}
/**
* 保存quartz定时任务表
*/
@RequiresPermissions("quartz:quartzJob:edit")
@PostMapping(value = "save")
@ResponseBody
public String save(@Validated QuartzJob quartzJob) {
quartzJobService.save(quartzJob);
return renderResult(Global.TRUE, text("保存quartz定时任务表成功!"));
}
/**
* 删除quartz定时任务表
*/
@RequiresPermissions("quartz:quartzJob:edit")
@RequestMapping(value = "delete")
@ResponseBody
public String delete(QuartzJob quartzJob) {
quartzJobService.delete(quartzJob);
return renderResult(Global.TRUE, text("删除quartz定时任务表成功!"));
}
/**
* 显示cron表达式界面
* @param id 待写入的input组件的id
* @param model 模型
* @return 视图
*/
@RequiresPermissions("quartz:quartzJob:view")
@RequestMapping(value = "showCron")
public String showCron(String id, Model model) {
model.addAttribute("id", id);
return "modules/quartz/cron-quartz/index";
}
/**
* 切换定时任务
* @param quartzJob
* @return
*/
@RequiresPermissions("quartz:quartzJob:edit")
@RequestMapping(value = "switch")
public Map switchQuartz(QuartzJob quartzJob, Model model) {
Map result = new HashMap();
result.put("code","error");
result.put("msg","未知错误!");
try {
quartzJobService.switchQuartz(quartzJob);
} catch (Exception e) {
e.printStackTrace();
result.put("msg","切换定时任务失败!" + e.getMessage());
return result;
}
result.put("code","ok");
result.put("msg","切换定时任务成功!");
return result;
}
}
Service服务层是改动最大的,所有对定时任务计划的操作都在这里,这里也是集合了jeesite4和jeecg2个框架的地方
同时添加一个autoRun的方法,在系统启动时遍历表查看哪些定时任务是开启状态,依次启动。
总感觉应该有其他方法启动这些任务,但是我没找到。只好用这种笨办法来启动开启的定时任务了
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.quartz.service;
import com.jeesite.common.entity.Page;
import com.jeesite.common.service.CrudService;
import com.jeesite.modules.quartz.dao.QuartzJobDao;
import com.jeesite.modules.quartz.entity.QuartzJob;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.utils.UserUtils;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
/**
* Quartz定时任务表Service
* @author 淡梦如烟
* @version 2020-03-02
*/
@Service
@Transactional(readOnly=true)
public class QuartzJobService extends CrudService<QuartzJobDao, QuartzJob> {
@Autowired
private Scheduler scheduler;
/**
* 获取单条数据
* @param quartzJob
* @return
*/
@Override
public QuartzJob get(QuartzJob quartzJob) {
return super.get(quartzJob);
}
/**
* 查询分页数据
* @param quartzJob 查询条件
* @return
*/
@Override
public Page<QuartzJob> findPage(QuartzJob quartzJob) {
return super.findPage(quartzJob);
}
/**
* 保存数据(插入或更新)
* @param quartzJob
*/
@Override
@Transactional(readOnly=false)
public void save(QuartzJob quartzJob) {
super.preSave(quartzJob);
User user = UserUtils.getUser();
if (quartzJob.getIsNewRecord()) {
//新增
if("0".equals(quartzJob.getStatus())){
// 定时器添加
this.schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
}
quartzJob.setCreateBy(user.getLoginCode());
quartzJob.setCreateTime(new Date());
super.insert(quartzJob);
} else {
//修改
if("0".equals(quartzJob.getStatus())){
//定时器删除
this.schedulerDelete(quartzJob.getJobClassName().trim());
// 定时器添加
this.schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
}else{
try {
//定时器暂停
scheduler.pauseJob(JobKey.jobKey(quartzJob.getJobClassName().trim()));
} catch (SchedulerException e) {
e.printStackTrace();
}
}
quartzJob.setUpdateBy(user.getLoginCode());
quartzJob.setUpdateTime(new Date());
super.update(quartzJob);
}
}
/**
* 更新状态
* @param quartzJob
*/
@Override
@Transactional(readOnly=false)
public void updateStatus(QuartzJob quartzJob) {
super.updateStatus(quartzJob);
}
/**
* 删除数据
* @param quartzJob
*/
@Override
@Transactional(readOnly=false)
public void delete(QuartzJob quartzJob) {
schedulerDelete(quartzJob.getJobClassName().trim());
super.delete(quartzJob);
}
/**
* 添加定时任务
* @param jobClassName 类名
* @param cronExpression cron表达式
* @param parameter 参数
*/
private void schedulerAdd(String jobClassName, String cronExpression, String parameter) {
try {
// 启动调度器
scheduler.start();
// 构建job信息
JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobClassName).usingJobData("parameter", parameter).build();
// 表达式调度构建器(即任务执行的时间)
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
// 按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName).withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger);
logger.info("定时任务[" + jobClassName + "]已添加");
} catch (SchedulerException e) {
throw new RuntimeException("创建定时任务失败", e);
} catch (RuntimeException e) {
throw new RuntimeException(e.getMessage(), e);
}catch (Exception e) {
throw new RuntimeException("后台找不到该类名:" + jobClassName, e);
}
}
/**
* 获取Class
* @param classname Class类名
* @return
* @throws Exception
*/
private static Job getClass(String classname) throws Exception {
Class<?> class1 = Class.forName(classname);
return (Job) class1.newInstance();
}
/**
* 删除定时任务
*
* @param jobClassName
*/
private void schedulerDelete(String jobClassName) {
try {
scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));
scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));
scheduler.deleteJob(JobKey.jobKey(jobClassName));
logger.info("定时任务[" + jobClassName + "]已删除");
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException("删除定时任务失败");
}
}
/**
* 切换任务调度
* @param quartzJob
*/
@Transactional(readOnly = false)
public void switchQuartz(QuartzJob quartzJob) throws Exception{
QuartzJob quartzJob1 = new QuartzJob();
quartzJob1.setId(quartzJob.getId());
QuartzJob quartzJob2 = super.get(quartzJob1);
quartzJob2.setStatus(quartzJob.getStatus());
User user = UserUtils.getUser();
//修改
if ("0".equals(quartzJob2.getStatus())) {
//定时器删除
this.schedulerDelete(quartzJob2.getJobClassName().trim());
// 定时器添加
this.schedulerAdd(quartzJob2.getJobClassName().trim(), quartzJob2.getCronExpression().trim(), quartzJob2.getParameter());
} else {
try {
//定时器暂停
scheduler.pauseJob(JobKey.jobKey(quartzJob2.getJobClassName().trim()));
logger.info("定时任务[" + quartzJob2.getJobClassName() + "]已暂停");
} catch (SchedulerException e) {
e.printStackTrace();
}
}
quartzJob2.setUpdateBy(user.getLoginCode());
quartzJob2.setUpdateTime(new Date());
super.update(quartzJob2);
super.updateStatus(quartzJob2);
}
/**
* 系统启动时启动所有开启的定时任务作业
*/
@Transactional(readOnly = false)
public void autoRun() {
try {
QuartzJob quartzJob1 = new QuartzJob();
//已启用的任务
quartzJob1.setStatus("0");
List<QuartzJob> list = super.findList(quartzJob1);
logger.info("已启用的任务共[" + list.size() + "]条,正在依次启动>>>>>>>>>>>>>>>>>>>>>>>>>>>");
for (QuartzJob quartzJob2 : list) {
try {
this.switchQuartz(quartzJob2);
} catch (Exception e) {
logger.error("启动失败! 任务类名[" + quartzJob2.getJobClassName() + "],描述[" +
quartzJob2.getDescription() + "],详细信息:");
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
其他后台代码都能自动生成,也能在前面的度盘包里下,我就不贴了。
前端页面就一个列表页面和一个新增修改页面
这2个改的稍大,直接贴出来吧:
列表页面views/modules/quartz/quartzJobList.html
<% layout('/layouts/default.html', {title: 'quartz定时任务表管理', libs: ['dataGrid']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-header">
<div class="box-title">
<i class="fa icon-notebook"></i> ${text('quartz定时任务表管理')}
</div>
<div class="box-tools pull-right">
<a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-filter"></i> ${text('查询')}</a>
<% if(hasPermi('quartz:quartzJob:edit')){ %>
<a href="${ctx}/quartz/quartzJob/form" class="btn btn-default btnTool" title="${text('新增quartz定时任务表')}"><i class="fa fa-plus"></i> ${text('新增')}</a>
<% } %>
</div>
</div>
<div class="box-body">
<#form:form id="searchForm" model="${quartzJob}" action="${ctx}/quartz/quartzJob/listData" method="post" class="form-inline hide"
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<div class="form-group">
<label class="control-label">${text('任务类名')}:</label>
<div class="control-inline">
<#form:input path="jobClassName" maxlength="255" class="form-control width-120"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('描述')}:</label>
<div class="control-inline">
<#form:input path="description" maxlength="255" class="form-control width-120"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('状态')}:</label>
<div class="control-inline width-120">
<#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('cron表达式')}:</label>
<div class="control-inline">
<#form:input path="cronExpression" maxlength="255" class="form-control width-120"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('参数')}:</label>
<div class="control-inline">
<#form:input path="parameter" maxlength="255" class="form-control width-120"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('创建时间')}:</label>
<div class="control-inline">
<#form:input path="createTime" readonly="true" maxlength="20" class="form-control Wdate-datetime"
dataFormat="datetime" onclick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm',isShowClear:false});"/>
</div>
</div>
<div class="form-group" style="display: none">
<label class="control-label">${text('删除状态')}:</label>
<div class="control-inline">
<#form:input path="delFlag" maxlength="10" class="form-control width-120"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('修改时间')}:</label>
<div class="control-inline">
<#form:input path="updateTime" readonly="true" maxlength="20" class="form-control Wdate-datetime"
dataFormat="datetime" onclick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm',isShowClear:false});"/>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm">${text('重置')}</button>
</div>
</#form:form>
<table id="dataGrid"></table>
<div id="dataGridPage"></div>
</div>
</div>
</div>
<% } %>
<script>
// 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
columnModel: [
{header:'${text("任务类名")}', name:'jobClassName', index:'a.job_class_name', width:220, align:"left", frozen:true, formatter: function(val, obj, row, act){
return '<a href="${ctx}/quartz/quartzJob/form?id='+row.id+'" class="btnList" data-title="${text("编辑quartz定时任务表")}">'+(val||row.id)+'</a>';
}},
{header:'${text("描述")}', name:'description', index:'a.description', width:200, align:"left"},
{header:'${text("状态")}', name:'status', index:'a.status', width:60, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('sys_search_status')}, val, '${text("未知")}', true);
}},
{header:'${text("cron表达式")}', name:'cronExpression', index:'a.cron_expression', width:120, align:"left"},
{header:'${text("参数")}', name:'parameter', index:'a.parameter', width:120, align:"left"},
{header:'${text("创建时间")}', name:'createTime', index:'a.create_time', width:130, align:"center",hidden:true},
{header:'${text("删除状态")}', name:'delFlag', index:'a.del_flag', width:150, align:"left",hidden:true},
{header:'${text("修改时间")}', name:'updateTime', index:'a.update_time', width:130, align:"center"},
{header:'${text("操作")}', name:'actions', width:120, sortable:false, title:false, formatter: function(val, obj, row, act){
var actions = [];
<% if(hasPermi('quartz:quartzJob:edit')){ %>
actions.push('<a href="${ctx}/quartz/quartzJob/form?id='+row.id+'" class="btnList" title="${text("编辑Quartz定时任务")}"><i class="fa fa-pencil"></i></a> ');
actions.push('<a href="${ctx}/quartz/quartzJob/delete?id='+row.id+'" class="btnList" title="${text("删除Quartz定时任务")}" data-confirm="${text("确认要删除该定时任务吗?")}"><i class="fa fa-trash-o"></i></a> ');
if(row.status == "0"){
actions.push('<a οnclick="switchQuartz(\''+row.id+'\',\'2\')" title="${text("暂停定时任务")}"><i class="fa fa-pause-circle-o"></i></a> ');
}else{
actions.push('<a οnclick="switchQuartz(\''+row.id+'\',\'0\')" title="${text("启动定时任务")}"><i class="fa fa-play-circle-o"></i></a> ');
}
<% } %>
return actions.join('');
}}
],
// 加载成功后执行事件
ajaxSuccess: function(data){
}
});
/**
* 切换状态
* @param id 主键
* @param status 状态
*/
function switchQuartz(id, status) {
$.ajax({
type: "post",
"url": "${ctx}/quartz/quartzJob/switch",
data: {"id": id, "status": status},
dataType: "json",
success: function (data) {
// console.log(data);
if(data.code=="ok"){
//当执行成功后,执行如下代码
$('#dataGrid').trigger("reloadGrid");
if(status == "0"){
layer.msg("启动成功");
}else{
layer.msg("暂停成功");
}
}else{
layer.alert(data.msg);
}
},
error: function (xml, code) {
console.log(xml.responseText);
layer.alert("提交数据失败,请确认任务类名的全称是否正确!");
}
});
}
</script>
多一个切换状态的方法,和一些界面上的修改
新增/修改界面views/modules/quartz/quartzJobForm.html
<% layout('/layouts/default.html', {title: 'quartz定时任务表管理', libs: ['validate']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-header with-border">
<div class="box-title">
<i class="fa icon-note"></i> ${text(quartzJob.isNewRecord ? '新增quartz定时任务表' : '编辑quartz定时任务表')}
</div>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
<#form:form id="inputForm" model="${quartzJob}" action="${ctx}/quartz/quartzJob/save" method="post" class="form-horizontal">
<div class="box-body">
<div class="form-unit">${text('基本信息')}</div>
<#form:hidden path="id"/>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('任务类名')}:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="jobClassName" maxlength="255" class="form-control"/>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('描述')}:<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:input path="description" maxlength="255" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('cron表达式')}:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="cronExpression" maxlength="255" class="form-control"/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('参数')}:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="parameter" maxlength="255" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row" style="display: none">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('修改时间')}:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="updateTime" readonly="true" maxlength="20" class="form-control Wdate"
dataFormat="datetime" onclick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm',isShowClear:true});"/>
</div>
</div>
</div>
</div>
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-offset-2 col-sm-10">
<% if (hasPermi('quartz:quartzJob:edit')){ %>
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>
<% } %>
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
</div>
</div>
</div>
</#form:form>
</div>
</div>
<% } %>
<script>
$("#inputForm").validate({
submitHandler: function(form){
js.ajaxSubmitForm($(form), function(data){
js.showMessage(data.message);
if(data.result == Global.TRUE){
js.closeCurrentTabPage(function(contentWindow){
contentWindow.page();
});
}
}, "json");
}
});
$(function () {
bindCron("cronExpression");
})
/**
* 绑定Cron点击事件
*/
function bindCron(id) {
$("#" + id).on("click", function (e) {
openCronFrame(id);
})
}
/**
* Cron执行表达式
* @param id 写入表达式的组件id
*/
function openCronFrame(id) {
layer.open({
title: "Cron执行表达式",
type: 1,
id: "cronFrameLayer",
btn: ['确定', '取消'],
area: ['660px', '530px'],
//不固定
fixed: false,
maxmin: true,
//点击遮罩层关闭
shadeClose: true,
content: "<iframe id='cronFrame' src='${ctxStatic}/cron-quartz/index.html?ctx=/js/a' " +
"style=\"width:660px;height:530px;border:0\"></iframe>",
yes: function (index, layero) {
var body = layer.getChildFrame('body', index);
var cron = body.find("#cron").val();
if (cron != null && cron != undefined && cron != "") {
$("#" + id).val(cron);
}
layer.close(index); //如果设定了yes回调,需进行手工关闭
}
});
}
</script>
该界面的openCronFrame就是打开cron表达式选择器的窗口。
本来layer.open的type为2直接给iframe的链接的,但不做为啥jeesite4识别为POST请求无法加载这个静态页面。于是手写一个iframe避开这个小坑…
上面就是系统内的控制流程了
但是服务器开启的时候不会自动加载这些定时任务,我也暂时没找到方法,只好启动时写个方法去查表依次启动这些任务流程了。代码如下:
package com.jeesite.modules.autoRun;
import com.jeesite.modules.quartz.service.QuartzJobService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* @program: jeesite4.1.5
* @description: MyCommandLineRunner
* @author: 淡梦如烟
* @create: 2020-02-10 16:54
*/
@Component
@Order(value = 2)
public class MyCommandLineRunner implements CommandLineRunner {
protected Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* Quartz定时任务模块
*/
@Autowired
private QuartzJobService quartzJobService;
@Override
public void run(String... args) throws Exception {
logger.info("启动Quartz定时任务模块>>>>>>>>>>>>>>>>>>>>>>>>");
quartzJobService.autoRun();
}
}
一个简单的开机自启方法
结语
一个简单的定时任务调度模块,还有很多功能没有实现,没有完善。但是好歹这也是第一步。
非常感谢jeesite和jeecg这些开源框架,在这些里面能学习很多东西~