vue3 添加編輯頁(yè)使用 cron 表達(dá)式生成方法小結(jié)
示例效果圖

1、添加組件
<template>
<div class="v3c">
<ul class="v3c-tab">
<li class="v3c-tab-item" :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)">時(shí)</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">秒執(zhí)行, 從</span>
<el-input-number v-model="state.second.incrementStart" :min="0" :max="59" controls-position="right"/>
<span>秒開(kāi)始</span>
</div>
<!-- 具體秒數(shù) -->
<div class="mt-15">
<el-radio label="3" v-model="state.second.cronEvery">具體秒數(shù)(可多選)</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">分執(zhí)行,從</span>
<el-input-number v-model="state.minute.incrementStart" :min="0" :max="59" controls-position="right"/>
<span>分開(kāi)始</span>
</div>
<!-- 具體分鐘數(shù) -->
<div class="mt-15">
<el-radio label="3" v-model="state.minute.cronEvery">具體分鐘數(shù)(可多選)</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>
<!-- 小時(shí) -->
<div class="v3c-content" v-show="tabActive == 3">
<!-- 每一小時(shí) -->
<div>
<el-radio label="1" v-model="state.hour.cronEvery">每一小時(shí)</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">小時(shí)執(zhí)行,從</span>
<el-input-number v-model="state.hour.incrementStart" :min="0" :max="23" controls-position="right"/>
<span>小時(shí)開(kāi)始</span>
</div>
<!-- 具體小時(shí)數(shù) -->
<div class="mt-15">
<el-radio label="3" v-model="state.hour.cronEvery">具體小時(shí)數(shù)(可多選)</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>時(shí)</span><span class="ml-10 mr-5">到</span>
<el-input-number v-model="state.hour.rangeEnd" :min="0" :max="23" controls-position="right"/>
<span>時(shí)</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">周執(zhí)行,從</span>-->
<!-- <el-input-number v-model="state.week.incrementStart" :min="1" :max="52" controls-position="right"/>-->
<!-- <span>周開(kāi)始</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">天執(zhí)行,從</span>
<el-input-number v-model="state.day.incrementStart" :min="1" :max="30" controls-position="right"/>
<span>天開(kāi)始</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">具體天數(shù)(可多選)</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">在這個(gè)月的最后一天</el-radio>
</div> -->
<!-- 7 -->
<!-- <div class="mt-15">
<el-radio label="7" v-model="state.day.cronEvery">在這個(gè)月的最后一個(gè)工作日</el-radio>
</div> -->
<!-- 8 -->
<!-- <div class="mt-15">
<el-radio label="8" v-model="state.day.cronEvery">在這個(gè)月的最后一個(gè)</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">在這個(gè)月的第</el-radio>
<el-input-number v-model="state.week.cronNthDayNth" :min="1" :max="5" controls-position="right" />
<span>個(gè)</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">月執(zhí)行,從</span>
<el-input-number v-model="state.month.incrementStart" :min="1" :max="12" controls-position="right"/>
<span>月開(kāi)始</span>
</div>
<!-- 3 -->
<div class="mt-15">
<el-radio label="3" v-model="state.month.cronEvery">具體月數(shù)(可多選)</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">年執(zhí)行,從</span>
<el-input-number v-model="state.year.incrementStart" :min="currYear" :max="currYear + 10"
controls-position="right" style="width:100px;"/>
<span>年開(kāi)始</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="mt-15">
<el-input v-model="value"/>
</div>
</div>
</template>
<script>
import {reactive, computed, toRefs, defineComponent, ref, watch} from "vue";
// (默認(rèn)是每一分鐘一次)
export default defineComponent({
name: "Vue3Cron",
props: {
maxHeight: String,
change: Function,
value: String,
},
setup(props, {emit}) {
const weekList = ref([
{name: '星期日', val: 'SUN', value: 1,},
{name: '星期一', val: 'MON', value: 2,},
{name: '星期二', val: 'TUE', value: 3,},
{name: '星期三', val: 'WED', value: 4,},
{name: '星期四', val: 'THU', value: 5,},
{name: '星期五', val: 'FRI', value: 6,},
{name: '星期六', val: 'SAT', value: 7,},
])
const tabActive = ref(1);
const currYear = ref(new Date().getFullYear());
const onHandleTab = (index) => {
tabActive.value = index;
};
// (默認(rèn)是每一分鐘一次)
const state = reactive({
second: {
cronEvery: "1",
incrementStart: 0,
incrementIncrement: 1,
rangeStart: 0,
rangeEnd: 0,
specificSpecific: [],
},
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(() => {
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(() => {
console.log("------------")
let weeks = "";
let cronEvery = state.day.cronEvery;
switch (cronEvery?.toString()) {
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 "5":
weeks = "?";
break;
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(() => {
let secondsText = `${state.secondsText || "*"}`
let minutesText = `${state.minutesText || "*"}`
let hoursText = `${state.hoursText || "*"}`
let daysText = `${state.daysText || "*"}`
let monthsText = `${state.monthsText || "*"}`
let weeksText = `${state.weeksText || "?"}`
let yearsText = `${state.yearsText || "*"}`
if (minutesText !== '*') {
secondsText = secondsText === '*' ? '0' : secondsText;
}
if (hoursText !== '*') {
secondsText = secondsText === '*' ? '0' : secondsText;
minutesText = minutesText === '*' ? '0' : minutesText;
}
if (daysText !== '*') {
secondsText = secondsText === '*' ? '0' : secondsText;
minutesText = minutesText === '*' ? '0' : minutesText;
hoursText = hoursText === '*' ? '0' : hoursText;
}
if (weeksText !== '?') {
secondsText = secondsText === '*' ? '0' : secondsText;
minutesText = minutesText === '*' ? '0' : minutesText;
hoursText = hoursText === '*' ? '0' : hoursText;
}
if (monthsText !== '*') {
secondsText = secondsText === '*' ? '0' : secondsText;
minutesText = minutesText === '*' ? '0' : minutesText;
hoursText = hoursText === '*' ? '0' : hoursText;
daysText = daysText === '*' ? '1' : daysText;
}
if (yearsText !== '*') {
secondsText = secondsText === '*' ? '0' : secondsText;
minutesText = minutesText === '*' ? '0' : minutesText;
hoursText = hoursText === '*' ? '0' : hoursText;
// daysText = daysText === '*' ? '1' : daysText;
// monthsText = monthsText === '*' ? '1' : monthsText;
}
return secondsText + " " + minutesText + " " + hoursText + " " + daysText + " " + monthsText + " " + weeksText + " " + yearsText;
}),
});
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;
}
}
}
};
// 點(diǎn)擊變更調(diào)用方數(shù)據(jù)
const handleChange = () => {
if (typeof state.cron !== "string") return false;
emit("change", state.cron);
};
// 數(shù)據(jù)變化時(shí)變更調(diào)用方數(shù)據(jù)
watch(
() => state.cron,
(value) => {
if (typeof state.cron !== "string") return;
emit("update:value", value);
}
);
return {
weekList,
state,
handleChange,
rest,
tabActive,
onHandleTab,
currYear,
};
},
});
</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-content > div {
line-height: 50px;
}
.v3c-content {
padding: 20px;
max-height: v-bind(maxHeight);
overflow: hidden;
overflow-y: auto;
}
.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;
}
</style>2、使用組件
2.1、定義相關(guān)前置參數(shù)
import {defineAsyncComponent} from "vue";
export default {
components: {
Vue3Cron: defineAsyncComponent(() => import('@/components/vue3-cron/cron.vue')),
},
data() {
return {
// 表單參數(shù)
obj: {},
// 定義彈窗開(kāi)關(guān)字段
cronDialogVisible: false,
cronTimes: [],
uri: {
// 定義預(yù)覽 uri 的接口地址
temporalPrediction: "/api/admin/dispatch/dispatchTask/temporalPrediction",
}
}
},
methods: {
// 獲取調(diào)度的預(yù)計(jì)執(zhí)行時(shí)間
temporalPrediction(cron, startTime, endTime) {
this.crud.get(this.uri.temporalPrediction, {cron: cron, startTime: startTime, endTime: endTime}).then(res => {
this.cronTimes = res.data.data;
})
},
} 2.2、 添加插槽 (添加/編輯頁(yè)中)
<!-- cron 表達(dá)式插槽 -->
<template #cron="{size,row,index}">
<!-- 展示當(dāng)前cron 表達(dá)式-->
<el-input v-model="this.obj.cron" placeholder=""/>
<!-- 打開(kāi) cron 生成彈窗,詳見(jiàn)定義彈窗中的內(nèi)容 -->
<el-button type="primary" style="margin-top: 10px;margin-bottom: 10px" @click="cronDialogVisible=true">cron 生成</el-button>
<!-- 時(shí)間預(yù)測(cè)-- 與預(yù)覽 (當(dāng)前頁(yè)面中) -->
<el-button type="primary" style="margin-top: 10px;margin-bottom: 10px" @click="temporalPrediction(this.obj.cron,this.obj.startTime,this.obj.endTime) ">時(shí)間預(yù)測(cè)</el-button>
<div v-for="(item,index) in cronTimes">
{{ item }}
</div>
</template>2.3、定義彈窗 (添加/編輯頁(yè)中)
<!-- cron 是彈窗 -->
<el-dialog title="cron 生成" v-if="cronDialogVisible" v-model="cronDialogVisible">
<!-- 選擇 -->
<Vue3Cron v-model:value="this.obj.cron"/>
<!-- 時(shí)間預(yù)測(cè)-- 與預(yù)覽 (彈窗中) -->
<el-button type="primary" style="margin-top: 10px;margin-bottom: 10px" @click="temporalPrediction(this.obj.cron) ">獲取最近運(yùn)行時(shí)間</el-button>
<div v-for="(item,index) in cronTimes">
{{ item }}
</div>
</el-dialog>后端部分 ( java)
pom.xml
<!-- quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>com.cronutils</groupId>
<artifactId>cron-utils</artifactId>
<version>9.1.0</version>
</dependency>接口 controller
@GetMapping(value = "/temporalPrediction")
@ApiOperation(value = "時(shí)間預(yù)測(cè)")
public Result<List<String>> temporalPrediction(@RequestParam String cron,String startTime,String endTime) {
return Result.success(baseService.temporalPrediction( cron, startTime, endTime));
}接口 service
/**
* 時(shí)間預(yù)測(cè)
*
* @param cron cron
* @param startTime 開(kāi)始時(shí)間
* @param endTime 結(jié)束時(shí)間
* @return {@link List}<{@link String}>
*/
List<String> temporalPrediction(String cron, String startTime, String endTime);
@Override
public List<String> temporalPrediction(String cron, String startTime, String endTime) {
List<String> nextExecuteTimes = null;
try {
if (StringUtils.isBlank(startTime) && StringUtils.isBlank(endTime)) {
nextExecuteTimes = QuartzUtil.getNextExecuteTimes(cron, 10);
} else {
nextExecuteTimes = QuartzUtil.getNextExecuteTimesByTimeRange(cron, startTime, endTime, 10);
}
} catch (Exception e) {
throw new ErrorException("cron 表達(dá)式解析失敗");
}
return nextExecuteTimes;
}QuartzUtil 工具
/**
* 根據(jù)時(shí)間范圍獲取新的cron表達(dá)式
*
* @param cronExpression 現(xiàn)有的 cron 表達(dá)式
* @param startTimeStr 開(kāi)始時(shí)間
* @param startTimeStr 結(jié)束時(shí)間
* @return {@link String} 時(shí)間范圍
*/
public static String getNewCronByTimeRange(String cronExpression, String startTimeStr, String endTimeStr) {
LocalDateTime startTime = LocalDateTimeUtil.parse("2021-01-01 " + startTimeStr);
LocalDateTime endTime = LocalDateTimeUtil.parse("2021-01-01 " + endTimeStr);
if (LocalDateTimeUtil.isAfter(startTime, endTime)) {
throw new ErrorException("開(kāi)始時(shí)間不能小于結(jié)束時(shí)間");
}
long minutes = LocalDateTimeUtil.betweenTwoTime(startTime, endTime, ChronoUnit.MINUTES);
if (minutes == 0) {
// 差值為0, cron 表達(dá)式結(jié)果不變
return cronExpression;
}
// 隨機(jī)分鐘數(shù)
long randomLong = RandomUtil.randomLong(minutes);
// 隨機(jī)秒數(shù)
long second = RandomUtil.randomLong(59);
LocalDateTime time = LocalDateTimeUtil.plus(startTime, randomLong, ChronoUnit.MINUTES);
// System.out.println("隨機(jī)數(shù):" + randomLong+ " 隨機(jī)時(shí)間:" + time.getHour() +":" + time.getMinute() +":"+ second);
String[] cronExpressionArray = cronExpression.split(" ");
cronExpressionArray[0] = second + "";
cronExpressionArray[1] = time.getMinute() + "";
cronExpressionArray[2] = time.getHour() + "";
return String.join(" ", cronExpressionArray);
}
/**
* 列出接下來(lái)的 n次 執(zhí)行時(shí)間 (根據(jù) cron 表達(dá)式)
*
* @param cronExpression cron表達(dá)式
* @param num 預(yù)測(cè)次數(shù)
* @throws ParseException 解析異常 (cron 表達(dá)式不規(guī)范需返回異常,調(diào)用方需主動(dòng)處理該錯(cuò)誤)
*/
public static List<String> getNextExecuteTimes(String cronExpression, int num) {
List<String> dates = new ArrayList<>();
CronExpression cron = null;
try {
cron = new CronExpression(cronExpression);
} catch (ParseException e) {
throw new RuntimeException(e);
}
Date currentDate = new Date();
for (int i = 0; i < num; i++) {
Date nextFireTime = cron.getNextValidTimeAfter(currentDate);
currentDate = nextFireTime;
dates.add(formatDate(nextFireTime));
}
return dates;
}
/**
* 列出接下來(lái)的 n次 執(zhí)行時(shí)間 (根據(jù) cron 表達(dá)式+ 時(shí)間范圍)
*
* @param cronExpression cron表達(dá)式
* @param num 預(yù)測(cè)次數(shù)
* @throws ParseException 解析異常 (cron 表達(dá)式不規(guī)范需返回異常,調(diào)用方需主動(dòng)處理該錯(cuò)誤)
*/
public static List<String> getNextExecuteTimesByTimeRange(String cronExpression, String startTimeStr, String endTimeStr, int num) {
List<String> dates = new ArrayList<>();
for (int i = 0; i < num; i++) {
String newCron = getNewCronByTimeRange(cronExpression, startTimeStr, endTimeStr);
CronExpression cron = null;
try {
// 每次獲取為 i 的最后一次的執(zhí)行來(lái)保證 年月日 單位的執(zhí)行日期, 時(shí)分秒日期每次 i 循環(huán)時(shí)修改獲得
cron = new CronExpression(newCron);
} catch (ParseException e) {
throw new RuntimeException(e);
}
Date currentDate = new Date();
for (int j = 0; j <= i; j++) {
Date nextFireTime = cron.getNextValidTimeAfter(currentDate);
currentDate = nextFireTime;
if (j == i) {
dates.add(formatDate(nextFireTime));
}
}
}
return dates;
}
/**
* 格式化時(shí)間日期
*
* @param date 日期
* @return {@link String}
*/
private static String formatDate(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(date);
}到此這篇關(guān)于vue3 添加編輯頁(yè)使用 cron 表達(dá)式生成的文章就介紹到這了,更多相關(guān)vue3 cron 表達(dá)式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
為Vue3?組件標(biāo)注?TS?類型實(shí)例詳解
這篇文章主要為大家介紹了為Vue3?組件標(biāo)注?TS?類型實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
vue cli 3.x 項(xiàng)目部署到 github pages的方法
這篇文章主要介紹了vue cli 3.x 項(xiàng)目部署到 github pages的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-04-04
Vue.js中的extend綁定節(jié)點(diǎn)并顯示的方法
在本篇內(nèi)容里小編給大家整理了關(guān)于Vue.js中的extend綁定節(jié)點(diǎn)并顯示的方法以及相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。2019-06-06
解決antd Form 表單校驗(yàn)方法無(wú)響應(yīng)的問(wèn)題
這篇文章主要介紹了解決antd Form 表單校驗(yàn)方法無(wú)響應(yīng)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
vue實(shí)踐---根據(jù)不同環(huán)境,自動(dòng)轉(zhuǎn)換請(qǐng)求的url地址操作
這篇文章主要介紹了vue實(shí)踐---根據(jù)不同環(huán)境,自動(dòng)轉(zhuǎn)換請(qǐng)求的url地址操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
Vue.js 點(diǎn)擊按鈕顯示/隱藏內(nèi)容的實(shí)例代碼
下面小編就為大家分享一篇Vue.js 點(diǎn)擊按鈕顯示/隱藏內(nèi)容的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
vue時(shí)間戳和時(shí)間的相互轉(zhuǎn)換方式
本文通過(guò)示例代碼介紹了vue時(shí)間戳和時(shí)間的相互轉(zhuǎn)換方式,通過(guò)場(chǎng)景分析介紹了vue3使用組合式api將時(shí)間戳格式轉(zhuǎn)換成時(shí)間格式(2023年09月28日 10:00),感興趣的朋友一起看看吧2023-12-12
vue實(shí)現(xiàn)離線地圖+leaflet+高德瓦片的詳細(xì)代碼
這篇文章主要給大家介紹了關(guān)于vue實(shí)現(xiàn)離線地圖+leaflet+高德瓦片的詳細(xì)代碼,Vue Leaflet是一種結(jié)合了Vue框架和Leaflet庫(kù)的前端技術(shù),用于展示和操作天地圖,需要的朋友可以參考下2023-10-10
關(guān)于ElementPlus中的表單驗(yàn)證規(guī)則詳解
這篇文章主要介紹了關(guān)于ElementPlus中的表單驗(yàn)證,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06

