最近做的一个vue3项目过程中,需要用到cron表达式功能,而对于普通业务人员,他们是不懂cron表达式规则的,所以需要做一个可手动配置生成cron表达式的功能。从网上查找了一些相关资料,然后结合vue3+Element Plus,改造成适合自己项目的组件。记录代码如下:

实现功能:

  1、在下拉框里手动选择后生成cron表达式

  2、根据cron表达式,各个下拉框最选中的回显

  3、根据cron表达式,打印表达式会在最近5次的执行时间

1、components目录下新建 vue3Cron/Index.vue

src/components/vue3Cron/Index.vue

<template>
<div class="v3c">
<ul class="v3c-tab">
<li class="v3c-tab-item" style="display:none;" :class="{ 'v3c-active': tabActive == 1 }" @click="onHandleTab(1)">秒
</li>
<li class="v3c-tab-item" :class="{ 'v3c-active': tabActive == 2 }" @click="onHandleTab(2)">分</li>
<li class="v3c-tab-item" :class="{ 'v3c-active': tabActive == 3 }" @click="onHandleTab(3)">时</li>
<li class="v3c-tab-item" :class="{ 'v3c-active': tabActive == 4 }" @click="onHandleTab(4)">天</li>
<li class="v3c-tab-item" :class="{ 'v3c-active': tabActive == 5 }" @click="onHandleTab(5)">月</li>
<!-- <li class="v3c-tab-item" :class="{ 'v3c-active': tabActive == 6 }" @click="onHandleTab(6)">年</li> -->
</ul>
<!-- 秒 -->
<div class="v3c-content" v-show="tabActive == 1">
<!-- 每一秒 -->
<div>
<el-radio label="1" v-model="state.second.cronEvery">每一秒钟</el-radio>
</div>
<!-- 每隔多久 -->
<div class="mt-15">
<el-radio label="2" v-model="state.second.cronEvery">每隔</el-radio>
<el-input-number v-model="state.second.incrementIncrement" :min="1" :max="60" controls-position="right" />
<span class="ml-5 mr-5">秒执行, 从</span>
<el-input-number v-model="state.second.incrementStart" :min="0" :max="59" controls-position="right" />
<span>秒开始</span>
</div>
<!-- 具体秒数 -->
<div class="mt-15">
<el-radio label="3" v-model="state.second.cronEvery">具体秒数(可多选)</el-radio>
<el-select v-model="state.second.specificSpecific" multiple clearable style="width: 140px">
<el-option v-for="(item, index) in 60" :key="index" :label="index" :value="index" />
</el-select>
</div>
<!-- 周期从 -->
<div class="mt-15">
<el-radio label="4" v-model="state.second.cronEvery">周期从</el-radio>
<el-input-number v-model="state.second.rangeStart" :min="0" :max="59" controls-position="right" />
<sapn>秒</sapn><span class="ml-10 mr-5">到</span>
<el-input-number v-model="state.second.rangeEnd" :min="0" :max="59" controls-position="right" />
<sapn>秒</sapn>
</div>
</div>
<!-- 分钟 -->
<div class="v3c-content" v-show="tabActive == 2">
<!-- 每一分钟 -->
<div>
<el-radio label="1" v-model="state.minute.cronEvery">每一分钟</el-radio>
</div>
<!-- 每隔多久 -->
<div class="mt-15">
<el-radio label="2" v-model="state.minute.cronEvery">每隔</el-radio>
<el-input-number v-model="state.minute.incrementIncrement" :min="1" :max="60" controls-position="right" />
<span class="ml-5 mr-5">分执行,从</span>
<el-input-number v-model="state.minute.incrementStart" :min="0" :max="59" controls-position="right" />
<span>分开始</span>
</div>
<!-- 具体分钟数 -->
<div class="mt-15">
<el-radio label="3" v-model="state.minute.cronEvery">具体分钟数(可多选)</el-radio>
<el-select v-model="state.minute.specificSpecific" multiple clearable style="width: 140px">
<el-option v-for="(item, index) in 60" :key="index" :label="index" :value="index" />
</el-select>
</div>
<!-- 周期从 -->
<div class="mt-15">
<el-radio label="4" v-model="state.minute.cronEvery">周期从</el-radio>
<el-input-number v-model="state.minute.rangeStart" :min="0" :max="59" controls-position="right" />
<span>分</span><span class="ml-10 mr-5">到</span>
<el-input-number v-model="state.minute.rangeEnd" :min="0" :max="59" controls-position="right" />
<span>分</span>
</div>
</div>
<!-- 小时 -->
<div class="v3c-content" v-show="tabActive == 3">
<!-- 每一小时 -->
<div>
<el-radio label="1" v-model="state.hour.cronEvery">每一小时</el-radio>
</div>
<!-- 每隔多久 -->
<div class="mt-15">
<el-radio label="2" v-model="state.hour.cronEvery">每隔</el-radio>
<el-input-number v-model="state.hour.incrementIncrement" :min="1" :max="24" controls-position="right" />
<span class="ml-5 mr-5">小时执行,从</span>
<el-input-number v-model="state.hour.incrementStart" :min="0" :max="23" controls-position="right" />
<span>小时开始</span>
</div>
<!-- 具体小时数 -->
<div class="mt-15">
<el-radio label="3" v-model="state.hour.cronEvery">具体小时数(可多选)</el-radio>
<el-select v-model="state.hour.specificSpecific" multiple clearable style="width: 140px">
<el-option v-for="(item, index) in 24" :key="index" :label="index" :value="index" />
</el-select>
</div>
<!-- 周期从 -->
<div class="mt-15">
<el-radio label="4" v-model="state.hour.cronEvery">周期从</el-radio>
<el-input-number v-model="state.hour.rangeStart" :min="0" :max="23" controls-position="right" />
<span>时</span><span class="ml-10 mr-5">到</span>
<el-input-number v-model="state.hour.rangeEnd" :min="0" :max="23" controls-position="right" />
<span>时</span>
</div>
</div>
<!-- 天 -->
<div class="v3c-content" v-show="tabActive == 4">
<!-- 1 -->
<div>
<el-radio label="1" v-model="state.day.cronEvery">每一天</el-radio>
</div>
<!-- 2 -->
<div class="mt-15">
<el-radio label="2" v-model="state.day.cronEvery">每隔</el-radio>
<el-input-number v-model="state.week.incrementIncrement" :min="1" :max="60" controls-position="right" />
<span class="ml-5 mr-5">周执行,从</span>
<el-input-number v-model="state.week.incrementStart" :min="1" :max="52" controls-position="right" />
<span>周开始</span>
</div>
<!-- 3 -->
<div class="mt-15">
<el-radio label="3" v-model="state.day.cronEvery">每隔</el-radio>
<el-input-number v-model="state.day.incrementIncrement" :min="1" :max="30" controls-position="right" />
<span class="ml-5 mr-5">天执行,从</span>
<el-input-number v-model="state.day.incrementStart" :min="1" :max="30" controls-position="right" />
<span>天开始</span>
</div>
<!-- 4 -->
<div class="mt-15">
<el-radio label="4" v-model="state.day.cronEvery">具体星期几(可多选)</el-radio>
<el-select v-model="state.week.specificSpecific" multiple clearable style="width: 140px">
<el-option v-for="(item, index) in weekList" :key="index" :label="item.name" :value="item.value" />
</el-select>
</div>
<!-- 5 -->
<div class="mt-15">
<el-radio label="5" v-model="state.day.cronEvery">具体天数(可多选)</el-radio>
<el-select v-model="state.day.specificSpecific" multiple clearable style="width: 140px">
<el-option v-for="(item, index) in 31" :key="index" :label="item" :value="item" />
</el-select>
</div>
<!-- 6 -->
<!-- <div class="mt-15">
<el-radio label="6" v-model="state.day.cronEvery">在这个月的最后一天</el-radio>
</div> -->
<!-- 7 -->
<!-- <div class="mt-15">
<el-radio label="7" v-model="state.day.cronEvery">在这个月的最后一个工作日</el-radio>
</div> -->
<!-- 8 -->
<!-- <div class="mt-15">
<el-radio label="8" v-model="state.day.cronEvery">在这个月的最后一个</el-radio>
<el-select v-model="state.day.cronLastSpecificDomDay" style="width: 140px">
<el-option v-for="(item, index) in weekList" :key="index" :label="item.name" :value="item.val" />
</el-select>
</div> -->
<!-- 9 -->
<!-- <div class="mt-15">
<el-radio label="9" v-model="state.day.cronEvery">{{ }}</el-radio>
<el-input-number v-model="state.day.cronDaysBeforeEomMinus" :min="1" :max="31" controls-position="right" />
<span>在本月底前</span>
</div> -->
<!-- 10 -->
<!-- <div class="mt-15">
<el-radio label="10" v-model="state.day.cronEvery">最近的工作日(周一至周五)至本月</el-radio>
<el-input-number v-model="state.day.cronDaysNearestWeekday" :min="1" :max="31" controls-position="right" />
<span>日</span>
</div> -->
<!-- 11 -->
<!-- <div class="mt-15">
<el-radio label="11" v-model="state.day.cronEvery">在这个月的第</el-radio>
<el-input-number v-model="state.week.cronNthDayNth" :min="1" :max="5" controls-position="right" />
<span>个</span>
<el-select v-model="state.week.cronNthDayDay" style="width: 140px">
<el-option v-for="(item, index) in weekList" :key="index" :label="item.name" :value="item.val" />
</el-select>
</div> -->
</div>
<!-- 月 -->
<div class="v3c-content" v-show="tabActive == 5">
<!-- 1 -->
<div>
<el-radio label="1" v-model="state.month.cronEvery">每一月</el-radio>
</div>
<!-- 2 -->
<div class="mt-15">
<el-radio label="2" v-model="state.month.cronEvery">每隔</el-radio>
<el-input-number v-model="state.month.incrementIncrement" :min="1" :max="12" controls-position="right" />
<span class="ml-5 mr-5">月执行,从</span>
<el-input-number v-model="state.month.incrementStart" :min="1" :max="12" controls-position="right" />
<span>月开始</span>
</div>
<!-- 3 -->
<div class="mt-15">
<el-radio label="3" v-model="state.month.cronEvery">具体月数(可多选)</el-radio>
<el-select multiple clearable v-model="state.month.specificSpecific" style="width: 140px">
<el-option v-for="(item, index) in 12" :key="index" :label="item" :value="item" />
</el-select>
</div>
<!-- 4 -->
<div class="mt-15">
<el-radio label="4" v-model="state.month.cronEvery">周期从</el-radio>
<el-input-number v-model="state.month.rangeStart" :min="1" :max="12" controls-position="right" />
<span>月</span><span class="ml-10 mr-5">到</span>
<el-input-number v-model="state.month.rangeEnd" :min="1" :max="12" controls-position="right" />
<span>月</span>
</div>
</div>
<!-- 年 -->
<div class="v3c-content" v-show="tabActive == 6">
<!-- 1 -->
<div>
<el-radio label="1" v-model="state.year.cronEvery">每一年</el-radio>
</div>
<!-- 2 -->
<div class="mt-15">
<el-radio label="2" v-model="state.year.cronEvery">每隔</el-radio>
<el-input-number v-model="state.year.incrementIncrement" :min="1" :max="99" controls-position="right" />
<span class="ml-5 mr-5">年执行,从</span>
<el-input-number v-model="state.year.incrementStart" :min="currYear" :max="currYear + 10"
controls-position="right" style="width:100px;" />
<span>年开始</span>
</div>
<!-- 3 -->
<div class="mt-15">
<el-radio label="3" v-model="state.year.cronEvery">具体年份(可多选)</el-radio>
<el-select multiple clearable v-model="state.year.specificSpecific" style="width: 140px">
<el-option v-for="(item, index) in 100" :key="index" :label="currYear + item" :value="currYear + item" />
</el-select>
</div>
<!-- 4 -->
<div class="mt-15">
<el-radio label="4" v-model="state.year.cronEvery">周期从</el-radio>
<el-input-number v-model="state.year.rangeStart" :min="currYear" :max="currYear + 10" controls-position="right"
style="width:100px;" />
<span>年</span><span class="ml-10 mr-5">到</span>
<el-input-number v-model="state.year.rangeEnd" :min="currYear" :max="currYear + 10" controls-position="right"
style="width:100px;" />
<span>年</span>
</div>
</div>
<!-- 结果 -->
<!-- <div class="v3c-footer">
<div style="flex: 1">
CRON &nbsp;: &nbsp;&nbsp;<span class="cron">{{ state.cron }}</span>
&nbsp; &nbsp; &nbsp;
<button class="btn-ok" @click.stop="handleChange">生成cron</button>
</div>
</div> -->
</div>
</template> <script setup>
import { reactive, computed, onMounted, ref, watch } from "vue"; //定义子组件需要接收的值
const props = defineProps({
maxHeight: { type: String },
value: { type: String },
defaultCron: { type: String },
}); // 注册事件
const emits = defineEmits(["change", "onShowError"]); onMounted(() => {
// 根据表达式做下拉框的选中回显
console.log('-=-==-', props.value)
let arr = props.value.split(' ');
console.log(arr)
let minT = arr[1]; // 分
if (minT == '*') {
state.minute.cronEvery = '1';
} else if (minT.indexOf('/') > -1) {
state.minute.cronEvery = '2';
state.minute.incrementStart = minT.split('/')[0] - 0;
state.minute.incrementIncrement = minT.split('/')[1] - 0;
} else if (minT.indexOf('-') > -1) {
state.minute.cronEvery = '4';
state.minute.rangeStart = minT.split('-')[0] - 0;
state.minute.rangeEnd = minT.split('-')[1] - 0;
} else {
state.minute.cronEvery = '3';
state.minute.specificSpecific = minT.split(',').map(item => item - 0);
} let hourT = arr[2]; // 时
if (hourT == '*') {
state.hour.cronEvery = '1';
} else if (hourT.indexOf('/') > -1) {
state.hour.cronEvery = '2';
state.hour.incrementStart = hourT.split('/')[0] - 0;
state.hour.incrementIncrement = hourT.split('/')[1] - 0;
} else if (hourT.indexOf('-') > -1) {
state.hour.cronEvery = '4';
state.hour.rangeStart = hourT.split('-')[0] - 0;
state.hour.rangeEnd = hourT.split('-')[1] - 0;
} else {
state.hour.cronEvery = '3';
state.hour.specificSpecific = hourT.split(',').map(item => item - 0);
} let dayT = arr[3]; // 天
if (dayT == '*') {
state.day.cronEvery = '1';
} else if (dayT == '?') { // state.day.cronEvery 为2或4
let text = arr[5];
if (text.indexOf('/') > -1) { // state.day.cronEvery 为2
state.day.cronEvery = '2';
state.week.incrementStart = text.split('/')[0] - 0;
state.week.incrementIncrement = text.split('/')[1] - 0;
} else {
state.day.cronEvery = '4';
state.week.specificSpecific = text.split(',');
}
} else if (dayT.indexOf('/') > -1) {
state.day.cronEvery = '3';
state.day.incrementStart = dayT.split('/')[0] - 0;
state.day.incrementIncrement = dayT.split('/')[1] - 0;
} else {
state.day.cronEvery = '5';
state.day.specificSpecific = dayT.split(',').map(item => item - 0);
} let monthT = arr[4]; // 月
if (monthT == '*') {
state.month.cronEvery = '1';
} else if (monthT.indexOf('/') > -1) {
state.month.cronEvery = '2';
state.month.incrementStart = monthT.split('/')[0] - 0;
state.month.incrementIncrement = monthT.split('/')[1] - 0;
} else if (monthT.indexOf('-') > -1) {
state.month.cronEvery = '4';
state.month.rangeStart = monthT.split('-')[0] - 0;
state.month.rangeEnd = monthT.split('-')[1] - 0;
} else {
state.month.cronEvery = '3';
state.month.specificSpecific = monthT.split(',').map(item => item - 0);
}
}) const weekList = ref([
{ name: '星期日', value: 'SUN', val: 1, },
{ name: '星期一', value: 'MON', val: 2, },
{ name: '星期二', value: 'TUE', val: 3, },
{ name: '星期三', value: 'WED', val: 4, },
{ name: '星期四', value: 'THU', val: 5, },
{ name: '星期五', value: 'FRI', val: 6, },
{ name: '星期六', value: 'SAT', val: 7, },
]) const tabActive = ref(2);
const currYear = ref(new Date().getFullYear());
const onHandleTab = (index) => {
tabActive.value = index;
}; let errArr = ['', '', '', ''];
const state = reactive({
second: {
cronEvery: "3",
incrementStart: 0,
incrementIncrement: 1,
rangeStart: 0,
rangeEnd: 0,
specificSpecific: [0],
},
minute: {
cronEvery: "1",
incrementStart: 0,
incrementIncrement: 1,
rangeStart: 0,
rangeEnd: 0,
specificSpecific: [],
},
hour: {
cronEvery: "1",
incrementStart: 1,
incrementIncrement: 1,
rangeStart: 0,
rangeEnd: 0,
specificSpecific: [],
},
day: {
cronEvery: "1",
incrementStart: 1,
incrementIncrement: 1,
rangeStart: 0,
rangeEnd: 0,
specificSpecific: [],
cronLastSpecificDomDay: 1,
cronDaysBeforeEomMinus: 0,
cronDaysNearestWeekday: 1,
},
week: {
cronEvery: "1",
incrementStart: 1,
incrementIncrement: 1,
specificSpecific: [],
cronNthDayDay: 1,
cronNthDayNth: 1,
},
month: {
cronEvery: "1",
incrementStart: 1,
incrementIncrement: 1,
rangeStart: 1,
rangeEnd: 1,
specificSpecific: [],
},
year: {
cronEvery: "1",
incrementStart: new Date().getFullYear(),
incrementIncrement: 1,
rangeStart: new Date().getFullYear(),
rangeEnd: new Date().getFullYear(),
specificSpecific: [],
},
output: {
second: "",
minute: "",
hour: "",
day: "",
month: "",
Week: "",
year: "",
},
secondsText: computed(() => {
let seconds = "";
let cronEvery = state.second.cronEvery;
switch (cronEvery?.toString()) {
case "1":
seconds = "*";
break;
case "2":
seconds = state.second.incrementStart + "/" + state.second.incrementIncrement;
break;
case "3":
state.second.specificSpecific.map((val) => {
seconds += val + ",";
});
seconds = seconds.slice(0, -1);
break;
case "4":
seconds = state.second.rangeStart + "-" + state.second.rangeEnd;
break;
}
return seconds;
}),
minutesText: computed(() => {
console.log('bbb')
let minutes = "";
let cronEvery = state.minute.cronEvery;
switch (cronEvery?.toString()) {
case "1":
minutes = "*";
break;
case "2":
minutes = state.minute.incrementStart + "/" + state.minute.incrementIncrement;
break;
case "3":
state.minute.specificSpecific.map((val) => {
minutes += val + ",";
});
minutes = minutes.slice(0, -1);
break;
case "4":
minutes = state.minute.rangeStart + "-" + state.minute.rangeEnd;
break;
}
return minutes;
}),
hoursText: computed(() => {
let hours = "";
let cronEvery = state.hour.cronEvery;
switch (cronEvery?.toString()) {
case "1":
hours = "*";
break;
case "2":
hours = state.hour.incrementStart + "/" + state.hour.incrementIncrement;
break;
case "3":
state.hour.specificSpecific.map((val) => {
hours += val + ",";
});
hours = hours.slice(0, -1);
break;
case "4":
hours = state.hour.rangeStart + "-" + state.hour.rangeEnd;
break;
}
return hours;
}),
daysText: computed(() => {
let days = "";
let cronEvery = state.day.cronEvery;
switch (cronEvery?.toString()) {
case "1":
break;
case "2":
case "4":
case "11":
days = "?";
break;
case "3":
days = state.day.incrementStart + "/" + state.day.incrementIncrement;
break;
case "5":
state.day.specificSpecific.map((val) => {
days += val + ",";
});
days = days.slice(0, -1);
break;
case "6":
days = "L";
break;
case "7":
days = "LW";
break;
case "8":
days = state.day.cronLastSpecificDomDay + "L";
break;
case "9":
days = "L-" + state.day.cronDaysBeforeEomMinus;
break;
case "10":
days = state.day.cronDaysNearestWeekday + "W";
break;
}
return days;
}),
weeksText: computed(() => {
let weeks = "";
let cronEvery = state.day.cronEvery;
switch (cronEvery?.toString()) {
case "1":
case "3":
case "5":
weeks = "?";
break;
case "2":
weeks = state.week.incrementStart + "/" + state.week.incrementIncrement;
break;
case "4":
state.week.specificSpecific.map((val) => {
weeks += val + ",";
});
weeks = weeks.slice(0, -1);
break;
case "6":
case "7":
case "8":
case "9":
case "10":
weeks = "?";
break;
case "11":
weeks = state.week.cronNthDayDay + "#" + state.week.cronNthDayNth;
break;
}
return weeks;
}),
monthsText: computed(() => {
let months = "";
let cronEvery = state.month.cronEvery;
switch (cronEvery?.toString()) {
case "1":
months = "*";
break;
case "2":
months = state.month.incrementStart + "/" + state.month.incrementIncrement;
break;
case "3":
state.month.specificSpecific.map((val) => {
months += val + ",";
});
months = months.slice(0, -1);
break;
case "4":
months = state.month.rangeStart + "-" + state.month.rangeEnd;
break;
}
return months;
}),
yearsText: computed(() => {
let years = "";
// TODO,目前先不指定年份,注释以下代码
let cronEvery = state.year.cronEvery;
switch (cronEvery?.toString()) {
case "1":
years = "*";
break;
case "2":
years = state.year.incrementStart + "/" + state.year.incrementIncrement;
break;
case "3":
state.year.specificSpecific.map((val) => {
years += val + ",";
});
years = years.slice(0, -1);
break;
case "4":
years = state.year.rangeStart + "-" + state.year.rangeEnd;
break;
}
return years;
}),
cron: computed(() => {
// TODO,目前不指定年份,取消掉${state.yearsText}
// const cronText = `${state.secondsText || "*"} ${state.minutesText || "*"} ${state.hoursText || "*"} ${state.daysText || "*"} ${state.monthsText || "*"} ${state.weeksText || "?"} ${state.yearsText || "*"}`;
const cronText = `${state.secondsText || "*"} ${state.minutesText || "*"} ${state.hoursText || "*"} ${state.daysText || "*"} ${state.monthsText || "*"} ${state.weeksText || "?"}`;
// console.log('----', cronText,[state.minute.cronEvery, state.hour.cronEvery, state.day.cronEvery, state.month.cronEvery])
const cronArr = cronText.split(' ');
console.log('表达式:', cronText, cronArr)
if (state.minute.cronEvery == '3' && cronArr[1] == '*') { //选择的是具体分钟数,下拉框却没选择数值
errArr[0] = '勾选具体分钟数(可多选)时,请在下拉框中选择值';
} else {
errArr[0] = '';
} if (state.hour.cronEvery == '3' && cronArr[2] == '*') { //选择的是具体小时数,下拉框却没选择数值
errArr[1] = '勾选具体小时数(可多选)时,请在下拉框中选择值';
} else {
errArr[1] = '';
} if (state.day.cronEvery == '4' && cronArr[5] == '?') { //选择的是具体星期几,下拉框却没选择数值
errArr[2] = '勾选具体星期几(可多选)时,请在下拉框中选择值';
} else if (state.day.cronEvery == '5' && cronArr[3] == '*') { //选择的是具体天数,下拉框却没选择数值
errArr[2] = '勾选具体天数(可多选)时,请在下拉框中选择值';
} else {
errArr[2] = '';
} if (state.month.cronEvery == '3' && cronArr[4] == '*') { //选择的是具体月数,下拉框却没选择数值
errArr[3] = '勾选具体月数(可多选)时,请在下拉框中选择值';
} else {
errArr[3] = '';
}
emits("onShowError", errArr);
return cronText;
}),
}); const handleChange = () => {
if (typeof state.cron !== "string") return false;
emits("change", state.cron, [state.min.cronEvery, state.hour.cronEvery, state.day.cronEvery, state.month.cronEvery]);
};
const rest = (data) => {
for (let i in data) {
if (data[i] instanceof Object) {
this.rest(data[i]);
} else {
switch (typeof data[i]) {
case "object":
data[i] = [];
break;
case "string":
data[i] = "";
break;
}
}
}
}; watch(
() => state.cron,
(value) => {
if (typeof state.cron !== "string") return;
emits("update:value", value);
}
); </script> <style lang="css" scoped>
:deep(.el-input-number) {
width: 80px;
margin-right: 5px;
} :deep(.el-radio) {
margin-right: 10px;
} .v3c {
width: auto;
border: 1px solid #f5f7fa;
} .v3c-tab {
padding: 0;
list-style: none;
margin: 0;
background-color: #f5f7fa;
display: flex;
} .v3c-tab-item {
flex: 1;
text-align: center;
cursor: pointer;
padding: 6px;
} .v3c-tab-item.v3c-active {
background-color: #409eff;
color: #ffffff;
} .v3c-lang-btn {
background-color: #61ddaa;
color: #ffffff;
/* border-radius: 10px; */
} .v3c-content {
padding: 20px;
max-height: v-bind(maxHeight);
overflow: hidden;
overflow-y: auto;
} .p-20 {
padding: 20px;
} .v3c-footer {
background-color: #f5f7fa;
padding-top: 10px;
padding-bottom: 10px;
display: flex;
text-align: center;
} .v3c input[type="text"] {
width: 80px;
} .v3c input[type="number"] {
width: 80px;
height: 28px;
border: 1px solid #d9d9d9;
} .v3c select {
width: 80px;
height: 32px;
border: 1px solid #d9d9d9;
} .v3c select[multiple] {
width: 80px;
height: 100px;
border: 1px solid #d9d9d9;
} .btn-ok {
line-height: 1.5715;
position: relative;
display: inline-block;
font-weight: 400;
white-space: nowrap;
text-align: center;
background-image: none;
border: 1px solid transparent;
box-shadow: 0 2px #00000004;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
touch-action: manipulation;
height: 32px;
padding: 4px 15px;
font-size: 14px;
border-radius: 2px; color: #fff;
background: #409eff;
border-color: #409eff;
text-shadow: 0 -1px 0 rgb(0 0 0 / 12%);
box-shadow: 0 2px #0000000b;
} .btn-close {
line-height: 1.5715;
position: relative;
display: inline-block;
font-weight: 400;
white-space: nowrap;
text-align: center;
background-image: none;
border: 1px solid transparent;
box-shadow: 0 2px #00000004;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
touch-action: manipulation;
height: 32px;
padding: 4px 15px;
font-size: 14px;
border-radius: 2px; color: #fff;
background: #61ddaa;
border-color: #61ddaa;
text-shadow: 0 -1px 0 rgb(0 0 0 / 12%);
box-shadow: 0 2px #0000000b;
} .cron {
background-color: #61ddaa;
padding: 5px;
padding-left: 10px;
padding-right: 10px;
color: #ffffff;
}
</style>

