123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661 |
- <template>
- <div class="vue3-cron-div">
- <!-- <el-button class="language" type="text" @click="state.language = state.language === 'en' ? 'cn' : 'en'">{{
- state.language === 'en' ? 'cn' : 'en'
- }}</el-button> -->
- <el-tabs type="border-card">
- <el-tab-pane>
- <template #label>
- <span><i class="el-icon-date"></i> {{ state.text.Seconds.name }}</span>
- </template>
- <div class="tabBody myScroller" :style="{ 'max-height': maxHeight }">
- <el-row>
- <el-radio v-model="state.second.cronEvery" label="1">{{ state.text.Seconds.every }}</el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.second.cronEvery" label="2">{{ state.text.Seconds.interval[0] }}
- <el-input-number size="small" v-model="state.second.incrementIncrement" :min="1" :max="60"></el-input-number>
- {{ state.text.Seconds.interval[1] || '' }}
- <el-input-number size="small" v-model="state.second.incrementStart" :min="0" :max="59"></el-input-number>
- {{ state.text.Seconds.interval[2] || '' }}
- </el-radio>
- </el-row>
- <el-row>
- <el-radio class="long" v-model="state.second.cronEvery" label="3">{{ state.text.Seconds.specific }}
- <el-select size="small" multiple v-model="state.second.specificSpecific">
- <el-option v-for="(val, index) in 60" :key="index" :value="val - 1">{{
- val - 1
- }}</el-option>
- </el-select>
- </el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.second.cronEvery" label="4">{{ state.text.Seconds.cycle[0] }}
- <el-input-number size="small" v-model="state.second.rangeStart" :min="1" :max="60"></el-input-number>
- {{ state.text.Seconds.cycle[1] || '' }}
- <el-input-number size="small" v-model="state.second.rangeEnd" :min="0" :max="59"></el-input-number>
- {{ state.text.Seconds.cycle[2] || '' }}
- </el-radio>
- </el-row>
- </div>
- </el-tab-pane>
- <el-tab-pane>
- <template #label>
- <span><i class="el-icon-date"></i> {{ state.text.Minutes.name }}</span>
- </template>
- <div class="tabBody myScroller" :style="{ 'max-height': maxHeight }">
- <el-row>
- <el-radio v-model="state.minute.cronEvery" label="1">{{ state.text.Minutes.every }}</el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.minute.cronEvery" label="2">{{ state.text.Minutes.interval[0] }}
- <el-input-number size="small" v-model="state.minute.incrementIncrement" :min="1" :max="60"></el-input-number>
- {{ state.text.Minutes.interval[1] }}
- <el-input-number size="small" v-model="state.minute.incrementStart" :min="0" :max="59"></el-input-number>
- {{ state.text.Minutes.interval[2] || '' }}
- </el-radio>
- </el-row>
- <el-row>
- <el-radio class="long" v-model="state.minute.cronEvery" label="3">{{ state.text.Minutes.specific }}
- <el-select size="small" multiple v-model="state.minute.specificSpecific">
- <el-option v-for="(val, index) in 60" :key="index" :value="val - 1">{{
- val - 1
- }}</el-option>
- </el-select>
- </el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.minute.cronEvery" label="4">{{ state.text.Minutes.cycle[0] }}
- <el-input-number size="small" v-model="state.minute.rangeStart" :min="1" :max="60"></el-input-number>
- {{ state.text.Minutes.cycle[1] }}
- <el-input-number size="small" v-model="state.minute.rangeEnd" :min="0" :max="59"></el-input-number>
- {{ state.text.Minutes.cycle[2] }}
- </el-radio>
- </el-row>
- </div>
- </el-tab-pane>
- <el-tab-pane>
- <template #label>
- <span><i class="el-icon-date"></i> {{ state.text.Hours.name }}</span>
- </template>
- <div class="tabBody myScroller" :style="{ 'max-height': maxHeight }">
- <el-row>
- <el-radio v-model="state.hour.cronEvery" label="1">{{ state.text.Hours.every }}</el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.hour.cronEvery" label="2">{{ state.text.Hours.interval[0] }}
- <el-input-number size="small" v-model="state.hour.incrementIncrement" :min="0" :max="23"></el-input-number>
- {{ state.text.Hours.interval[1] }}
- <el-input-number size="small" v-model="state.hour.incrementStart" :min="0" :max="23"></el-input-number>
- {{ state.text.Hours.interval[2] }}
- </el-radio>
- </el-row>
- <el-row>
- <el-radio class="long" v-model="state.hour.cronEvery" label="3">{{ state.text.Hours.specific }}
- <el-select size="small" multiple v-model="state.hour.specificSpecific">
- <el-option v-for="(val, index) in 24" :key="index" :value="val - 1">{{
- val - 1
- }}</el-option>
- </el-select>
- </el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.hour.cronEvery" label="4">{{ state.text.Hours.cycle[0] }}
- <el-input-number size="small" v-model="state.hour.rangeStart" :min="0" :max="23"></el-input-number>
- {{ state.text.Hours.cycle[1] }}
- <el-input-number size="small" v-model="state.hour.rangeEnd" :min="0" :max="23"></el-input-number>
- {{ state.text.Hours.cycle[2] }}
- </el-radio>
- </el-row>
- </div>
- </el-tab-pane>
- <el-tab-pane>
- <template #label>
- <span><i class="el-icon-date"></i> {{ state.text.Day.name }}</span>
- </template>
- <div class="tabBody myScroller" :style="{ 'max-height': maxHeight }">
- <el-row>
- <el-radio v-model="state.day.cronEvery" label="1">{{ state.text.Day.every }}</el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.day.cronEvery" label="2">{{ state.text.Day.intervalWeek[0] }}
- <el-input-number size="small" v-model="state.week.incrementIncrement" :min="1" :max="7"></el-input-number>
- {{ state.text.Day.intervalWeek[1] }}
- <el-select size="small" v-model="state.week.incrementStart">
- <el-option v-for="(val, index) in 7" :key="index" :label="state.text.Week[val - 1]" :value="val"></el-option>
- </el-select>
- {{ state.text.Day.intervalWeek[2] }}
- </el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.day.cronEvery" label="3">{{ state.text.Day.intervalDay[0] }}
- <el-input-number size="small" v-model="state.day.incrementIncrement" :min="1" :max="31"></el-input-number>
- {{ state.text.Day.intervalDay[1] }}
- <el-input-number size="small" v-model="state.day.incrementStart" :min="1" :max="31"></el-input-number>
- {{ state.text.Day.intervalDay[2] }}
- </el-radio>
- </el-row>
- <el-row>
- <el-radio class="long" v-model="state.day.cronEvery" label="4">{{ state.text.Day.specificWeek }}
- <el-select size="small" multiple v-model="state.week.specificSpecific">
- <el-option v-for="(val, index) in 7" :key="index" :label="state.text.Week[val - 1]" :value="['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'][val - 1]"></el-option>
- </el-select>
- </el-radio>
- </el-row>
- <el-row>
- <el-radio class="long" v-model="state.day.cronEvery" label="5">{{ state.text.Day.specificDay }}
- <el-select size="small" multiple v-model="state.day.specificSpecific">
- <el-option v-for="(val, index) in 31" :key="index" :value="val">{{ val }}</el-option>
- </el-select>
- </el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.day.cronEvery" label="6">{{ state.text.Day.lastDay }}</el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.day.cronEvery" label="7">{{ state.text.Day.lastWeekday }}</el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.day.cronEvery" label="8">{{ state.text.Day.lastWeek[0] }}
- <el-select size="small" v-model="state.day.cronLastSpecificDomDay">
- <el-option v-for="(val, index) in 7" :key="index" :label="state.text.Week[val - 1]" :value="val"></el-option>
- </el-select>
- {{ state.text.Day.lastWeek[1] || '' }}
- </el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.day.cronEvery" label="9">
- <el-input-number size="small" v-model="state.day.cronDaysBeforeEomMinus" :min="1" :max="31"></el-input-number>
- {{ state.text.Day.beforeEndMonth[0] }}
- </el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.day.cronEvery" label="10">{{ state.text.Day.nearestWeekday[0] }}
- <el-input-number size="small" v-model="state.day.cronDaysNearestWeekday" :min="1" :max="31"></el-input-number>
- {{ state.text.Day.nearestWeekday[1] }}
- </el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.day.cronEvery" label="11">{{ state.text.Day.someWeekday[0] }}
- <el-input-number size="small" v-model="state.week.cronNthDayNth" :min="1" :max="5"></el-input-number>
- <el-select size="small" v-model="state.week.cronNthDayDay">
- <el-option v-for="(val, index) in 7" :key="index" :label="state.text.Week[val - 1]" :value="val"></el-option>
- </el-select>
- {{ state.text.Day.someWeekday[1] }}
- </el-radio>
- </el-row>
- </div>
- </el-tab-pane>
- <el-tab-pane>
- <template #label>
- <span><i class="el-icon-date"></i> {{ state.text.Month.name }}</span>
- </template>
- <div class="tabBody myScroller" :style="{ 'max-height': maxHeight }">
- <el-row>
- <el-radio v-model="state.month.cronEvery" label="1">{{ state.text.Month.every }}</el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.month.cronEvery" label="2">{{ state.text.Month.interval[0] }}
- <el-input-number size="small" v-model="state.month.incrementIncrement" :min="0" :max="12"></el-input-number>
- {{ state.text.Month.interval[1] }}
- <el-input-number size="small" v-model="state.month.incrementStart" :min="0" :max="12"></el-input-number>
- </el-radio>
- </el-row>
- <el-row>
- <el-radio class="long" v-model="state.month.cronEvery" label="3">{{ state.text.Month.specific }}
- <el-select size="small" multiple v-model="state.month.specificSpecific">
- <el-option v-for="(val, index) in 12" :key="index" :label="val" :value="val"></el-option>
- </el-select>
- </el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.month.cronEvery" label="4">{{ state.text.Month.cycle[0] }}
- <el-input-number size="small" v-model="state.month.rangeStart" :min="1" :max="12"></el-input-number>
- {{ state.text.Month.cycle[1] }}
- <el-input-number size="small" v-model="state.month.rangeEnd" :min="1" :max="12"></el-input-number>
- </el-radio>
- </el-row>
- </div>
- </el-tab-pane>
- <el-tab-pane>
- <template #label>
- <span><i class="el-icon-date"></i> {{ state.text.Year.name }}</span>
- </template>
- <div class="tabBody myScroller" :style="{ 'max-height': maxHeight }">
- <el-row>
- <el-radio v-model="state.year.cronEvery" label="1">{{ state.text.Year.every }}</el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.year.cronEvery" label="2">{{ state.text.Year.interval[0] }}
- <el-input-number size="small" v-model="state.year.incrementIncrement" :min="1" :max="99"></el-input-number>
- {{ state.text.Year.interval[1] }}
- <el-input-number size="small" v-model="state.year.incrementStart" :min="2018" :max="2118"></el-input-number>
- </el-radio>
- </el-row>
- <el-row>
- <el-radio class="long" v-model="state.year.cronEvery" label="3">{{ state.text.Year.specific }}
- <el-select size="small" filterable multiple v-model="state.year.specificSpecific">
- <el-option v-for="(val, index) in 100" :key="index" :label="2017 + val" :value="2017 + val"></el-option>
- </el-select>
- </el-radio>
- </el-row>
- <el-row>
- <el-radio v-model="state.year.cronEvery" label="4">{{ state.text.Year.cycle[0] }}
- <el-input-number size="small" v-model="state.year.rangeStart" :min="2018" :max="2118"></el-input-number>
- {{ state.text.Year.cycle[1] }}
- <el-input-number size="small" v-model="state.year.rangeEnd" :min="2018" :max="2118"></el-input-number>
- </el-radio>
- </el-row>
- </div>
- </el-tab-pane>
- </el-tabs>
- <div class="bottom">
- <div class="value" style="margin: 10px;">
- <span> cron预览: </span>
- <el-tag type="primary">
- {{ state.cron }}
- </el-tag>
- </div>
- <div class="buttonDiv" style="text-align: right;">
- <el-button type="primary" size="mini" @click.stop="handleChange">{{ state.text.Save }}</el-button>
- <el-button type="primary" size="mini" @click="close">{{ state.text.Close }}</el-button>
- </div>
- </div>
- </div>
- </template>
- <script>
- import Language from './language';
- import { reactive, computed, toRefs, defineComponent } from 'vue';
- export default defineComponent({
- name: 'vue3Cron',
- props: {
- cronValue: {},
- type: '',
- i18n: {},
- maxHeight: {}
- },
- setup(props, { emit }) {
- const { i18n } = toRefs(props);
- const state = reactive({
- language: i18n.value,
- 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: 0
- },
- week: {
- cronEvery: '1',
- incrementStart: 1,
- incrementIncrement: 1,
- specificSpecific: [],
- cronNthDayDay: 1,
- cronNthDayNth: 1
- },
- month: {
- cronEvery: '1',
- incrementStart: 3,
- incrementIncrement: 5,
- rangeStart: 0,
- rangeEnd: 0,
- specificSpecific: []
- },
- year: {
- cronEvery: '1',
- incrementStart: 2017,
- incrementIncrement: 1,
- rangeStart: 0,
- rangeEnd: 0,
- specificSpecific: []
- },
- output: {
- second: '',
- minute: '',
- hour: '',
- day: '',
- month: '',
- Week: '',
- year: ''
- },
- text: computed(() => Language[state.language || 'cn']),
- 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(() => {
- 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 getValue = () => {
- return state.cron;
- };
- const close = () => {
- emit('close');
- };
- const handleChange = () => {
- emit('handlelisten', {
- cron: state.cron,
- type: props.type
- });
- close();
- };
- 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;
- }
- }
- }
- };
- return {
- state,
- getValue,
- close,
- handleChange,
- rest
- };
- }
- });
- </script>
- <style >
- .vue3-cron-div {
- .el-input-number__decrease,
- .el-input-number__increase {
- top: 2px !important;
- }
- .language {
- position: absolute;
- right: 25px;
- z-index: 1;
- }
- .el-tabs {
- box-shadow: none;
- }
- .tabBody {
- overflow: auto;
- .el-row {
- margin: 20px 0;
- .long {
- .el-select {
- width: 350px;
- }
- }
- .el-input-number {
- width: 110px;
- }
- }
- }
- .myScroller {
- &::-webkit-scrollbar {
- /*滚动条整体样式*/
- width: 5px;
- /*高宽分别对应横竖滚动条的尺寸*/
- height: 1px;
- }
- &::-webkit-scrollbar-thumb {
- /*滚动条里面小方块*/
- border-radius: 10px;
- background-color: skyblue;
- background-image: -webkit-linear-gradient(45deg,
- rgba(255, 255, 255, 0.2) 25%,
- transparent 25%,
- transparent 50%,
- rgba(255, 255, 255, 0.2) 50%,
- rgba(255, 255, 255, 0.2) 75%,
- transparent 75%,
- transparent);
- }
- &::-webkit-scrollbar-track {
- /*滚动条里面轨道*/
- box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
- background: #ededed;
- border-radius: 10px;
- }
- }
- .bottom {
- width: 100%;
- margin-top: 5px;
- display: flex;
- align-items: center;
- justify-content: space-around;
- .value {
- float: left;
- font-size: 14px;
- vertical-align: middle;
- span:nth-child(1) {
- color: red;
- }
- }
- }
- }
- </style>
|