|
|
@@ -1,966 +0,0 @@
|
|
|
-<template>
|
|
|
- <div>
|
|
|
- <el-input v-model="state.modelData" placeholder="请输入cron表达式">
|
|
|
- <template #append>
|
|
|
- <ext-button icon="ele-Setting" @click="state.tooltipVisible = !state.tooltipVisible"/>
|
|
|
- </template>
|
|
|
- </el-input>
|
|
|
-
|
|
|
- <el-dialog
|
|
|
- title="cron表达式工具"
|
|
|
- v-model="state.tooltipVisible"
|
|
|
- width="720px"
|
|
|
- draggable
|
|
|
- destroy-on-close
|
|
|
- append-to-body
|
|
|
- :modal="false"
|
|
|
- :close-on-click-modal="false"
|
|
|
- :close-on-press-escape="false"
|
|
|
- align-center>
|
|
|
- <div class="cron-container" style="width: 100%;min-height:500px; ">
|
|
|
- <el-tabs type="border-card" v-model="state.activeTab">
|
|
|
-
|
|
|
- <el-tab-pane name="generator" label="生成器" v-if="!disabled">
|
|
|
-
|
|
|
- <el-tabs model-value="second">
|
|
|
- <el-tab-pane :label="state.text.Seconds.name" name="second">
|
|
|
- <div>
|
|
|
- <label for="seconds1">
|
|
|
- <input type="radio" id="seconds1" value="1" v-model="state.second.cronEvery"/>
|
|
|
- {{ state.text.Seconds.every }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 每隔多久 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="seconds2">
|
|
|
- <input type="radio" id="seconds2" value="2" v-model="state.second.cronEvery"/>
|
|
|
- {{ state.text.Seconds.interval[0] }}
|
|
|
- <el-input-number type="number" :min="1" :max="60" v-model="state.second.incrementIncrement"/>
|
|
|
- {{ state.text.Seconds.interval[1] || "" }}
|
|
|
- <el-input-number type="number" :min="0" :max="59" v-model="state.second.incrementStart"/>
|
|
|
- {{ state.text.Seconds.interval[2] || "" }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 具体秒数 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="seconds3">
|
|
|
- <input type="radio" id="seconds3" value="3" v-model="state.second.cronEvery"/>
|
|
|
- {{ state.text.Seconds.specific }}
|
|
|
- <el-select multiple filterable v-model="state.second.specificSpecific">
|
|
|
- <el-option :value="index" v-for="(item, index) in 60" :key="index">{{ index }}</el-option>
|
|
|
- </el-select>
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 具体秒数 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="seconds4">
|
|
|
- <input type="radio" id="seconds4" value="4" v-model="state.second.cronEvery"/>
|
|
|
- {{ state.text.Seconds.cycle[0] }}
|
|
|
- <el-input-number type="number" v-model="state.second.rangeStart" :min="1" :max="60"/>
|
|
|
- {{ state.text.Seconds.cycle[1] || "" }}
|
|
|
- <el-input-number type="number" v-model="state.second.rangeEnd" :min="0" :max="59"/>
|
|
|
- {{ state.text.Seconds.cycle[2] || "" }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- </el-tab-pane>
|
|
|
-
|
|
|
- <el-tab-pane :label="state.text.Minutes.name">
|
|
|
- <div>
|
|
|
- <label for="minute1">
|
|
|
- <input type="radio" id="minute1" value="1" v-model="state.minute.cronEvery"/>
|
|
|
- {{ state.text.Minutes.every }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 每隔多久 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="minute2">
|
|
|
- <input type="radio" id="minute2" value="2" v-model="state.minute.cronEvery"/>
|
|
|
- {{ state.text.Minutes.interval[0] }}
|
|
|
- <el-input-number type="number" :min="1" :max="60" v-model="state.minute.incrementIncrement"/>
|
|
|
- {{ state.text.Minutes.interval[1] || "" }}
|
|
|
- <el-input-number type="number" :min="0" :max="59" v-model="state.minute.incrementStart"/>
|
|
|
- {{ state.text.Minutes.interval[2] || "" }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 具体秒数 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="minute3">
|
|
|
- <input type="radio" id="minute3" value="3" v-model="state.minute.cronEvery"/>
|
|
|
- {{ state.text.Minutes.specific }}
|
|
|
- <el-select multiple filterable v-model="state.minute.specificSpecific">
|
|
|
- <el-option :value="index" v-for="(item, index) in 60" :key="index">{{ index }}</el-option>
|
|
|
- </el-select>
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 具体秒数 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="minute4">
|
|
|
- <input type="radio" id="minute4" value="4" v-model="state.minute.cronEvery"/>
|
|
|
- {{ state.text.Minutes.cycle[0] }}
|
|
|
- <el-input-number type="number" v-model="state.minute.rangeStart" :min="1" :max="60"/>
|
|
|
- {{ state.text.Minutes.cycle[1] || "" }}
|
|
|
- <el-input-number type="number" v-model="state.minute.rangeEnd" :min="0" :max="59"/>
|
|
|
- {{ state.text.Minutes.cycle[2] || "" }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- </el-tab-pane>
|
|
|
-
|
|
|
-
|
|
|
- <el-tab-pane :label="state.text.Hours.name">
|
|
|
-
|
|
|
- <div>
|
|
|
- <label for="hour1">
|
|
|
- <input type="radio" id="hour1" value="1" v-model="state.hour.cronEvery"/>
|
|
|
- {{ state.text.Hours.every }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 每隔多久 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="hour2">
|
|
|
- <input type="radio" id="hour2" value="2" v-model="state.hour.cronEvery"/>
|
|
|
- {{ state.text.Hours.interval[0] }}
|
|
|
- <el-input-number type="number" :min="1" :max="60" v-model="state.hour.incrementIncrement"/>
|
|
|
- {{ state.text.Hours.interval[1] || "" }}
|
|
|
- <el-input-number type="number" :min="0" :max="59" v-model="state.hour.incrementStart"/>
|
|
|
- {{ state.text.Hours.interval[2] || "" }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 具体秒数 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="hour3">
|
|
|
- <input type="radio" id="hour3" value="3" v-model="state.hour.cronEvery"/>
|
|
|
- {{ state.text.Hours.specific }}
|
|
|
- <el-select multiple filterable v-model="state.hour.specificSpecific">
|
|
|
- <el-option :value="index" v-for="(item, index) in 24" :key="index">{{ index }}</el-option>
|
|
|
- </el-select>
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 具体秒数 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="hour4">
|
|
|
- <input type="radio" id="hour4" value="4" v-model="state.hour.cronEvery"/>
|
|
|
- {{ state.text.Hours.cycle[0] }}
|
|
|
- <el-input-number type="number" v-model="state.hour.rangeStart" :min="1" :max="60"/>
|
|
|
- {{ state.text.Hours.cycle[1] || "" }}
|
|
|
- <el-input-number type="number" v-model="state.hour.rangeEnd" :min="0" :max="59"/>
|
|
|
- {{ state.text.Hours.cycle[2] || "" }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- </el-tab-pane>
|
|
|
-
|
|
|
- <el-tab-pane :label="state.text.Day.name">
|
|
|
- <!-- 1 -->
|
|
|
- <div>
|
|
|
- <label for="day1">
|
|
|
- <input type="radio" id="day1" value="1" v-model="state.day.cronEvery"/>
|
|
|
- {{ state.text.Day.every }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 2 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="day2">
|
|
|
- <input type="radio" id="day2" value="2" v-model="state.day.cronEvery"/>
|
|
|
- {{ state.text.Day.intervalWeek[0] }}
|
|
|
- <el-input-number type="number" :min="1" :max="7" v-model="state.week.incrementIncrement"/>
|
|
|
- {{ state.text.Day.intervalWeek[1] }}
|
|
|
- <el-input-number type="number" :min="0" :max="59" v-model="state.week.incrementStart"/>
|
|
|
- {{ state.text.Day.intervalWeek[2] }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 3 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="day3">
|
|
|
- <input type="radio" id="day3" value="3" v-model="state.day.cronEvery"/>
|
|
|
- {{ state.text.Day.intervalDay[0] }}
|
|
|
- <el-input-number type="number" v-model="state.day.rangeStart" :min="1" :max="30"/>
|
|
|
- {{ state.text.Day.intervalDay[1] }}
|
|
|
- <el-input-number type="number" v-model="state.day.rangeEnd" :min="1" :max="30"/>
|
|
|
- {{ state.text.Day.intervalDay[2] }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 4 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="day4">
|
|
|
- <input type="radio" id="day4" value="4" v-model="state.day.cronEvery"/>
|
|
|
- {{ state.text.Day.specificWeek }}
|
|
|
- <el-select multiple filterable v-model="state.week.specificSpecific">
|
|
|
- <el-option v-for="(val, index) in 7" :key="index" :value="['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'][val - 1]">
|
|
|
- {{ state.text.Week[val - 1] }}
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 5 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="day5">
|
|
|
- <input type="radio" id="day5" value="5" v-model="state.day.cronEvery"/>
|
|
|
- {{ state.text.Day.specificDay }}
|
|
|
- <el-select multiple filterable v-model="state.day.specificSpecific">
|
|
|
- <el-option v-for="(val, index) in 31" :key="index" :value="val">
|
|
|
- {{ val }}
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 6 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="day6">
|
|
|
- <input type="radio" id="day6" value="6" v-model="state.day.cronEvery"/>
|
|
|
- {{ state.text.Day.lastDay }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 7 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="day7">
|
|
|
- <input type="radio" id="day7" value="7" v-model="state.day.cronEvery"/>
|
|
|
- {{ state.text.Day.lastWeekday }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 8 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="day8">
|
|
|
- <input type="radio" id="day8" value="8" v-model="state.day.cronEvery"/>
|
|
|
- {{ state.text.Day.lastWeek[0] }}
|
|
|
- <el-select v-model="state.day.cronLastSpecificDomDay">
|
|
|
- <el-option v-for="(val, index) in 7" :key="index" :value="val">
|
|
|
- {{ state.text.Week[val - 1] }}
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- {{ state.text.Day.lastWeek[1] || "" }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 9 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="day9">
|
|
|
- <input type="radio" id="day9" value="9" v-model="state.day.cronEvery"/>
|
|
|
- <el-input-number type="number" v-model="state.day.cronDaysBeforeEomMinus" :min="1" :max="31"/>
|
|
|
- {{ state.text.Day.beforeEndMonth[0] }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 10 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="day10">
|
|
|
- <input type="radio" id="day10" value="10" v-model="state.day.cronEvery"/>
|
|
|
- {{ state.text.Day.nearestWeekday[0] }}
|
|
|
- <el-input-number type="number" v-model="state.day.cronDaysNearestWeekday" :min="1" :max="31"/>
|
|
|
- {{ state.text.Day.nearestWeekday[1] }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 11 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="day11">
|
|
|
- <input type="radio" id="day11" value="11" v-model="state.day.cronEvery"/>
|
|
|
- {{ state.text.Day.someWeekday[0] }}
|
|
|
- <el-input-number type="number" v-model="state.week.cronNthDayNth" :min="1" :max="5"/>
|
|
|
-
|
|
|
- <el-select v-model="state.week.cronNthDayDay">
|
|
|
- <el-option v-for="(val, index) in 7" :key="index" :value="val">
|
|
|
- {{ state.text.Week[val - 1] }}
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- {{ state.text.Day.someWeekday[1] }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- </el-tab-pane>
|
|
|
-
|
|
|
- <el-tab-pane :label="state.text.Month.name">
|
|
|
- <div>
|
|
|
- <label for="month1">
|
|
|
- <input type="radio" id="month1" value="1" v-model="state.month.cronEvery"/>
|
|
|
- {{ state.text.Month.every }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 2 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="month2">
|
|
|
- <input type="radio" id="month2" value="2" v-model="state.month.cronEvery"/>
|
|
|
- {{ state.text.Month.interval[0] }}
|
|
|
- <el-input-number type="number" v-model="state.month.incrementIncrement" :min="0" :max="12"/>
|
|
|
- {{ state.text.Month.interval[1] }}
|
|
|
- <el-input-number type="number" v-model="state.month.incrementStart" :min="0" :max="12"/>
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 3 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="month3">
|
|
|
- <input type="radio" id="month3" value="3" v-model="state.month.cronEvery"/>
|
|
|
- {{ state.text.Month.specific }}
|
|
|
- <el-select multiple filterable v-model="state.month.specificSpecific">
|
|
|
- <el-option v-for="(val, index) in 12" :key="index" :value="val">
|
|
|
- {{ val }}
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 4 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="month4">
|
|
|
- <input type="radio" id="month4" value="4" v-model="state.month.cronEvery"/>
|
|
|
- {{ state.text.Month.cycle[0] }}
|
|
|
- <el-input-number type="number" v-model="state.month.rangeStart" :min="1" :max="12"/>
|
|
|
- {{ state.text.Month.cycle[1] }}
|
|
|
- <el-input-number type="number" v-model="state.month.rangeEnd" :min="1" :max="12"/>
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- </el-tab-pane>
|
|
|
-
|
|
|
- <el-tab-pane :label="state.text.Year.name">
|
|
|
- <!-- 1 -->
|
|
|
- <div>
|
|
|
- <label for="year1">
|
|
|
- <input type="radio" id="year1" value="1" v-model="state.year.cronEvery"/>
|
|
|
- {{ state.text.Year.every }}
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 2 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="year2">
|
|
|
- <input type="radio" id="year2" value="2" v-model="state.year.cronEvery"/>
|
|
|
- {{ state.text.Year.interval[0] }}
|
|
|
- <el-input-number type="number" v-model="state.year.incrementIncrement" :min="1" :max="99"/>
|
|
|
- {{ state.text.Year.interval[1] }}
|
|
|
- <el-input-number type="number" v-model="state.year.incrementStart" :min="currYear" :max="currYear + 10"/>
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 3 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="year3">
|
|
|
- <input type="radio" id="year3" value="3" v-model="state.year.cronEvery"/>
|
|
|
- {{ state.text.Year.specific }}
|
|
|
- <el-select multiple filterable v-model="state.year.specificSpecific">
|
|
|
- <el-option v-for="(val, index) in 100" :key="index" :value="currYear + val">
|
|
|
- {{ currYear + val }}
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <!-- 4 -->
|
|
|
- <div class="mt-20">
|
|
|
- <label for="year3">
|
|
|
- <input type="radio" id="year3" value="4" v-model="state.year.cronEvery"/>
|
|
|
- {{ state.text.Year.cycle[0] }}
|
|
|
- <el-input-number type="number" v-model="state.year.rangeStart" :min="currYear" :max="currYear + 10"/>
|
|
|
- {{ state.text.Year.cycle[1] }}
|
|
|
- <el-input-number type="number" v-model="state.year.rangeEnd" :min="currYear" :max="currYear + 10"/>
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- </el-tab-pane>
|
|
|
- </el-tabs>
|
|
|
-
|
|
|
- <div class="v3c-footer mt20">
|
|
|
- <div style="flex: 1">
|
|
|
- 完整表达式 : <span class="cron">{{ state.cron }}</span>
|
|
|
-
|
|
|
-<!-- <el-button type="primary" @click.stop="handleChange">{{ state.text.Save }}</el-button>-->
|
|
|
- <el-button type="success" @click.stop="handleCheck">{{ state.text.Check }}</el-button>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </el-tab-pane>
|
|
|
-
|
|
|
- <el-tab-pane name="examples" label="常用示例">
|
|
|
- <el-card shadow="hover" class="mt20">
|
|
|
- <div class="flex justify-between flex-wrap hp code">
|
|
|
- <ext-clipboard message="*/10 * * * * ?" class="hc"/>
|
|
|
- <div class="mh10">*/10 * * * * ?</div>
|
|
|
- <div>每隔10秒执行一次</div>
|
|
|
- </div>
|
|
|
-
|
|
|
-
|
|
|
- <div class="flex justify-between flex-wrap hp code">
|
|
|
- <ext-clipboard message="0 */5 * * * ?" class="hc"/>
|
|
|
- <div class="mh10"> 0 */5 * * * ?</div>
|
|
|
- <div>每隔5分钟执行一次</div>
|
|
|
- </div>
|
|
|
-
|
|
|
-
|
|
|
- <div class="flex justify-between flex-wrap hp code">
|
|
|
- <ext-clipboard message="0 2,22,32 * * * ?" class="hc"/>
|
|
|
- <div class="mh10">0 2,22,32 * * * ?</div>
|
|
|
- <div>在2分、22分、32分执行一次</div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="flex justify-between flex-wrap hp code">
|
|
|
- <ext-clipboard message="0 0 4-8 * * ?" class="hc"/>
|
|
|
- <div class="mh10">0 0 4-8 * * ?</div>
|
|
|
- <div>每天4-8点整点执行一次</div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="flex justify-between flex-wrap hp code">
|
|
|
- <ext-clipboard message="0 0 2 * * ?" class="hc"/>
|
|
|
- <div class="mh10">0 0 2 * * ?</div>
|
|
|
- <div>每天凌晨2点执行一次</div>
|
|
|
- </div>
|
|
|
-
|
|
|
-
|
|
|
- <div class="flex justify-between flex-wrap hp code">
|
|
|
- <ext-clipboard message="0 0 2 1 * ?" class="hc"/>
|
|
|
- <div class="mh10">0 0 2 1 * ?</div>
|
|
|
- <div>每月1号凌晨2点执行一次</div>
|
|
|
- </div>
|
|
|
-
|
|
|
-
|
|
|
- </el-card>
|
|
|
- <p class="code">
|
|
|
- 格式:{Seconds} {Minutes} {Hours} {DayofMonth} {Month} {DayofWeek} {Year}[可选]
|
|
|
- </p>
|
|
|
- <p class="code">
|
|
|
- 取值说明:<br>
|
|
|
- * : 表示匹配该域的任意值。比如Minutes域使用*,就表示每分钟都会触发。<br>
|
|
|
- - : 表示范围。比如Minutes域使用 10-20,就表示从10分钟到20分钟每分钟都会触发一次。<br>
|
|
|
- , : 表示列出枚举值。比如Minutes域使用1,3,就表示1分钟和3分钟都会触发一次。<br>
|
|
|
- / : 表示间隔时间触发(开始时间/时间间隔)。例如在Minutes域使用 5/10,就表示从第5分钟开始,每隔10分钟触发一次。<br>
|
|
|
- ? : 表示不指定值。简单理解就是忽略该字段的值,直接根据另一个字段的值触发执行。<br>
|
|
|
- # : 表示该月第n个星期x(x#n),仅用星期域。如:星期:6#3,表示该月的第三个星期五。<br>
|
|
|
- L : 表示最后,是单词"last"的缩写(最后一天或最后一个星期几);仅出现在日和星期的域中。用在日则表示该月的最后一天,用在星期则表示该月的最后一个星期。如:星期域上的值为5L,则表示该月最后一个星期的星期四。在使用'L'时,不要指定列表','或范围'-',否则易导致出现意料之外的结果。<br>
|
|
|
- W: 仅用在日的域中,表示距离当月给定日期最近的工作日(周一到周五),是单词"weekday"的缩写。<br>
|
|
|
- </p>
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- </el-tab-pane>
|
|
|
- <el-tab-pane name="validator" label="校验器">
|
|
|
- <h5>最近10次的cron表达式执行时间:</h5>
|
|
|
- <el-input v-model="state.validatorCron">
|
|
|
- <template #append>
|
|
|
- <el-button @click="handleGenLatestCronTime(10)">生成执行计划</el-button>
|
|
|
- </template>
|
|
|
- </el-input>
|
|
|
-
|
|
|
- <el-row v-loading="state.validatorLoading">
|
|
|
- <el-col :sm="24" :md="24">{{state.cronDesc}}</el-col>
|
|
|
- <el-col :sm="24" :md="24" v-for="(item,idx) in state.latestCronTimeList" :key="idx">{{ item }}</el-col>
|
|
|
- </el-row>
|
|
|
- </el-tab-pane>
|
|
|
- </el-tabs>
|
|
|
- </div>
|
|
|
- <template #footer>
|
|
|
- <span class="dialog-footer">
|
|
|
- <el-button @click="state.tooltipVisible = false">关闭</el-button>
|
|
|
- <el-button type="primary" @click="handleChange">确定</el-button>
|
|
|
- </span>
|
|
|
- </template>
|
|
|
- </el-dialog>
|
|
|
- </div>
|
|
|
-
|
|
|
-
|
|
|
-</template>
|
|
|
-
|
|
|
-<script>
|
|
|
-import {reactive, computed, toRefs, defineComponent, ref, watch} from "vue";
|
|
|
-import ExtButton from "/@/components/form/ExtButton.vue";
|
|
|
-import {Msg} from "../../utils/message";
|
|
|
-import ExtClipboard from "/@/components/form/ExtClipboard.vue";
|
|
|
-import {$post} from "/@/utils/request.ts";
|
|
|
-
|
|
|
-import cronstrue from 'cronstrue/i18n';
|
|
|
-
|
|
|
-export default defineComponent({
|
|
|
- name: "ExtCron",
|
|
|
- components: {ExtClipboard, ExtButton},
|
|
|
- props: {
|
|
|
- i18n: {},
|
|
|
- maxHeight: String,
|
|
|
- change: Function,
|
|
|
- value: String,
|
|
|
- modelValue: String,
|
|
|
- disabled:Boolean
|
|
|
- },
|
|
|
- setup(props, {emit}) {
|
|
|
- const {i18n} = toRefs(props);
|
|
|
- const state = reactive({
|
|
|
- activeTab:'generator',
|
|
|
- validatorLoading:false,
|
|
|
- cronDesc:'',
|
|
|
- validatorCron:'',
|
|
|
- editorActiveTab: '秒',
|
|
|
- latestCronTimeList: [],
|
|
|
- modelData: '',
|
|
|
- language: i18n.value,
|
|
|
- tooltipVisible: false,
|
|
|
- second: {
|
|
|
- cronEvery: "1",
|
|
|
- incrementStart: 3,
|
|
|
- incrementIncrement: 5,
|
|
|
- rangeStart: 0,
|
|
|
- rangeEnd: 0,
|
|
|
- specificSpecific: [],
|
|
|
- },
|
|
|
- minute: {
|
|
|
- cronEvery: "1",
|
|
|
- incrementStart: 3,
|
|
|
- incrementIncrement: 5,
|
|
|
- rangeStart: 0,
|
|
|
- rangeEnd: 0,
|
|
|
- specificSpecific: [],
|
|
|
- },
|
|
|
- hour: {
|
|
|
- cronEvery: "1",
|
|
|
- incrementStart: 3,
|
|
|
- incrementIncrement: 5,
|
|
|
- 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: 3,
|
|
|
- incrementIncrement: 5,
|
|
|
- rangeStart: 1,
|
|
|
- rangeEnd: 1,
|
|
|
- specificSpecific: [],
|
|
|
- },
|
|
|
- year: {
|
|
|
- cronEvery: "1",
|
|
|
- incrementStart: 2022,
|
|
|
- incrementIncrement: 1,
|
|
|
- rangeStart: 1,
|
|
|
- rangeEnd: 1,
|
|
|
- specificSpecific: [],
|
|
|
- },
|
|
|
- output: {
|
|
|
- second: "",
|
|
|
- minute: "",
|
|
|
- hour: "",
|
|
|
- day: "",
|
|
|
- month: "",
|
|
|
- Week: "",
|
|
|
- year: "",
|
|
|
- },
|
|
|
- // text: computed(() => Language[state.language || "cn"]),
|
|
|
- text: {
|
|
|
- Seconds: {
|
|
|
- name: '秒',
|
|
|
- every: '每一秒钟',
|
|
|
- interval: ['每隔', '秒执行 ,从', '秒开始'],
|
|
|
- specific: '具体秒数(可多选)',
|
|
|
- cycle: ['周期从', '到', '秒']
|
|
|
- },
|
|
|
- Minutes: {
|
|
|
- name: '分',
|
|
|
- every: '每一分钟',
|
|
|
- interval: ['每隔', '分执行 ,从', '分开始'],
|
|
|
- specific: '具体分钟数(可多选)',
|
|
|
- cycle: ['周期从', '到', '分']
|
|
|
- },
|
|
|
- Hours: {
|
|
|
- name: '时',
|
|
|
- every: '每一小时',
|
|
|
- interval: ['每隔', '小时执行 ,从', '小时开始'],
|
|
|
- specific: '具体小时数(可多选)',
|
|
|
- cycle: ['周期从', '到', '小时']
|
|
|
- },
|
|
|
- Day: {
|
|
|
- name: '天',
|
|
|
- every: '每一天',
|
|
|
- intervalWeek: ['每隔', '周执行 ,从', '开始'],
|
|
|
- intervalDay: ['每隔', '天执行 ,从', '天开始'],
|
|
|
- specificWeek: '具体星期几(可多选)',
|
|
|
- specificDay: '具体天数(可多选)',
|
|
|
- lastDay: '在这个月的最后一天',
|
|
|
- lastWeekday: '在这个月的最后一个工作日',
|
|
|
- lastWeek: ['在这个月的最后一个'],
|
|
|
- beforeEndMonth: ['在本月底前', '天'],
|
|
|
- nearestWeekday: ['最近的工作日(周一至周五)至本月', '日'],
|
|
|
- someWeekday: ['在这个月的第', '个'],
|
|
|
- },
|
|
|
- Week: ['天', '一', '二', '三', '四', '五', '六'].map(val => '星期' + val),
|
|
|
- Month: {
|
|
|
- name: '月',
|
|
|
- every: '每一月',
|
|
|
- interval: ['每隔', '月执行 从', '月开始'],
|
|
|
- specific: '具体月数(可多选)',
|
|
|
- cycle: ['从', '到', '月之间的每个月']
|
|
|
- },
|
|
|
- Year: {
|
|
|
- name: '年',
|
|
|
- every: '每一年',
|
|
|
- interval: ['每隔', '年执行 从', '年开始'],
|
|
|
- specific: '具体年份(可多选)',
|
|
|
- cycle: ['从', '到', '年之间的每一年']
|
|
|
- },
|
|
|
- Save: '保存',
|
|
|
- Check: '校验',
|
|
|
- },
|
|
|
- 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;
|
|
|
- console.log(cronEvery)
|
|
|
- switch (cronEvery.toString()) {
|
|
|
- case "1":
|
|
|
- break;
|
|
|
- case "2":
|
|
|
- case "4":
|
|
|
- case "11":
|
|
|
- days = "?";
|
|
|
- break;
|
|
|
- case "3":
|
|
|
- days = state.day.rangeStart + "/" + state.day.rangeEnd;
|
|
|
- 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 = "";
|
|
|
- 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 cron = `${state.secondsText || "*"} ${state.minutesText || "*"} ${state.hoursText || "*"} ${state.daysText || "*"} ${state.monthsText || "*"} ${state.weeksText || "?"} ${
|
|
|
- state.yearsText || "*"
|
|
|
- }`;
|
|
|
-
|
|
|
- return cron;
|
|
|
- }),
|
|
|
- });
|
|
|
-
|
|
|
- const handleGenLatestCronTime = () => {
|
|
|
- if (!state.validatorCron) {
|
|
|
- Msg.message('cron表达式为空', 'error');
|
|
|
- return;
|
|
|
- }
|
|
|
- let cronText = state.validatorCron.trim()
|
|
|
- let cs = cronstrue.toString(cronText, {locale: 'zh_CN'})
|
|
|
- console.log(cs)
|
|
|
-
|
|
|
- state.cronDesc = cs;
|
|
|
- $post('checkCron',{cron:cronText}).then(res=>{
|
|
|
- state.latestCronTimeList = res;
|
|
|
- state.validatorLoading = false;
|
|
|
- }).catch((e)=>{
|
|
|
- console.error(e)
|
|
|
- state.validatorLoading = false;
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- const handleCheck= () => {
|
|
|
- state.activeTab='validator';
|
|
|
- state.validatorCron = state.cron;
|
|
|
- handleGenLatestCronTime()
|
|
|
- };
|
|
|
-
|
|
|
- const handleChange = () => {
|
|
|
- if(props.disabled){
|
|
|
- state.tooltipVisible = false;
|
|
|
- return false;
|
|
|
- }
|
|
|
- if (typeof state.cron !== "string") return false;
|
|
|
- emit("update:modelValue", state.cron);
|
|
|
- emit("on-change", state.cron);
|
|
|
- state.modelData = state.cron;
|
|
|
- state.tooltipVisible = false;
|
|
|
- };
|
|
|
- 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;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- const tabActive = ref(1);
|
|
|
- const currYear = new Date().getFullYear() - 1;
|
|
|
- const onHandleTab = (index) => {
|
|
|
- tabActive.value = index;
|
|
|
- };
|
|
|
-
|
|
|
- watch(
|
|
|
- () => state.cron,
|
|
|
- (value) => {
|
|
|
- if (typeof state.cron !== "string") return;
|
|
|
- emit("update:modelValue", value);
|
|
|
- emit("on-change", value);
|
|
|
- }
|
|
|
- );
|
|
|
-
|
|
|
-
|
|
|
- watch(
|
|
|
- () => props.modelValue,
|
|
|
- (value) => {
|
|
|
- state.modelData = value;
|
|
|
- }
|
|
|
- );
|
|
|
-
|
|
|
-
|
|
|
- return {
|
|
|
- state,
|
|
|
- handleChange,
|
|
|
- handleCheck,
|
|
|
- handleGenLatestCronTime,
|
|
|
- rest,
|
|
|
- tabActive,
|
|
|
- onHandleTab,
|
|
|
- currYear,
|
|
|
- };
|
|
|
- },
|
|
|
-});
|
|
|
-</script>
|
|
|
-
|
|
|
-<style lang="css" scoped>
|
|
|
-.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: 10px;
|
|
|
-}
|
|
|
-
|
|
|
-.v3c-tab-item.v3c-active {
|
|
|
- background-color: #5b8ff9;
|
|
|
- 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;
|
|
|
-}
|
|
|
-
|
|
|
-.mt-20 {
|
|
|
- margin-top: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.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;
|
|
|
-}
|
|
|
-
|
|
|
-.cron {
|
|
|
- color: #61ddaa;
|
|
|
- padding: 5px;
|
|
|
- padding-left: 10px;
|
|
|
- padding-right: 10px;
|
|
|
-}
|
|
|
-</style>
|