2、根据cron表达式获取最近5次的执行时间

由于需要根据cron表达式获取最近5次执行时间,所以从网上找到了别人写的一个插件,我没有做改造,首先下载了这个插件(later.min.js)后,然后把它放置到项目里,最后在项目根目录的index.html使用script标签引入该js文件

later.min.js:

var later = function() {
"use strict";
var e = {
version: "1.2.0"
};
return Array.prototype.indexOf || (Array.prototype.indexOf = function(e) {
if (null == this)
throw new TypeError;
var t = Object(this)
, n = t.length >>> 0;
if (0 === n)
return -1;
var r = 0;
if (arguments.length > 1 && (r = Number(arguments[1]),
r != r ? r = 0 : 0 != r && r != 1 / 0 && r != -(1 / 0) && (r = (r > 0 || -1) * Math.floor(Math.abs(r)))),
r >= n)
return -1;
for (var a = r >= 0 ? r : Math.max(n - Math.abs(r), 0); n > a; a++)
if (a in t && t[a] === e)
return a;
return -1
}
),
String.prototype.trim || (String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, "")
}
),
e.array = {},
e.array.sort = function(e, t) {
e.sort(function(e, t) {
return +e - +t
}),
t && 0 === e[0] && e.push(e.shift())
}
,
e.array.next = function(e, t, n) {
for (var r, a = 0 !== n[0], i = 0, u = t.length - 1; u > -1; --u) {
if (r = t[u],
r === e)
return r;
if (!(r > e || 0 === r && a && n[1] > e))
break;
i = u
}
return t[i]
}
,
e.array.nextInvalid = function(e, t, n) {
for (var r = n[0], a = n[1], i = t.length, u = 0 === t[i - 1] && 0 !== r ? a : 0, o = e, f = t.indexOf(e), d = o; o === (t[f] || u); )
if (o++,
o > a && (o = r),
f++,
f === i && (f = 0),
o === d)
return;
return o
}
,
e.array.prev = function(e, t, n) {
for (var r, a = t.length, i = 0 !== n[0], u = a - 1, o = 0; a > o; o++) {
if (r = t[o],
r === e)
return r;
if (!(e > r || 0 === r && i && n[1] < e))
break;
u = o
}
return t[u]
}
,
e.array.prevInvalid = function(e, t, n) {
for (var r = n[0], a = n[1], i = t.length, u = 0 === t[i - 1] && 0 !== r ? a : 0, o = e, f = t.indexOf(e), d = o; o === (t[f] || u); )
if (o--,
r > o && (o = a),
f--,
-1 === f && (f = i - 1),
o === d)
return;
return o
}
,
e.day = e.D = {
name: "day",
range: 86400,
val: function(t) {
return t.D || (t.D = e.date.getDate.call(t))
},
isValid: function(t, n) {
return e.D.val(t) === (n || e.D.extent(t)[1])
},
extent: function(t) {
if (t.DExtent)
return t.DExtent;
var n = e.M.val(t)
, r = e.DAYS_IN_MONTH[n - 1];
return 2 === n && 366 === e.dy.extent(t)[1] && (r += 1),
t.DExtent = [1, r]
},
start: function(t) {
return t.DStart || (t.DStart = e.date.next(e.Y.val(t), e.M.val(t), e.D.val(t)))
},
end: function(t) {
return t.DEnd || (t.DEnd = e.date.prev(e.Y.val(t), e.M.val(t), e.D.val(t)))
},
next: function(t, n) {
n = n > e.D.extent(t)[1] ? 1 : n;
var r = e.date.nextRollover(t, n, e.D, e.M)
, a = e.D.extent(r)[1];
return n = n > a ? 1 : n || a,
e.date.next(e.Y.val(r), e.M.val(r), n)
},
prev: function(t, n) {
var r = e.date.prevRollover(t, n, e.D, e.M)
, a = e.D.extent(r)[1];
return e.date.prev(e.Y.val(r), e.M.val(r), n > a ? a : n || a)
}
},
e.dayOfWeekCount = e.dc = {
name: "day of week count",
range: 604800,
val: function(t) {
return t.dc || (t.dc = Math.floor((e.D.val(t) - 1) / 7) + 1)
},
isValid: function(t, n) {
return e.dc.val(t) === n || 0 === n && e.D.val(t) > e.D.extent(t)[1] - 7
},
extent: function(t) {
return t.dcExtent || (t.dcExtent = [1, Math.ceil(e.D.extent(t)[1] / 7)])
},
start: function(t) {
return t.dcStart || (t.dcStart = e.date.next(e.Y.val(t), e.M.val(t), Math.max(1, 7 * (e.dc.val(t) - 1) + 1 || 1)))
},
end: function(t) {
return t.dcEnd || (t.dcEnd = e.date.prev(e.Y.val(t), e.M.val(t), Math.min(7 * e.dc.val(t), e.D.extent(t)[1])))
},
next: function(t, n) {
n = n > e.dc.extent(t)[1] ? 1 : n;
var r = e.date.nextRollover(t, n, e.dc, e.M)
, a = e.dc.extent(r)[1];
n = n > a ? 1 : n;
var i = e.date.next(e.Y.val(r), e.M.val(r), 0 === n ? e.D.extent(r)[1] - 6 : 1 + 7 * (n - 1));
return i.getTime() <= t.getTime() ? (r = e.M.next(t, e.M.val(t) + 1),
e.date.next(e.Y.val(r), e.M.val(r), 0 === n ? e.D.extent(r)[1] - 6 : 1 + 7 * (n - 1))) : i
},
prev: function(t, n) {
var r = e.date.prevRollover(t, n, e.dc, e.M)
, a = e.dc.extent(r)[1];
return n = n > a ? a : n || a,
e.dc.end(e.date.prev(e.Y.val(r), e.M.val(r), 1 + 7 * (n - 1)))
}
},
e.dayOfWeek = e.dw = e.d = {
name: "day of week",
range: 86400,
val: function(t) {
return t.dw || (t.dw = e.date.getDay.call(t) + 1)
},
isValid: function(t, n) {
return e.dw.val(t) === (n || 7)
},
extent: function() {
return [1, 7]
},
start: function(t) {
return e.D.start(t)
},
end: function(t) {
return e.D.end(t)
},
next: function(t, n) {
return n = n > 7 ? 1 : n || 7,
e.date.next(e.Y.val(t), e.M.val(t), e.D.val(t) + (n - e.dw.val(t)) + (n <= e.dw.val(t) ? 7 : 0))
},
prev: function(t, n) {
return n = n > 7 ? 7 : n || 7,
e.date.prev(e.Y.val(t), e.M.val(t), e.D.val(t) + (n - e.dw.val(t)) + (n >= e.dw.val(t) ? -7 : 0))
}
},
e.dayOfYear = e.dy = {
name: "day of year",
range: 86400,
val: function(t) {
return t.dy || (t.dy = Math.ceil(1 + (e.D.start(t).getTime() - e.Y.start(t).getTime()) / e.DAY))
},
isValid: function(t, n) {
return e.dy.val(t) === (n || e.dy.extent(t)[1])
},
extent: function(t) {
var n = e.Y.val(t);
return t.dyExtent || (t.dyExtent = [1, n % 4 ? 365 : 366])
},
start: function(t) {
return e.D.start(t)
},
end: function(t) {
return e.D.end(t)
},
next: function(t, n) {
n = n > e.dy.extent(t)[1] ? 1 : n;
var r = e.date.nextRollover(t, n, e.dy, e.Y)
, a = e.dy.extent(r)[1];
return n = n > a ? 1 : n || a,
e.date.next(e.Y.val(r), e.M.val(r), n)
},
prev: function(t, n) {
var r = e.date.prevRollover(t, n, e.dy, e.Y)
, a = e.dy.extent(r)[1];
return n = n > a ? a : n || a,
e.date.prev(e.Y.val(r), e.M.val(r), n)
}
},
e.hour = e.h = {
name: "hour",
range: 3600,
val: function(t) {
return t.h || (t.h = e.date.getHour.call(t))
},
isValid: function(t, n) {
return e.h.val(t) === n
},
extent: function() {
return [0, 23]
},
start: function(t) {
return t.hStart || (t.hStart = e.date.next(e.Y.val(t), e.M.val(t), e.D.val(t), e.h.val(t)))
},
end: function(t) {
return t.hEnd || (t.hEnd = e.date.prev(e.Y.val(t), e.M.val(t), e.D.val(t), e.h.val(t)))
},
next: function(t, n) {
n = n > 23 ? 0 : n;
var r = e.date.next(e.Y.val(t), e.M.val(t), e.D.val(t) + (n <= e.h.val(t) ? 1 : 0), n);
return !e.date.isUTC && r.getTime() <= t.getTime() && (r = e.date.next(e.Y.val(r), e.M.val(r), e.D.val(r), n + 1)),
r
},
prev: function(t, n) {
return n = n > 23 ? 23 : n,
e.date.prev(e.Y.val(t), e.M.val(t), e.D.val(t) + (n >= e.h.val(t) ? -1 : 0), n)
}
},
e.minute = e.m = {
name: "minute",
range: 60,
val: function(t) {
return t.m || (t.m = e.date.getMin.call(t))
},
isValid: function(t, n) {
return e.m.val(t) === n
},
extent: function(e) {
return [0, 59]
},
start: function(t) {
return t.mStart || (t.mStart = e.date.next(e.Y.val(t), e.M.val(t), e.D.val(t), e.h.val(t), e.m.val(t)))
},
end: function(t) {
return t.mEnd || (t.mEnd = e.date.prev(e.Y.val(t), e.M.val(t), e.D.val(t), e.h.val(t), e.m.val(t)))
},
next: function(t, n) {
var r = e.m.val(t)
, a = e.s.val(t)
, i = n > 59 ? 60 - r : r >= n ? 60 - r + n : n - r
, u = new Date(t.getTime() + i * e.MIN - a * e.SEC);
return !e.date.isUTC && u.getTime() <= t.getTime() && (u = new Date(t.getTime() + (i + 120) * e.MIN - a * e.SEC)),
u
},
prev: function(t, n) {
return n = n > 59 ? 59 : n,
e.date.prev(e.Y.val(t), e.M.val(t), e.D.val(t), e.h.val(t) + (n >= e.m.val(t) ? -1 : 0), n)
}
},
e.month = e.M = {
name: "month",
range: 2629740,
val: function(t) {
return t.M || (t.M = e.date.getMonth.call(t) + 1)
},
isValid: function(t, n) {
return e.M.val(t) === (n || 12)
},
extent: function() {
return [1, 12]
},
start: function(t) {
return t.MStart || (t.MStart = e.date.next(e.Y.val(t), e.M.val(t)))
},
end: function(t) {
return t.MEnd || (t.MEnd = e.date.prev(e.Y.val(t), e.M.val(t)))
},
next: function(t, n) {
return n = n > 12 ? 1 : n || 12,
e.date.next(e.Y.val(t) + (n > e.M.val(t) ? 0 : 1), n)
},
prev: function(t, n) {
return n = n > 12 ? 12 : n || 12,
e.date.prev(e.Y.val(t) - (n >= e.M.val(t) ? 1 : 0), n)
}
},
e.second = e.s = {
name: "second",
range: 1,
val: function(t) {
return t.s || (t.s = e.date.getSec.call(t))
},
isValid: function(t, n) {
return e.s.val(t) === n
},
extent: function() {
return [0, 59]
},
start: function(e) {
return e
},
end: function(e) {
return e
},
next: function(t, n) {
var r = e.s.val(t)
, a = n > 59 ? 60 - r : r >= n ? 60 - r + n : n - r
, i = new Date(t.getTime() + a * e.SEC);
return !e.date.isUTC && i.getTime() <= t.getTime() && (i = new Date(t.getTime() + (a + 7200) * e.SEC)),
i
},
prev: function(t, n, r) {
return n = n > 59 ? 59 : n,
e.date.prev(e.Y.val(t), e.M.val(t), e.D.val(t), e.h.val(t), e.m.val(t) + (n >= e.s.val(t) ? -1 : 0), n)
}
},
e.time = e.t = {
name: "time",
range: 1,
val: function(t) {
return t.t || (t.t = 3600 * e.h.val(t) + 60 * e.m.val(t) + e.s.val(t))
},
isValid: function(t, n) {
return e.t.val(t) === n
},
extent: function() {
return [0, 86399]
},
start: function(e) {
return e
},
end: function(e) {
return e
},
next: function(t, n) {
n = n > 86399 ? 0 : n;
var r = e.date.next(e.Y.val(t), e.M.val(t), e.D.val(t) + (n <= e.t.val(t) ? 1 : 0), 0, 0, n);
return !e.date.isUTC && r.getTime() < t.getTime() && (r = e.date.next(e.Y.val(r), e.M.val(r), e.D.val(r), e.h.val(r), e.m.val(r), n + 7200)),
r
},
prev: function(t, n) {
return n = n > 86399 ? 86399 : n,
e.date.next(e.Y.val(t), e.M.val(t), e.D.val(t) + (n >= e.t.val(t) ? -1 : 0), 0, 0, n)
}
},
e.weekOfMonth = e.wm = {
name: "week of month",
range: 604800,
val: function(t) {
return t.wm || (t.wm = (e.D.val(t) + (e.dw.val(e.M.start(t)) - 1) + (7 - e.dw.val(t))) / 7)
},
isValid: function(t, n) {
return e.wm.val(t) === (n || e.wm.extent(t)[1])
},
extent: function(t) {
return t.wmExtent || (t.wmExtent = [1, (e.D.extent(t)[1] + (e.dw.val(e.M.start(t)) - 1) + (7 - e.dw.val(e.M.end(t)))) / 7])
},
start: function(t) {
return t.wmStart || (t.wmStart = e.date.next(e.Y.val(t), e.M.val(t), Math.max(e.D.val(t) - e.dw.val(t) + 1, 1)))
},
end: function(t) {
return t.wmEnd || (t.wmEnd = e.date.prev(e.Y.val(t), e.M.val(t), Math.min(e.D.val(t) + (7 - e.dw.val(t)), e.D.extent(t)[1])))
},
next: function(t, n) {
n = n > e.wm.extent(t)[1] ? 1 : n;
var r = e.date.nextRollover(t, n, e.wm, e.M)
, a = e.wm.extent(r)[1];
return n = n > a ? 1 : n || a,
e.date.next(e.Y.val(r), e.M.val(r), Math.max(1, 7 * (n - 1) - (e.dw.val(r) - 2)))
},
prev: function(t, n) {
var r = e.date.prevRollover(t, n, e.wm, e.M)
, a = e.wm.extent(r)[1];
return n = n > a ? a : n || a,
e.wm.end(e.date.next(e.Y.val(r), e.M.val(r), Math.max(1, 7 * (n - 1) - (e.dw.val(r) - 2))))
}
},
e.weekOfYear = e.wy = {
name: "week of year (ISO)",
range: 604800,
val: function(t) {
if (t.wy)
return t.wy;
var n = e.dw.next(e.wy.start(t), 5)
, r = e.dw.next(e.Y.prev(n, e.Y.val(n) - 1), 5);
return t.wy = 1 + Math.ceil((n.getTime() - r.getTime()) / e.WEEK)
},
isValid: function(t, n) {
return e.wy.val(t) === (n || e.wy.extent(t)[1])
},
extent: function(t) {
if (t.wyExtent)
return t.wyExtent;
var n = e.dw.next(e.wy.start(t), 5)
, r = e.dw.val(e.Y.start(n))
, a = e.dw.val(e.Y.end(n));
return t.wyExtent = [1, 5 === r || 5 === a ? 53 : 52]
},
start: function(t) {
return t.wyStart || (t.wyStart = e.date.next(e.Y.val(t), e.M.val(t), e.D.val(t) - (e.dw.val(t) > 1 ? e.dw.val(t) - 2 : 6)))
},
end: function(t) {
return t.wyEnd || (t.wyEnd = e.date.prev(e.Y.val(t), e.M.val(t), e.D.val(t) + (e.dw.val(t) > 1 ? 8 - e.dw.val(t) : 0)))
},
next: function(t, n) {
n = n > e.wy.extent(t)[1] ? 1 : n;
var r = e.dw.next(e.wy.start(t), 5)
, a = e.date.nextRollover(r, n, e.wy, e.Y);
1 !== e.wy.val(a) && (a = e.dw.next(a, 2));
var i = e.wy.extent(a)[1]
, u = e.wy.start(a);
return n = n > i ? 1 : n || i,
e.date.next(e.Y.val(u), e.M.val(u), e.D.val(u) + 7 * (n - 1))
},
prev: function(t, n) {
var r = e.dw.next(e.wy.start(t), 5)
, a = e.date.prevRollover(r, n, e.wy, e.Y);
1 !== e.wy.val(a) && (a = e.dw.next(a, 2));
var i = e.wy.extent(a)[1]
, u = e.wy.end(a);
return n = n > i ? i : n || i,
e.wy.end(e.date.next(e.Y.val(u), e.M.val(u), e.D.val(u) + 7 * (n - 1)))
}
},
e.year = e.Y = {
name: "year",
range: 31556900,
val: function(t) {
return t.Y || (t.Y = e.date.getYear.call(t))
},
isValid: function(t, n) {
return e.Y.val(t) === n
},
extent: function() {
return [1970, 2099]
},
start: function(t) {
return t.YStart || (t.YStart = e.date.next(e.Y.val(t)))
},
end: function(t) {
return t.YEnd || (t.YEnd = e.date.prev(e.Y.val(t)))
},
next: function(t, n) {
return n > e.Y.val(t) && n <= e.Y.extent()[1] ? e.date.next(n) : e.NEVER
},
prev: function(t, n) {
return n < e.Y.val(t) && n >= e.Y.extent()[0] ? e.date.prev(n) : e.NEVER
}
},
e.fullDate = e.fd = {
name: "full date",
range: 1,
val: function(e) {
return e.fd || (e.fd = e.getTime())
},
isValid: function(t, n) {
return e.fd.val(t) === n
},
extent: function() {
return [0, 3250368e7]
},
start: function(e) {
return e
},
end: function(e) {
return e
},
next: function(t, n) {
return e.fd.val(t) < n ? new Date(n) : e.NEVER
},
prev: function(t, n) {
return e.fd.val(t) > n ? new Date(n) : e.NEVER
}
},
e.modifier = {},
e.modifier.after = e.modifier.a = function(e, t) {
var n = t[0];
return {
name: "after " + e.name,
range: (e.extent(new Date)[1] - n) * e.range,
val: e.val,
isValid: function(e, t) {
return this.val(e) >= n
},
extent: e.extent,
start: e.start,
end: e.end,
next: function(t, r) {
return r != n && (r = e.extent(t)[0]),
e.next(t, r)
},
prev: function(t, r) {
return r = r === n ? e.extent(t)[1] : n - 1,
e.prev(t, r)
}
}
}
,
e.modifier.before = e.modifier.b = function(e, t) {
var n = t[t.length - 1];
return {
name: "before " + e.name,
range: e.range * (n - 1),
val: e.val,
isValid: function(e, t) {
return this.val(e) < n
},
extent: e.extent,
start: e.start,
end: e.end,
next: function(t, r) {
return r = r === n ? e.extent(t)[0] : n,
e.next(t, r)
},
prev: function(t, r) {
return r = r === n ? n - 1 : e.extent(t)[1],
e.prev(t, r)
}
}
}
,
e.compile = function(t) {
function n(e) {
return "next" === e ? function(e, t) {
return e.getTime() > t.getTime()
}
: function(e, t) {
return t.getTime() > e.getTime()
}
}
var r, a = [], i = 0;
for (var u in t) {
var o = u.split("_")
, f = o[0]
, d = o[1]
, v = t[u]
, l = d ? e.modifier[d](e[f], v) : e[f];
a.push({
constraint: l,
vals: v
}),
i++
}
return a.sort(function(e, t) {
var n = e.constraint.range
, r = t.constraint.range;
return n > r ? -1 : r > n ? 1 : 0
}),
r = a[i - 1].constraint,
{
start: function(t, n) {
for (var u, o = n, f = e.array[t], d = 1e3; d-- && !u && o; ) {
u = !0;
for (var v = 0; i > v; v++) {
var l = a[v].constraint
, c = l.val(o)
, s = l.extent(o)
, m = f(c, a[v].vals, s);
if (!l.isValid(o, m)) {
o = l[t](o, m),
u = !1;
break
}
}
}
return o !== e.NEVER && (o = "next" === t ? r.start(o) : r.end(o)),
o
},
end: function(t, r) {
for (var u, o = e.array[t + "Invalid"], f = n(t), d = i - 1; d >= 0; d--) {
var v, l = a[d].constraint, c = l.val(r), s = l.extent(r), m = o(c, a[d].vals, s);
void 0 !== m && (v = l[t](r, m),
!v || u && !f(u, v) || (u = v))
}
return u
},
tick: function(t, n) {
return new Date("next" === t ? r.end(n).getTime() + e.SEC : r.start(n).getTime() - e.SEC)
},
tickStart: function(e) {
return r.start(e)
}
}
}
,
e.schedule = function(t) {
function n(t, n, x, g, p) {
var D, M, b, Y = s(t), k = n, E = 1e3, T = [], O = [], S = [], N = "next" === t, R = N ? 0 : 1, C = N ? 1 : 0;
if (x = x ? new Date(x) : new Date,
!x || !x.getTime())
throw new Error("Invalid start date.");
for (a(t, h, T, x),
u(t, w, O, x); E-- && k && (D = m(T, Y)) && (!g || !Y(D, g)); )
if (y && (o(t, w, O, D),
M = v(t, O, D)))
i(t, h, T, M);
else {
if (p) {
var V = l(O, Y);
M = c(t, h, T, D, V);
var I = N ? [new Date(Math.max(x, D)), M ? new Date(g ? Math.min(M, g) : M) : void 0] : [M ? new Date(g ? Math.max(g, M.getTime() + e.SEC) : M.getTime() + e.SEC) : void 0, new Date(Math.min(x, D.getTime() + e.SEC))];
if (b && I[R].getTime() === b[C].getTime() ? (b[C] = I[C],
k++) : (b = I,
S.push(b)),
!M)
break;
i(t, h, T, M)
} else
S.push(N ? new Date(Math.max(x, D)) : d(h, T, D, g)),
f(t, h, T, D);
k--
}
for (var U = 0, A = S.length; A > U; U++) {
var W = S[U];
S[U] = "[object Array]" === Object.prototype.toString.call(W) ? [r(W[0]), r(W[1])] : r(W)
}
return 0 === S.length ? e.NEVER : 1 === n ? S[0] : S
}
function r(e) {
return e instanceof Date && !isNaN(e.valueOf()) ? new Date(e) : void 0
}
function a(e, t, n, r) {
for (var a = 0, i = t.length; i > a; a++)
n[a] = t[a].start(e, r)
}
function i(e, t, n, r) {
for (var a = s(e), i = 0, u = t.length; u > i; i++)
n[i] && !a(n[i], r) && (n[i] = t[i].start(e, r))
}
function u(t, n, r, a) {
for (var i = (s(t),
0), u = n.length; u > i; i++) {
var o = n[i].start(t, a);
o ? r[i] = [o, n[i].end(t, o)] : r[i] = e.NEVER
}
}
function o(t, n, r, a) {
for (var i = s(t), u = 0, o = n.length; o > u; u++)
if (r[u] && !i(r[u][0], a)) {
var f = n[u].start(t, a);
f ? r[u] = [f, n[u].end(t, f)] : r[u] = e.NEVER
}
}
function f(e, t, n, r) {
for (var a = 0, i = t.length; i > a; a++)
n[a] && n[a].getTime() === r.getTime() && (n[a] = t[a].start(e, t[a].tick(e, r)))
}
function d(e, t, n, r) {
for (var a, i = 0, u = t.length; u > i; i++)
if (t[i] && t[i].getTime() === n.getTime()) {
var o = e[i].tickStart(n);
if (r && r > o)
return r;
(!a || o > a) && (a = o)
}
return a
}
function v(e, t, n) {
for (var r, a = s(e), i = 0, u = t.length; u > i; i++) {
var o = t[i];
!o || a(o[0], n) || o[1] && !a(o[1], n) || (!r || a(o[1], r)) && (r = o[1])
}
return r
}
function l(e, t) {
for (var n, r = 0, a = e.length; a > r; r++)
!e[r] || n && !t(n, e[r][0]) || (n = e[r][0]);
return n
}
function c(e, t, n, r, a) {
for (var i, u = s(e), o = 0, f = t.length; f > o; o++) {
var d = n[o];
if (d && d.getTime() === r.getTime()) {
var v = t[o].end(e, d);
if (a && (!v || u(v, a)))
return a;
(!i || u(v, i)) && (i = v)
}
}
return i
}
function s(e) {
return "next" === e ? function(e, t) {
return !t || e.getTime() > t.getTime()
}
: function(e, t) {
return !e || t.getTime() > e.getTime()
}
}
function m(e, t) {
for (var n = e[0], r = 1, a = e.length; a > r; r++)
e[r] && t(n, e[r]) && (n = e[r]);
return n
}
if (!t)
throw new Error("Missing schedule definition.");
if (!t.schedules)
throw new Error("Definition must include at least one schedule.");
for (var h = [], x = t.schedules.length, w = [], y = t.exceptions ? t.exceptions.length : 0, g = 0; x > g; g++)
h.push(e.compile(t.schedules[g]));
for (var p = 0; y > p; p++)
w.push(e.compile(t.exceptions[p]));
return {
isValid: function(t) {
return n("next", 1, t, t) !== e.NEVER
},
next: function(e, t, r) {
return n("next", e || 1, t, r)
},
prev: function(e, t, r) {
return n("prev", e || 1, t, r)
},
nextRange: function(e, t, r) {
return n("next", e || 1, t, r, !0)
},
prevRange: function(e, t, r) {
return n("prev", e || 1, t, r, !0)
}
}
}
,
e.setTimeout = function(t, n) {
function r() {
var e = Date.now()
, n = i.next(2, e);
if (!n[0])
return void (a = void 0);
var u = n[0].getTime() - e;
1e3 > u && (u = n[1] ? n[1].getTime() - e : 1e3),
a = 2147483647 > u ? setTimeout(t, u) : setTimeout(r, 2147483647)
}
var a, i = e.schedule(n);
return t && r(),
{
isDone: function() {
return !a
},
clear: function() {
clearTimeout(a)
}
}
}
,
e.setInterval = function(t, n) {
function r() {
i || (t(),
a = e.setTimeout(r, n))
}
if (t) {
var a = e.setTimeout(r, n)
, i = a.isDone();
return {
isDone: function() {
return a.isDone()
},
clear: function() {
i = !0,
a.clear()
}
}
}
}
,
e.date = {},
e.date.timezone = function(t) {
e.date.build = t ? function(e, t, n, r, a, i) {
return new Date(e,t,n,r,a,i)
}
: function(e, t, n, r, a, i) {
return new Date(Date.UTC(e, t, n, r, a, i))
}
;
var n = t ? "get" : "getUTC"
, r = Date.prototype;
e.date.getYear = r[n + "FullYear"],
e.date.getMonth = r[n + "Month"],
e.date.getDate = r[n + "Date"],
e.date.getDay = r[n + "Day"],
e.date.getHour = r[n + "Hours"],
e.date.getMin = r[n + "Minutes"],
e.date.getSec = r[n + "Seconds"],
e.date.isUTC = !t
}
,
e.date.UTC = function() {
e.date.timezone(!1)
}
,
e.date.localTime = function() {
e.date.timezone(!0)
}
,
e.date.UTC(),
e.SEC = 1e3,
e.MIN = 60 * e.SEC,
e.HOUR = 60 * e.MIN,
e.DAY = 24 * e.HOUR,
e.WEEK = 7 * e.DAY,
e.DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
e.NEVER = 0,
e.date.next = function(t, n, r, a, i, u) {
return e.date.build(t, void 0 !== n ? n - 1 : 0, void 0 !== r ? r : 1, a || 0, i || 0, u || 0)
}
,
e.date.nextRollover = function(t, n, r, a) {
var i = r.val(t)
, u = r.extent(t)[1];
return i >= (n || u) || n > u ? new Date(a.end(t).getTime() + e.SEC) : a.start(t)
}
,
e.date.prev = function(t, n, r, a, i, u) {
var o = arguments.length;
return n = 2 > o ? 11 : n - 1,
r = 3 > o ? e.D.extent(e.date.next(t, n + 1))[1] : r,
a = 4 > o ? 23 : a,
i = 5 > o ? 59 : i,
u = 6 > o ? 59 : u,
e.date.build(t, n, r, a, i, u)
}
,
e.date.prevRollover = function(e, t, n, r) {
var a = n.val(e);
return t >= a || !t ? r.start(r.prev(e, r.val(e) - 1)) : r.start(e)
}
,
e.parse = {},
e.parse.cron = function(e, t) {
function n(e, t, n) {
return isNaN(e) ? s[e] || null : Math.min(+e + (t || 0), n || 9999)
}
function r(e) {
var t, n = {};
for (t in e)
"dc" !== t && "d" !== t && (n[t] = e[t].slice(0));
return n
}
function a(e, t, n, r, a) {
var i = n;
for (e[t] || (e[t] = []); r >= i; )
e[t].indexOf(i) < 0 && e[t].push(i),
i += a || 1;
e[t].sort(function(e, t) {
return e - t
})
}
function i(e, t, n, i) {
(t.d && !t.dc || t.dc && t.dc.indexOf(i) < 0) && (e.push(r(t)),
t = e[e.length - 1]),
a(t, "d", n, n),
a(t, "dc", i, i)
}
function u(e, t, n) {
var r = {}
, i = {};
1 === n ? (a(t, "D", 1, 3),
a(t, "d", s.MON, s.FRI),
a(r, "D", 2, 2),
a(r, "d", s.TUE, s.FRI),
a(i, "D", 3, 3),
a(i, "d", s.TUE, s.FRI)) : (a(t, "D", n - 1, n + 1),
a(t, "d", s.MON, s.FRI),
a(r, "D", n - 1, n - 1),
a(r, "d", s.MON, s.THU),
a(i, "D", n + 1, n + 1),
a(i, "d", s.TUE, s.FRI)),
e.exceptions.push(r),
e.exceptions.push(i)
}
function o(e, t, r, i, u, o) {
var f = e.split("/")
, d = +f[1]
, v = f[0];
if ("*" !== v && "0" !== v) {
var l = v.split("-");
i = n(l[0], o, u),
u = n(l[1], o, u) || u
}
a(t, r, i, u, d)
}
function f(e, t, r, f, d, v) {
var l, c, s = t.schedules, m = s[s.length - 1];
"L" === e && (e = f - 1),
null !== (l = n(e, v, d)) ? a(m, r, l, l) : null !== (l = n(e.replace("W", ""), v, d)) ? u(t, m, l) : null !== (l = n(e.replace("L", ""), v, d)) ? i(s, m, l, f - 1) : 2 === (c = e.split("#")).length ? (l = n(c[0], v, d),
i(s, m, l, n(c[1]))) : o(e, m, r, f, d, v)
}
function d(e) {
return e.indexOf("#") > -1 || e.indexOf("L") > 0
}
function v(e, t) {
return d(e) && !d(t) ? 1 : e - t
}
function l(e) {
var t, n, r, a, i = {
schedules: [{}],
exceptions: []
}, u = e.replace(/(\s)+/g, " ").split(" ");
for (t in h)
if (n = h[t],
r = u[n[0]],
r && "*" !== r && "?" !== r) {
a = r.split(",").sort(v);
var o, d = a.length;
for (o = 0; d > o; o++)
f(a[o], i, t, n[1], n[2], n[3])
}
return i
}
function c(e) {
var t = e.toUpperCase();
return m[t] || t
}
var s = {
JAN: 1,
FEB: 2,
MAR: 3,
APR: 4,
MAY: 5,
JUN: 6,
JUL: 7,
AUG: 8,
SEP: 9,
OCT: 10,
NOV: 11,
DEC: 12,
SUN: 1,
MON: 2,
TUE: 3,
WED: 4,
THU: 5,
FRI: 6,
SAT: 7
}
, m = {
"* * * * * *": "0/1 * * * * *",
"@YEARLY": "0 0 1 1 *",
"@ANNUALLY": "0 0 1 1 *",
"@MONTHLY": "0 0 1 * *",
"@WEEKLY": "0 0 * * 0",
"@DAILY": "0 0 * * *",
"@HOURLY": "0 * * * *"
}
, h = {
s: [0, 0, 59],
m: [1, 0, 59],
h: [2, 0, 23],
D: [3, 1, 31],
M: [4, 1, 12],
Y: [6, 1970, 2099],
d: [5, 1, 7, 1]
}
, x = c(e);
return l(t ? x : "0 " + x)
}
,
e.parse.recur = function() {
function t(e, t, l) {
if (e = u ? e + "_" + u : e,
n || (s.push({}),
n = s[0]),
n[e] || (n[e] = []),
r = n[e],
i) {
for (a = [],
d = t; l >= d; d += i)
a.push(d);
v = {
n: e,
x: i,
c: r.length,
m: l
}
}
a = o ? [t] : f ? [l] : a;
var c = a.length;
for (d = 0; c > d; d += 1) {
var m = a[d];
r.indexOf(m) < 0 && r.push(m)
}
a = i = u = o = f = 0
}
var n, r, a, i, u, o, f, d, v, l = [], c = [], s = l;
return {
schedules: l,
exceptions: c,
on: function() {
return a = arguments[0]instanceof Array ? arguments[0] : arguments,
this
},
every: function(e) {
return i = e || 1,
this
},
after: function(e) {
return u = "a",
a = [e],
this
},
before: function(e) {
return u = "b",
a = [e],
this
},
first: function() {
return o = 1,
this
},
last: function() {
return f = 1,
this
},
time: function() {
for (var e = 0, n = a.length; n > e; e++) {
var r = a[e].split(":");
r.length < 3 && r.push(0),
a[e] = 3600 * +r[0] + 60 * +r[1] + +r[2]
}
return t("t"),
this
},
second: function() {
return t("s", 0, 59),
this
},
minute: function() {
return t("m", 0, 59),
this
},
hour: function() {
return t("h", 0, 23),
this
},
dayOfMonth: function() {
return t("D", 1, f ? 0 : 31),
this
},
dayOfWeek: function() {
return t("d", 1, 7),
this
},
onWeekend: function() {
return a = [1, 7],
this.dayOfWeek()
},
onWeekday: function() {
return a = [2, 3, 4, 5, 6],
this.dayOfWeek()
},
dayOfWeekCount: function() {
return t("dc", 1, f ? 0 : 5),
this
},
dayOfYear: function() {
return t("dy", 1, f ? 0 : 366),
this
},
weekOfMonth: function() {
return t("wm", 1, f ? 0 : 5),
this
},
weekOfYear: function() {
return t("wy", 1, f ? 0 : 53),
this
},
month: function() {
return t("M", 1, 12),
this
},
year: function() {
return t("Y", 1970, 2450),
this
},
fullDate: function() {
for (var e = 0, n = a.length; n > e; e++)
a[e] = a[e].getTime();
return t("fd"),
this
},
customModifier: function(t, n) {
var r = e.modifier[t];
if (!r)
throw new Error("Custom modifier " + t + " not recognized!");
return u = t,
a = arguments[1]instanceof Array ? arguments[1] : [arguments[1]],
this
},
customPeriod: function(n) {
var r = e[n];
if (!r)
throw new Error("Custom time period " + n + " not recognized!");
return t(n, r.extent(new Date)[0], r.extent(new Date)[1]),
this
},
startingOn: function(e) {
return this.between(e, v.m)
},
between: function(e, r) {
return n[v.n] = n[v.n].splice(0, v.c),
i = v.x,
t(v.n, e, r),
this
},
and: function() {
return n = s[s.push({}) - 1],
this
},
except: function() {
return s = c,
n = null,
this
}
}
}
,
e.parse.text = function(t) {
function n(e, t, n, r) {
return {
startPos: e,
endPos: t,
text: n,
type: r
}
}
function r(e) {
var t, r, a, i, u, o, f = e instanceof Array ? e : [e], d = /\s+/;
for (f.push(d),
u = w; !t || t.type === d; ) {
o = -1,
r = y.substring(u),
t = n(u, u, y.split(d)[0]);
var v, l = f.length;
for (v = 0; l > v; v++)
i = f[v],
a = i.exec(r),
a && 0 === a.index && a[0].length > o && (o = a[0].length,
t = n(u, u + o, r.substring(0, o), i));
t.type === d && (u = t.endPos)
}
return t
}
function a(e) {
var t = r(e);
return w = t.endPos,
t
}
function i(e) {
for (var t = +s(e), n = l(g.through) ? +s(e) : t, r = [], a = t; n >= a; a++)
r.push(a);
return r
}
function u(e) {
for (var t = i(e); l(g.and); )
t = t.concat(i(e));
return t
}
function o(e) {
var t, n, r, a;
l(g.weekend) ? e.on(p.sun, p.sat).dayOfWeek() : l(g.weekday) ? e.on(p.mon, p.tue, p.wed, p.thu, p.fri).dayOfWeek() : (t = s(g.rank),
e.every(t),
n = v(e),
l(g.start) ? (t = s(g.rank),
e.startingOn(t),
c(n.type)) : l(g.between) && (r = s(g.rank),
l(g.and) && (a = s(g.rank),
e.between(r, a))))
}
function f(e) {
l(g.first) ? e.first() : l(g.last) ? e.last() : e.on(u(g.rank)),
v(e)
}
function d(e) {
w = 0,
y = e,
h = -1;
for (var t = x(); w < y.length && 0 > h; ) {
var n = c([g.every, g.after, g.before, g.onthe, g.on, g.of, g["in"], g.at, g.and, g.except, g.also]);
switch (n.type) {
case g.every:
o(t);
break;
case g.after:
void 0 !== r(g.time).type ? (t.after(s(g.time)),
t.time()) : (t.after(s(g.rank)),
v(t));
break;
case g.before:
void 0 !== r(g.time).type ? (t.before(s(g.time)),
t.time()) : (t.before(s(g.rank)),
v(t));
break;
case g.onthe:
f(t);
break;
case g.on:
t.on(u(g.dayName)).dayOfWeek();
break;
case g.of:
t.on(u(g.monthName)).month();
break;
case g["in"]:
t.on(u(g.yearIndex)).year();
break;
case g.at:
for (t.on(s(g.time)).time(); l(g.and); )
t.on(s(g.time)).time();
break;
case g.and:
break;
case g.also:
t.and();
break;
case g.except:
t.except();
break;
default:
h = w
}
}
return {
schedules: t.schedules,
exceptions: t.exceptions,
error: h
}
}
function v(e) {
var t = c([g.second, g.minute, g.hour, g.dayOfYear, g.dayOfWeek, g.dayInstance, g.day, g.month, g.year, g.weekOfMonth, g.weekOfYear]);
switch (t.type) {
case g.second:
e.second();
break;
case g.minute:
e.minute();
break;
case g.hour:
e.hour();
break;
case g.dayOfYear:
e.dayOfYear();
break;
case g.dayOfWeek:
e.dayOfWeek();
break;
case g.dayInstance:
e.dayOfWeekCount();
break;
case g.day:
e.dayOfMonth();
break;
case g.weekOfMonth:
e.weekOfMonth();
break;
case g.weekOfYear:
e.weekOfYear();
break;
case g.month:
e.month();
break;
case g.year:
e.year();
break;
default:
h = w
}
return t
}
function l(e) {
var t = r(e).type === e;
return t && a(e),
t
}
function c(e) {
var t = a(e);
return t.type ? t.text = m(t.text, e) : h = w,
t
}
function s(e) {
return c(e).text
}
function m(e, t) {
var n = e;
switch (t) {
case g.time:
var r = e.split(/(:|am|pm)/)
, a = "pm" === r[3] && r[0] < 12 ? parseInt(r[0], 10) + 12 : r[0]
, i = r[2].trim();
n = (1 === a.length ? "0" : "") + a + ":" + i;
break;
case g.rank:
n = parseInt(/^\d+/.exec(e)[0], 10);
break;
case g.monthName:
case g.dayName:
n = p[e.substring(0, 3)]
}
return n
}
var h, x = e.parse.recur, w = 0, y = "", g = {
eof: /^$/,
rank: /^((\d+)(st|nd|rd|th)?)\b/,
time: /^((([0]?[1-9]|1[0-2]):[0-5]\d(\s)?(am|pm))|(([0]?\d|1\d|2[0-3]):[0-5]\d))\b/,
dayName: /^((sun|mon|tue(s)?|wed(nes)?|thu(r(s)?)?|fri|sat(ur)?)(day)?)\b/,
monthName: /^(jan(uary)?|feb(ruary)?|ma((r(ch)?)?|y)|apr(il)?|ju(ly|ne)|aug(ust)?|oct(ober)?|(sept|nov|dec)(ember)?)\b/,
yearIndex: /^(\d\d\d\d)\b/,
every: /^every\b/,
after: /^after\b/,
before: /^before\b/,
second: /^(s|sec(ond)?(s)?)\b/,
minute: /^(m|min(ute)?(s)?)\b/,
hour: /^(h|hour(s)?)\b/,
day: /^(day(s)?( of the month)?)\b/,
dayInstance: /^day instance\b/,
dayOfWeek: /^day(s)? of the week\b/,
dayOfYear: /^day(s)? of the year\b/,
weekOfYear: /^week(s)?( of the year)?\b/,
weekOfMonth: /^week(s)? of the month\b/,
weekday: /^weekday\b/,
weekend: /^weekend\b/,
month: /^month(s)?\b/,
year: /^year(s)?\b/,
between: /^between (the)?\b/,
start: /^(start(ing)? (at|on( the)?)?)\b/,
at: /^(at|@)\b/,
and: /^(,|and\b)/,
except: /^(except\b)/,
also: /(also)\b/,
first: /^(first)\b/,
last: /^last\b/,
"in": /^in\b/,
of: /^of\b/,
onthe: /^on the\b/,
on: /^on\b/,
through: /(-|^(to|through)\b)/
}, p = {
jan: 1,
feb: 2,
mar: 3,
apr: 4,
may: 5,
jun: 6,
jul: 7,
aug: 8,
sep: 9,
oct: 10,
nov: 11,
dec: 12,
sun: 1,
mon: 2,
tue: 3,
wed: 4,
thu: 5,
fri: 6,
sat: 7,
"1st": 1,
fir: 1,
"2nd": 2,
sec: 2,
"3rd": 3,
thi: 3,
"4th": 4,
"for": 4
};
return d(t.toLowerCase())
}
,
e
}();

