【过往系列文章】
cron表达式通常有6个(也可能7个)由空格分隔的时间元素。该词来源于希腊语chronos(χρόνος),原意是时间。
顺序 字段 取值范围 允许的特殊字符
1 秒 0~59 , - * /
2 分 0~59 , - * /
3 时 0~23 , - * /
4 日 1~31 , - * ? / L W C
5 月 1~12 , - * /
6 星期 0~7 (SUN=0或7,或SUN-SAT) , - * ? / L C #
7 年份 1970~2099(可有可无) , - * /
简单点,直接举几个例子:
0 0 2 1 * ? * 表示在每月的1日的凌晨2点调度任务
0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业
0 15 10 ? * 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作
对于非技术用户来说,妈呀,这是啥?
做动态任务,最难的可能就是在线生成Cron表达式,以前我们的做法一般是百度类似的表达式改造,或者用一些在线页面生成Cron,如果遇上用户不会,需要一个页面让他们可以看着选择需要的执行时间,拿我这个是不错的选择
这里我整合了一个分享给大家,效果图
这里用到的就是有两个,打开一个窗口的页面,我用的layer,这个一般用最新的就可以了
JY.Layer.iframeFull("Cron快速选择",jypath+"/static/plugins/cronb/cron.html");
关于JY京缘网络的js核心组件,这个我把封装源码再分享一下
Layer:{
//title:相册标题
photo:function(s,t,a){
layer.photos({photos: {"title":t,"id": 100, "start": 0,"data": [{"alt":a,"pid":1,"src":s,"thumb":s}]}});
},
iframe:function(title,url,width,height){
let layerIframe=layer.open({maxmin:true,type:2,title:title,shadeClose:true,area:[width, height],content:url});return layerIframe;
},
iframeFull:function(title,url){
let layerIframe=layer.open({type:2,title:title,shadeClose:true,area:[document.documentElement.clientWidth * 1+"px", document.documentElement.clientHeight * 1+"px"],content:url});layer.full(layerIframe);return layerIframe;
},
iframeRatio:function(title,url,ratio){
let layerIframe=layer.open({type:2,title:title,shadeClose:true,maxmin:true ,area:[document.documentElement.clientWidth * ratio+"px", document.documentElement.clientHeight * ratio+"px"],content:url});return layerIframe;
}
}
核心的js主要有两个
init.js,定义一些页面的方法
/**
* Created by LinJ on 2015/11/5.
* 初始化页面模块js
*/
//初始化各类元素以及监听
$(function () {
inition();
});
//页面所有的页签名称
var itemList = ["second", "min", "hour", "day", "month", "week"];
//初始化各个页签自主选择的最大值
var max_second = 59;
var max_min = 59;
var max_hour = 23;
var max_day = 31;
var max_month = 12;
var max_quarter = 12;
var max_week = 7;
function inition() {
//初始化checkbox
initCheckBox("l_second", 0, 59);
initCheckBox("l_min", 0, 59);
initCheckBox("l_hour", 0, 23);
initCheckBox("l_day", 1, 31);
initCheckBox("l_month", 1, 12);
initCheckBox("l_quarter", 1, 12);
initCheckBox("l_week", 1, 7);
//初始化单选、复选框
$('input').iCheck({
checkboxClass: 'icheckbox_square-blue',
radioClass: 'iradio_square-blue',
increaseArea: '20%' // optional
});
//解析按钮绑定函数
$('#explain').click(function () {
reverseExp();
});
$("#saveCronBtn").on('click', function(e) {
let cronInput=$("#cron").val();
parent.$("#transCronInput").val(cronInput);
parent.calNextPoint(cronInput);
let index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
parent.layer.close(index); //再执行关闭
});
$("#cancelCronBtn").on('click', function(e) {
let index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
parent.layer.close(index); //再执行关闭
});
initFirstRadio();
initNoConfirmRadio();
initRadio();
initRadioCheckDiv();
initSpinner();
initCronFromTable();
initListChange();
initMonthByQuarter();
//如果已有传输过来的值,那么放入cron字段并且反解析
var instr = $("#transCron").val();
if (instr) {
$("#cron").val(instr);
reverseExp();
}
}
//初始化大量的复选框 根据div的id以及数量进行初始化 每个复选框占1/12宽度
function initCheckBox(divid, start, cnt) {
if (cnt != null && cnt > 0) {
for (dc = start; dc <= cnt; dc++) {
$("#" + divid).append(" <div class='col-xs-1 col-sm-1 col-md-1'> <label><input type='checkbox' value=" + dc + "> " + dc + "</label></div>");
}
}
}
//初始化每个页签第一排的radio,即*条件
function initFirstRadio() {
$('.firstradio').on('ifChecked', function () {
everyTime(this);
});
$('.unselectradio').on('ifChecked', function () {
clearSpan(this);
});
//季度的第一排radio,需要指定为month
$('.firstradioreactor').on('ifChecked', function () {
everyTimeByName("v_month");
});
}
//初始化不指定的radio 即?条件 以及最后一日条件
function initNoConfirmRadio() {
$('.noconfirmradio').on('ifChecked', function () {
unAppoint(this);
});
$('.lastdayradio').on('ifChecked', function () {
lastDay(this);
});
}
//初始化每个页签选择的的radio
function initRadio() {
//周期选择的radio
$('.cycleradio').on('ifChecked', function () {
writeStartAndEnd(this, "-");
});
//循环选择的radio
$('.loopradio').on('ifChecked', function () {
writeStartAndEnd(this, "/");
});
//指定选择的radio 即#
$('.designradio').on('ifChecked', function () {
writeStartAndEnd(this, "#");
});
//自主选择的radio
$('.choiceradio').on('ifChecked', function () {
var spanname = this.name;
var theList = $("." + spanname + "List").find(':checkbox');
var maxvalue = eval("max_" + this.name);
changeSpanFromCheckList(theList, maxvalue, spanname);
});
//最近工作日的radio
$('.nearradio').on('ifChecked', function () {
writeEnd(this, "W");
});
//最后一个周几的radio
$('.lastradio').on('ifChecked', function () {
writeEnd(this, "L");
});
}
//初始化div内容监听绑定函数,即点击div,对应radio被选中
function initRadioCheckDiv() {
$('.radiocheck').click(function () {
radioCheckByClick(this);
});
$.each(itemList, function (n, value) {
var checkList = $("." + value + "List");
checkList.click(function () {
var theRadio = this.closest('.radiocheck').find(':radio');
theRadio.eq(0).iCheck('check');
});
});
}
//绑定数字微调器
function initSpinner() {
//绑定数字微调器
$(".cyclespin").spinner('changing', function (e, newVal, oldVal) {
//trigger immediately
writeStartAndEnd(this, "-");
});
$(".loopspin").spinner('changing', function (e, newVal, oldVal) {
//trigger immediately
writeStartAndEnd(this, "/");
});
$(".designspin").spinner('changing', function (e, newVal, oldVal) {
//trigger immediately
writeStartAndEnd(this, "#");
});
$(".nearspin").spinner('changing', function (e, newVal, oldVal) {
//trigger immediately
writeEnd(this, "W");
});
$(".lastspin").spinner('changing', function (e, newVal, oldVal) {
//trigger immediately
writeEnd(this, "L");
});
}
//表达式结果由表格生成到cron表达式
function initCronFromTable() {
//查找所有name以v_开头的span元素
var vals = $("span[name^='v_']");
var cron = $("#cron");
vals.change(function () {
var item = [];
vals.each(function () {
item.push(this.innerHTML);
});
cron.val(item.join(" "));
});
}
//定义checkbox在被点击的时候的绑定函数 循环遍历页签数组
function initListChange() {
$.each(itemList, function (n, value) {
var checkList = $("." + value + "List").find(':checkbox');
var maxvalue = eval("max_" + value);
initChangeOnCheckboxList(checkList, maxvalue, value);
});
}
//给list的checkbox绑定点击方法 入参是list,最大值,指定输出的span名称
function initChangeOnCheckboxList(checkList, maxvalue, spanname) {
checkList.on('ifChanged', function () {
//模拟div被点击过一次
$(this).closest('.radiocheck').click();
changeSpanFromCheckList(checkList, maxvalue, spanname);
});
}
//定义季度的月份选择监听
function initMonthByQuarter() {
var checkList = $("#quarter_spe").find(':checkbox');
checkList.on('ifChanged', function () {
var vals = [];
checkList.each(function () {
if (this.checked) {
vals.push(this.value);
}
});
var val = "?";
val = vals.join(",");
ary = val.split(",");
unselectAll('l_quarter');
for (var i = 0; i < ary.length; i++) {
$("#l_quarter input[value='" + ary[i] + "']").iCheck('check');
}
});
}
//清除选中状态
function unselectAll(listId) {
for (var i = 1; i <= 12; i++) {
$("#l_quarter input[value='" + i + "']").iCheck('uncheck');
}
}
cronboot.js,主要功能模块
/**
* Created by LinJ on 2015/11/5.
* 页面功能模块js
*/
/**
* 表达式重置为默认值
*/
function everyTime(dom) {
var item = $("span[name=v_" + dom.name + "]");
item.html("*");
item.change();
}
/**
* 表达式重置为默认值
入参为元素的名字
*/
function everyTimeByName(v_name) {
var item = $("span[name=" +v_name + "]");
item.html("*");
item.change();
}
//清除表达式的值
function clearSpan(dom){
var item = $("span[name=v_" +dom.name + "]");
item.html("");
item.change();
}
/**
* 不指定 即重置为?号
*/
function unAppoint(dom) {
var name = dom.name;
var val = "?";
if (name == "year")
val = "";
var item = $("span[name=v_" + name + "]");
item.html(val);
item.change();
}
/**
* 不指定 即重置为?号
入参为元素的名字
*/
function unAppointByName(v_name) {
var val = "?";
if (v_name == "year")
val = "";
var item = $("span[name=" + v_name + "]");
item.html(val);
item.change();
}
//最后一日
function lastDay(dom){
var item = $("span[name=v_" + dom.name + "]");
item.html("L");
item.change();
}
/**
* 书写有前后的公式,包括 1-2 1/2 1#2 等
*/
function writeStartAndEnd(dom,sym) {
var name = dom.name;
var ns = $(dom).closest('.radiocheck').find(".numberspinner");
var start = ns.eq(0).val();
var end = ns.eq(1).val();
var item = $("span[name=v_" + name + "]");
item.html(start + sym + end);
item.change();
}
//书写只有前的工时,包括1W 1L等
function writeEnd(dom,sym){
var name = dom.name;
var ns = $(dom).closest('.radiocheck').find(".numberspinner");
var value = ns.eq(0).val();
var item = $("span[name=v_" + name + "]");
item.html(value + sym);
item.change();
}
//点击div中的内容,对应radio即被选中的功能
function radioCheckByClick(dom){
var theRadio = $(dom).find(':radio');
theRadio.eq(0).iCheck('check');
}
//从checkList更新span的通用方法
function changeSpanFromCheckList(checkList,maxvalue,spanname){
var vals = [];
checkList.each(function () {
if (this.checked) {
vals.push(this.value);
}
});
var val = "?";
if (vals.length > 0 && vals.length < maxvalue) {
val = vals.join(",");
}else if(vals.length == maxvalue){
val = "*";
}
var item = $("span[name=v_"+spanname+"]");
item.html(val);
item.change();
}
//解析cron表达式到生成器的函数
function reverseExp() {
//获取参数中表达式的值
var txt = $("#cron").val();
if (txt) {
var regs = txt.split(' ');
expObj(regs[0], "second");
expObj(regs[1], "min");
expObj(regs[2], "hour");
expDay(regs[3], "day");
expObj(regs[4], "month");
expWeek(regs[5],"week");
if (regs.length > 6) {
$("span[name=v_year]").html(regs[6]);
expYear(regs[6],"year");
}
}
}
//解析时分秒月
function expObj(val,type){
//表达式结果框赋值
$("span[name=v_"+type+"]").html(val);
//寻找对应类型的radio列表
var radios = $(":radio[name="+type+"]");
var ary = null;
//根据值的类型进行判断与对应赋值,以及radio的选中。
if (val == "*") {
radios.eq(0).iCheck("check");
} else if (val.split('-').length > 1) {
ary = val.split('-');
$(":text[name="+type+"]").eq(0).val(ary[0]);
$(":text[name="+type+"]").eq(1).val(ary[1]);
radios.eq(1).iCheck("check");
} else if (val.split('/').length > 1) {
ary = val.split('/');
$(":text[name="+type+"]").eq(2).val(ary[0]);
$(":text[name="+type+"]").eq(3).val(ary[1]);
radios.eq(2).iCheck("check");
} else {
if (val != "?") {
ary = val.split(",");
for (var i = 0; i < ary.length; i++) {
$("." + type + "List input[value='" + ary[i] + "']").iCheck("check");
}
}
radios.eq(3).iCheck("check");
}
}
//解析日
function expDay(val,type){
//表达式结果框赋值
$("span[name=v_"+type+"]").html(val);
//寻找对应类型的radio列表
var radios = $(":radio[name="+type+"]");
var ary = null;
//根据值的类型进行判断与对应赋值,以及radio的选中。
if (val == "*") {
radios.eq(0).iCheck("check");
}else if (val == "?") {
radios.eq(1).iCheck("check");
}else if (val == "L") {
radios.eq(2).iCheck("check");
}else if (val.split('-').length > 1) {
ary = val.split('-');
$(":text[name="+type+"]").eq(0).val(ary[0]);
$(":text[name="+type+"]").eq(1).val(ary[1]);
radios.eq(3).iCheck("check");
} else if (val.split('/').length > 1) {
ary = val.split('/');
$(":text[name="+type+"]").eq(2).val(ary[0]);
$(":text[name="+type+"]").eq(3).val(ary[1]);
radios.eq(4).iCheck("check");
} else if (val.split('W').length > 1) {
ary = val.split('W');
$(":text[name="+type+"]").eq(4).val(ary[0]);
radios.eq(5).iCheck("check");
}else {
if (val != "?") {
ary = val.split(",");
for (var i = 0; i < ary.length; i++) {
$("." + type + "List input[value='" + ary[i] + "']").iCheck("check");
}
}
radios.eq(6).iCheck("check");
}
}
//解析周
function expWeek(val,type){
//表达式结果框赋值
$("span[name=v_"+type+"]").html(val);
//寻找对应类型的radio列表
var radios = $(":radio[name="+type+"]");
var ary = null;
//根据值的类型进行判断与对应赋值,以及radio的选中。
if (val == "*") {
radios.eq(0).iCheck("check");
}else if (val == "?") {
radios.eq(1).iCheck("check");
}else if (val.split('-').length > 1) {
ary = val.split('-');
$(":text[name="+type+"]").eq(0).val(ary[0]);
$(":text[name="+type+"]").eq(1).val(ary[1]);
radios.eq(2).iCheck("check");
} else if (val.split('/').length > 1) {
ary = val.split('/');
$(":text[name="+type+"]").eq(2).val(ary[0]);
$(":text[name="+type+"]").eq(3).val(ary[1]);
radios.eq(3).iCheck("check");
}else if (val.split('#').length > 1) {
ary = val.split('#');
$(":text[name="+type+"]").eq(4).val(ary[0]);
$(":text[name="+type+"]").eq(5).val(ary[1]);
radios.eq(4).iCheck("check");
} else if (val.split('L').length > 1) {
ary = val.split('L');
$(":text[name="+type+"]").eq(6).val(ary[0]);
radios.eq(5).iCheck("check");
}else {
if (val != "?") {
ary = val.split(",");
for (var i = 0; i < ary.length; i++) {
$("." + type + "List input[value='" + ary[i] + "']").iCheck("check");
}
}
radios.eq(6).iCheck("check");
}
}
//解析年
function expYear(val,type){
//表达式结果框赋值
$("span[name=v_"+type+"]").html(val);
//寻找对应类型的radio列表
var radios = $(":radio[name="+type+"]");
var ary = null;
//根据值的类型进行判断与对应赋值,以及radio的选中。
if (val == "*") {
radios.eq(1).iCheck("check");
}else if (val.split('-').length > 1) {
ary = val.split('-');
$(":text[name="+type+"]").eq(0).val(ary[0]);
$(":text[name="+type+"]").eq(1).val(ary[1]);
radios.eq(2).iCheck("check");
}
}
然后关于整合的web系统,我们可以通过打开链接到这个页面
这里可以通过修改init.js适应大家不同的系统
$("#saveCronBtn").on('click', function(e) {
let cronInput=$("#cron").val();
parent.$("#transCronInput").val(cronInput);
parent.calNextPoint(cronInput);
let index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
parent.layer.close(index); //再执行关闭
});
$("#cancelCronBtn").on('click', function(e) {
let index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
parent.layer.close(index); //再执行关闭
});
这里只需要父窗口有一个id为transCronInput的input即可,用来保存生成数据
这两个可按需要修改对应的
这里展示一下对应的父窗口设计是怎样的,按快选就是进入上面的页面
到这里,就介绍完我的这个模板,有问题可以留言,看见会回复大家的,下载这个模板组件可以留意下面