3、业务代码中引入vue3Cron/Index.vue使用即可

<template>
<el-drawer :model-value="isShow" direction="rtl" :show-close="false" :destroy-on-close="true"
:close-on-click-modal="false" :title="!!curRecord ? '编辑触发器' : '创建触发器'" @open="onOpen" @closed="onCancel" size="500px">
<div class="pr-20">
<el-form class="edit-form" :model="formData" ref="formRef" :rules="rules" label-width="100px">
// 删除部分代码 -- START
     // 删除部分代码 -- END

<el-form-item label="cron表达式" prop="logicConfig">
<el-input v-model="formData.logicConfig" placeholder="请输入cron表达式">
<template #append>
<el-tooltip content="配置cron表达式" placement="top">
<el-button :icon="ArrowDown" @click="() => { isShowCronCore = !isShowCronCore }" />
</el-tooltip>
</template>
</el-input>
</el-form-item>
<div style="width:100%;padding-left: 10px;margin-top: -5px;" v-show="isShowCronCore">
<div v-if="formData.logicConfig.length > 0">
<Vue3Cron @change="changeCron" @onShowError="onShowError" v-model:value="formData.logicConfig"
:defaultCron="defaultCron" />
<div style="display:flex;">
<el-button type="primary" plain size="small" class="mt-10" @click="getRecentRunTime">最近5次运行时间</el-button>
<div style="width:150px;text-align: center;">
<p v-for="item in runTimeList" :key="item" class="mt-10">{{ item }}</p>
</div>
</div>
</div>
</div>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="onCancel">取 消</el-button>
<el-button type="primary" v-if="modalType != 'view'" :loading="submiting" @click="onSubmit">确 定</el-button>
</span>
</template>
</el-drawer>
</template>
<script setup>
import { ref, reactive } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { ArrowDown } from '@element-plus/icons-vue'
import { isValidCron } from 'cron-validator';
import cronParse from 'cron-parser';
import { regex, sexTypeList } from '@/common/constant';
import triggerApi from '@/api/triggerApi';
import Vue3Cron from "@/components/vue3Cron/Index.vue"; const sysUser = JSON.parse(sessionStorage.getItem('sysUser')); //定义子组件需要接收的值
const props = defineProps({
isShow: { type: Boolean, default: false }, //是否显示弹窗
curRecord: { type: Object, default: null }, // 当前条目
}); // 注册事件
const emits = defineEmits(["onClose"]); // 定义数据
const errList = ref(['', '', '', '']);
const defaultCron = "0 * * * * ?"; // 默认cron表达式
const isShowCronCore = ref(true); // 是否打开cron表达式配置框
const runTimeList = ref([]); // 最近5次运行时间
const submiting = ref(false); // 是否正在提交中
const formRef = ref(null);
const formData = reactive({ // 表单数据
logicConfig: '', // cron表达式(当触发逻辑=cron_express,填充cron配置,其它情况为空)(默认是每一分钟一次,不指定年份)
operatoruserId: sysUser.userId,
}); const changeCron = (cron, arr) => {
runTimeList.value = [];
if (typeof cron !== "string") return false;
formData.logicConfig = cron;
}; const onShowError = (errArr) => {
console.log('=====', errArr)
errList.value = errArr;
} const getRecentRunTime = () => {
runTimeList.value = [];
let cronText = formData.logicConfig;
if (cronText.trim() == '') {
ElMessage.warning('cron表达式为空');
} else {
cronText = cronText.trim().substring(2, 100)
var sched = later.parse.cron(cronText);
later.date.localTime();
var results = later.schedule(sched).next(5);
let list = [];
for (var i = 0; i < results.length; i++) {
list.push(results[i].toLocaleString());
}
runTimeList.value = list;
} } // 校验cron表达式
const validateCronExpression = (rule, value, callback) => {
if (value) {
try {
const interval = cronParse.parseExpression(value)
} catch (e) {
callback('cron表达式语法错误,请检查')
}
} else {
callback('执行表达式不能为空!')
}
callback()
} // 表单校验
const rules = {
name: [{ required: true, max: 20, whitespace: true, message: '名称不能为空且不能大于20个字符', trigger: 'blur' }],
description: [{ max: 100, whitespace: true, message: '描述不能大于100个字符', trigger: 'blur' },],
triggerLogic: [{ required: true, message: '请选择触发逻辑', trigger: 'blur' }],
logicConfig: [
{ required: true, whitespace: true, message: '请选择cron表达式', trigger: 'change' },
// { validator: validateCronExpression, trigger: ['blur'] }
],
} // 打开弹窗的回调
const onOpen = () => {
if (!!props.curRecord) { // 是编辑
for (let key in formData) {
if (key != 'roleIds') {
formData[key] = props.curRecord[key]
}
}
} else { // 是新增
formData.logicConfig = defaultCron;
}
}; // 点击取消按钮
const onCancel = () => {
submiting.value = false;
formRef.value.resetFields();
runTimeList.value = [];
emits("onClose", false);
}; const tips = (res) => {
submiting.value = false;
runTimeList.value = [];
if (res && res.code == 200) {
ElMessage.success(res.msg || '操作成功');
formRef.value.resetFields();
emits("onClose", true);
} else {
ElMessage.warning(res.msg || '操作失败');
}
} // 点击确定按钮
const onSubmit = () => {
runTimeList.value = [];
formRef.value.validate(valid => {
if (valid) {
if (errList.value.join('').length) {
console.log('有错误信息');
let html = '<div>';
errList.value.forEach(item => {
if (item) html += `<p>${item}</p>`;
})
html += '</div>';
console.log(html)
ElMessageBox.alert(
html,
'错误提示',
{
dangerouslyUseHTMLString: true,
type:'warning'
}
)
return;
}
submiting.value = true;
let params = { ...formData };
if (props.curRecord == null) { // 是新增
triggerApi.trigerAdd(params).then(res => {
tips(res);
})
} else { // 是编辑
params.id = props.curRecord.id;
triggerApi.trigerEdit(params).then(res => {
tips(res);
})
}
}
});
} </script>

4、效果

例如:勾选配置为:每天10:30执行一次,输入框显示的表达式如下

注:由于公司项目的需求,这里隐藏了秒和年的选项,天的选项里也注释了部分选项

附上cron表达式基本介绍:

1、Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:

  (1)、秒 分 时 日 月 周 年

  (2)、秒 分 时 日 月 周

corn从左到右(用空格隔开):秒 分 小时 月份中的日期 月份 星期中的日期 年份

二、各字段的含义

 
字段 允许值 允许的特殊字符
秒(Seconds) 0~59的整数 , - * /    四个字符
分(Minutes 0~59的整数 , - * /    四个字符
小时(Hours 0~23的整数 , - * /    四个字符
日期(DayofMonth 1~31的整数(但是你需要考虑你月的天数) ,- * ? / L W C     八个字符
月份(Month 1~12的整数或者 JAN-DEC , - * /    四个字符
星期(DayofWeek 1~7的整数或者 SUN-SAT (1=SUN) , - * ? / L C #     八个字符
年(可选,留空)(Year 1970~2099 , - * /    四个字符

注意事项:

  每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是:

  (1)*:表示匹配该域的任意值。假如在Minutes域使用*, 即表示每分钟都会触发事件。

  (2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。

  (3)-:表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次

  (4)/:表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.

  (5),:表示列出枚举值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。

  (6)L:表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。

  (7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 。

  (8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。

  (9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

  三、常用表达式例子

  (1)0 0 2 1 * ? *   表示在每月的1日的凌晨2点调整任务

  (2)0 15 10 ? * MON-FRI   表示周一到周五每天上午10:15执行作业

  (3)0 15 10 ? 6L 2002-2006   表示2002-2006年的每个月的最后一个星期五上午10:15执行作

  (4)0 0 10,14,16 * * ?   每天上午10点,下午2点,4点

  (5)0 0/30 9-17 * * ?   朝九晚五工作时间内每半小时

  (6)0 0 12 ? * WED    表示每个星期三中午12点

  (7)0 0 12 * * ?   每天中午12点触发

  (8)0 15 10 ? * *    每天上午10:15触发

  (9)0 15 10 * * ?     每天上午10:15触发

  (10)0 15 10 * * ? *    每天上午10:15触发

  (11)0 15 10 * * ? 2005    2005年的每天上午10:15触发

  (12)0 * 14 * * ?     在每天下午2点到下午2:59期间的每1分钟触发

  (13)0 0/5 14 * * ?    在每天下午2点到下午2:55期间的每5分钟触发

  (14)0 0/5 14,18 * * ?     在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发

  (15)0 0-5 14 * * ?    在每天下午2点到下午2:05期间的每1分钟触发

  (16)0 10,44 14 ? 3 WED    每年三月的星期三的下午2:10和2:44触发

  (17)0 15 10 ? * MON-FRI    周一至周五的上午10:15触发

  (18)0 15 10 15 * ?    每月15日上午10:15触发

  (19)0 15 10 L * ?    每月最后一日的上午10:15触发

  (20)0 15 10 ? * 6L    每月的最后一个星期五上午10:15触发

  (21)0 15 10 ? * 6L 2002-2005   2002年至2005年的每月的最后一个星期五上午10:15触发

  (22)0 15 10 ? * 6#3   每月的第三个星期五上午10:15触发

注:

  (1)有些子表达式能包含一些范围或列表

  例如:子表达式(天(星期))可以为 “MON-FRI”,“MON,WED,FRI”,“MON-WED,SAT”

“*”字符代表所有可能的值

  因此,“*”在子表达式(月)里表示每个月的含义,“*”在子表达式(天(星期))表示星期的每一天

  “/”字符用来指定数值的增量 
  例如:在子表达式(分钟)里的“0/15”表示从第0分钟开始,每15分钟 
在子表达式(分钟)里的“3/20”表示从第3分钟开始,每20分钟(它和“3,23,43”)的含义一样

  “?”字符仅被用于天(月)和天(星期)两个子表达式,表示不指定值 
  当2个子表达式其中之一被指定了值以后,为了避免冲突,需要将另一个子表达式的值设为“?”

  “L” 字符仅被用于天(月)和天(星期)两个子表达式,它是单词“last”的缩写 
  但是它在两个子表达式里的含义是不同的。 
  在天(月)子表达式中,“L”表示一个月的最后一天 
  在天(星期)自表达式中,“L”表示一个星期的最后一天,也就是SAT

  如果在“L”前有具体的内容,它就具有其他的含义了

  例如:“6L”表示这个月的倒数第6天,“FRIL”表示这个月的最一个星期五 
  注意:在使用“L”参数时,不要指定列表或范围,因为这会导致问题

Vue3项目-生成Cron表达式组件的更多相关文章

  1. 按时间间隔生成cron表达式

    cron表达式是使用任务调度经常使用的表达式了.对于通常的简单任务,我们只需要一条cron表达式就能满足.但是有的时候任务也可以很复杂. 最近我遇到了一个问题,一条任务在开始的时候要触发A方法,在结束 ...

  2. java生成cron表达式

    bean类: package com.cst.klocwork.service.cron; public class TaskScheduleModel { /** * 所选作业类型: * 1 -&g ...

  3. 指定时间生成cron表达式

    public class CronUtils { private static final SimpleDateFormat sdf = new SimpleDateFormat("ss m ...

  4. quartz cron表达式在线生成

    近期使用了quartz定时器,有感于起cron表达式有点复杂.且无法实时推断定时时间是否正确,因此写了个在线表达式及依据表达式获得前10次运行时间. 訪问地址例如以下:http://cron.g2ro ...

  5. quartz.net 时间表达式----- Cron表达式详解

    序言 Cron表达式:就是用简单的xxoo符号按照一定的规则,就能把各种时间维度表达的淋漓尽致,无所不在其中,然后在用来做任务调度(定时服务)的quart.net中所认知执行,可想而知这是多么的天衣无 ...

  6. 通过Quartz 配置定时调度任务:使用cron表达式配置时间点

    Cron官网入口 在后台经常需要一些定时处理的任务,比如微信相关应用所需的access_token,就要定时刷新,官方返回的有效性是7200s,也就是2小时,但是为了保险起见,除了在发现access_ ...

  7. Quartz Cron表达式的二三事

    最近在解决产品上的一个需求,就是定期生成报告(Report),我们叫做Scheduled Report. 原理:UI获取用户输入的时间信息,后台使用Spring框架设置定时任务,这里定时任务用的就是  ...

  8. 详解定时任务中的 cron 表达式

    1.前言 我们经常使用 cron 表达式来定义定时任务的执行策略,今天我们就总结一下 cron 表达式的一些相关知识. 2. cron 表达式的定义 cron 表达式是一个字符串,该字符串由 6 个空 ...

  9. 使用Cron表达式创建定时任务

    CronTriggerCronTrigger功能非常强大,是基于日历的作业调度,而SimpleTrigger是精准指定间隔,所以相比SimpleTrigger,CroTrigger更加常用.CroTr ...

  10. quartz Cron表达式生成详解

    简介 Cron作为一个Unix工具,已经存在很长一段时间了,用于实现任务调度的功能.CronTrigger类基于Cron而来. CronTrigger CronTriggers往往比SimpleTri ...

随机推荐

  1. 微信小程序实现原理

    微信小程序实现原理 微信小程序采用wxml.wxss.javascript进行开发,本质是一个单页应用,所有的页面渲染和事件处理,都在一个页面内进行,但又可以通过微信客户端调用原生的各种接口.微信的架 ...

  2. win32 - 对于32位的应用程序,LoadResource为什么不需要释放资源

    原话: [此功能已过时,仅支持与16位Windows向后兼容.对于32位Windows应用程序,不必释放使用LoadResource加载的资源.如果在32或64位Windows系统上使用,此函数将返回 ...

  3. 【Android逆向】脱壳项目frida_dump 原理分析

    脱dex核心文件dump_dex.js 核心函数 function dump_dex() { var libart = Process.findModuleByName("libart.so ...

  4. SSH不对称密钥自动登入服务器

    SSH不对称密钥自动登入服务器 1.先在自己的电脑上创建密钥对 ssh-keygen -t rsa Windows下生成SSH密钥 $ ssh-keygen -t rsa -C "youre ...

  5. You can't specify target table for update in FROM clause

    mysql中You can't specify target table for update in FROM clause错误的意思是说,不能先select出同一表中的某些值,再update这个表( ...

  6. NebulaGraph is nothing without you | 社区 2023 年度人物合集

    在去年的年度人物 回顾中,我们看到了形形色色的人们,他们当中有帮 NebulaGraph 捉 bug 的小能手,也有通过用回复来解答他人疑惑的启蒙者-在今年(2023 年),我们这个整点不一样的,将镜 ...

  7. 揭秘可视化图探索工具 NebulaGraph Explore 是如何实现图计算的

    前言 在可视化图探索工具 NebulaGraph Explorer 3.1.0 版本中加入了图计算工作流功能,针对 NebulaGraph 提供了图计算的能力,同时可以利用工作流的 nGQL 运行能力 ...

  8. [C++/QT] 获取进程完整路径

    气哭我了,我不就获取一下进程路径嘛,,,绕了好大一圈 主要是用到了GetModuleFileNameEx() 函数 食用方式如下 HANDLE hProcess = OpenProcess(PROCE ...

  9. centos 7与8修改主机名的各种方法

    hostname 查看当前系统主机名,知道当前主机名为localhost 当然在centos7特地添加了hostnamectl命令查看,修改主机名 使用hostnamectl set-hostname ...

  10. 虚拟机和开发板之间通过NFS互联

    简介 NFS是Network File System的首字母缩写.它是一种分布式协议,使客户端可以访问远程服务器上的共享文件.它允许网络中的计算机之间通过TCP/IP网络共享资源. 配置过程 安装NF ...