Devosend
3 years ago
committed by
GitHub
10 changed files with 1500 additions and 10 deletions
@ -0,0 +1,193 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import _ from 'lodash' |
||||
|
||||
const timeI18n = { |
||||
second: { |
||||
everyTime: 'crontab.every_second', |
||||
every: 'crontab.every', |
||||
timeCarriedOut: 'crontab.second_carried_out', |
||||
timeStart: 'crontab.second_start', |
||||
cycleFrom: 'crontab.cycle_from', |
||||
specificTime: 'crontab.specific_second', |
||||
specificTimeTip: 'crontab.specific_second_tip', |
||||
to: 'crontab.to', |
||||
time: 'crontab.second' |
||||
}, |
||||
minute: { |
||||
everyTime: 'crontab.every_minute', |
||||
every: 'crontab.every', |
||||
timeCarriedOut: 'crontab.minute_carried_out', |
||||
timeStart: 'crontab.minute_start', |
||||
cycleFrom: 'crontab.cycle_from', |
||||
specificTime: 'crontab.specific_minute', |
||||
specificTimeTip: 'crontab.specific_minute_tip', |
||||
to: 'crontab.to', |
||||
time: 'crontab.minute' |
||||
}, |
||||
hour: { |
||||
everyTime: 'crontab.every_hour', |
||||
every: 'crontab.every', |
||||
timeCarriedOut: 'crontab.hour_carried_out', |
||||
timeStart: 'crontab.hour_start', |
||||
cycleFrom: 'crontab.cycle_from', |
||||
specificTime: 'crontab.specific_hour', |
||||
specificTimeTip: 'crontab.specific_hour_tip', |
||||
to: 'crontab.to', |
||||
time: 'crontab.hour' |
||||
}, |
||||
month: { |
||||
everyTime: 'crontab.every_month', |
||||
every: 'crontab.every', |
||||
timeCarriedOut: 'crontab.month_carried_out', |
||||
timeStart: 'crontab.month_start', |
||||
cycleFrom: 'crontab.cycle_from', |
||||
specificTime: 'crontab.specific_month', |
||||
specificTimeTip: 'crontab.specific_month_tip', |
||||
to: 'crontab.to', |
||||
time: 'crontab.month' |
||||
}, |
||||
year: { |
||||
everyTime: 'crontab.every_year', |
||||
every: 'crontab.every', |
||||
timeCarriedOut: 'crontab.year_carried_out', |
||||
timeStart: 'crontab.year_start', |
||||
cycleFrom: 'crontab.cycle_from', |
||||
specificTime: 'crontab.specific_year', |
||||
specificTimeTip: 'crontab.specific_year_tip', |
||||
to: 'crontab.to', |
||||
time: 'crontab.year' |
||||
} |
||||
} |
||||
|
||||
const week = [ |
||||
{ |
||||
label: 'crontab.sunday', |
||||
value: 1 |
||||
}, |
||||
{ |
||||
label: 'crontab.monday', |
||||
value: 2 |
||||
}, |
||||
{ |
||||
label: 'crontab.tuesday', |
||||
value: 3 |
||||
}, |
||||
{ |
||||
label: 'crontab.wednesday', |
||||
value: 4 |
||||
}, |
||||
{ |
||||
label: 'crontab.thursday', |
||||
value: 5 |
||||
}, |
||||
{ |
||||
label: 'crontab.friday', |
||||
value: 6 |
||||
}, |
||||
{ |
||||
label: 'crontab.saturday', |
||||
value: 7 |
||||
} |
||||
] |
||||
|
||||
const specificWeek = [ |
||||
{ |
||||
label: 'SUN', |
||||
value: 'SUN' |
||||
}, |
||||
{ |
||||
label: 'MON', |
||||
value: 'MON' |
||||
}, |
||||
{ |
||||
label: 'TUE', |
||||
value: 'TUE' |
||||
}, |
||||
{ |
||||
label: 'WED', |
||||
value: 'WED' |
||||
}, |
||||
{ |
||||
label: 'THU', |
||||
value: 'THU' |
||||
}, |
||||
{ |
||||
label: 'FRI', |
||||
value: 'FRI' |
||||
}, |
||||
{ |
||||
label: 'SAT', |
||||
value: 'SAT' |
||||
} |
||||
] |
||||
|
||||
const lastWeeks = [ |
||||
{ |
||||
label: 'crontab.sunday', |
||||
value: '?' |
||||
}, |
||||
{ |
||||
label: 'crontab.monday', |
||||
value: '2L' |
||||
}, |
||||
{ |
||||
label: 'crontab.tuesday', |
||||
value: '3L' |
||||
}, |
||||
{ |
||||
label: 'crontab.wednesday', |
||||
value: '4L' |
||||
}, |
||||
{ |
||||
label: 'crontab.thursday', |
||||
value: '5L' |
||||
}, |
||||
{ |
||||
label: 'crontab.friday', |
||||
value: '6L' |
||||
}, |
||||
{ |
||||
label: 'crontab.saturday', |
||||
value: '7L' |
||||
} |
||||
] |
||||
|
||||
const isStr = (str: string, v: string) => { |
||||
let flag |
||||
if (str.indexOf(v) !== -1) { |
||||
flag = str.split(v) |
||||
} |
||||
return flag |
||||
} |
||||
|
||||
const isWeek = (str: string) => { |
||||
let flag = false |
||||
const data = str.split(',') |
||||
const isSpecificWeek = (key: string) => { |
||||
return _.findIndex(specificWeek, (v) => v.value === key) !== -1 |
||||
} |
||||
_.map(data, (v) => { |
||||
if (isSpecificWeek(v)) { |
||||
flag = true |
||||
} |
||||
}) |
||||
return flag |
||||
} |
||||
|
||||
export { isStr, isWeek, timeI18n, week, specificWeek, lastWeeks } |
@ -0,0 +1,29 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
.crontab-list { |
||||
display: flex; |
||||
.crontab-list-item { |
||||
display: flex; |
||||
vertical-align: middle; |
||||
align-items: center; |
||||
width: 460px; |
||||
> div { |
||||
margin: 5px; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,131 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import { computed, defineComponent, ref, watch, PropType } from 'vue' |
||||
import { NTabPane, NTabs } from 'naive-ui' |
||||
import { useI18n } from 'vue-i18n' |
||||
import CrontabTime from './modules/time' |
||||
import CrontabDay from './modules/day' |
||||
import { timeI18n } from './common' |
||||
|
||||
const props = { |
||||
value: { |
||||
type: String as PropType<String>, |
||||
default: '* * * * * ? *' |
||||
} |
||||
} |
||||
|
||||
export default defineComponent({ |
||||
name: 'Crontab', |
||||
props, |
||||
emits: ['update:value'], |
||||
setup(props, ctx) { |
||||
const cron = props.value.split(' ') |
||||
const secondRef = ref(cron[0]) |
||||
const minuteRef = ref(cron[1]) |
||||
const hourRef = ref(cron[2]) |
||||
const dayRef = ref(cron[3]) |
||||
const monthRef = ref(cron[4]) |
||||
const weekRef = ref(cron[5]) |
||||
const yearRef = ref(cron[6]) |
||||
|
||||
const crontabValue = computed( |
||||
() => |
||||
`${secondRef.value} ${minuteRef.value} ${hourRef.value} ${dayRef.value} ${monthRef.value} ${weekRef.value} ${yearRef.value}` |
||||
) |
||||
|
||||
const reset = () => { |
||||
const cron = props.value.split(' ') |
||||
secondRef.value = cron[0] |
||||
minuteRef.value = cron[1] |
||||
hourRef.value = cron[2] |
||||
dayRef.value = cron[3] |
||||
monthRef.value = cron[4] |
||||
weekRef.value = cron[5] |
||||
yearRef.value = cron[6] |
||||
} |
||||
|
||||
watch( |
||||
() => crontabValue.value, |
||||
() => { |
||||
ctx.emit('update:value', crontabValue.value) |
||||
} |
||||
) |
||||
|
||||
watch( |
||||
() => props.value, |
||||
() => { |
||||
reset() |
||||
} |
||||
) |
||||
|
||||
return { |
||||
secondRef, |
||||
minuteRef, |
||||
hourRef, |
||||
dayRef, |
||||
weekRef, |
||||
monthRef, |
||||
yearRef, |
||||
crontabValue |
||||
} |
||||
}, |
||||
render() { |
||||
const { t } = useI18n() |
||||
|
||||
return ( |
||||
<NTabs type='line'> |
||||
<NTabPane name='seconde' tab={t('crontab.second')}> |
||||
<CrontabTime |
||||
v-model:timeValue={this.secondRef} |
||||
timeI18n={timeI18n.second} |
||||
/> |
||||
</NTabPane> |
||||
<NTabPane name='minute' tab={t('crontab.minute')}> |
||||
<CrontabTime |
||||
v-model:timeValue={this.minuteRef} |
||||
timeI18n={timeI18n.minute} |
||||
/> |
||||
</NTabPane> |
||||
<NTabPane name='hour' tab={t('crontab.hour')}> |
||||
<CrontabTime |
||||
v-model:timeValue={this.hourRef} |
||||
timeI18n={timeI18n.hour} |
||||
/> |
||||
</NTabPane> |
||||
<NTabPane name='day' tab={t('crontab.day')}> |
||||
<CrontabDay |
||||
v-model:dayValue={this.dayRef} |
||||
v-model:weekValue={this.weekRef} |
||||
/> |
||||
</NTabPane> |
||||
<NTabPane name='month' tab={t('crontab.month')}> |
||||
<CrontabTime |
||||
v-model:timeValue={this.monthRef} |
||||
timeI18n={timeI18n.month} |
||||
/> |
||||
</NTabPane> |
||||
<NTabPane name='year' tab={t('crontab.year')}> |
||||
<CrontabTime |
||||
v-model:timeValue={this.yearRef} |
||||
timeI18n={timeI18n.year} |
||||
/> |
||||
</NTabPane> |
||||
</NTabs> |
||||
) |
||||
} |
||||
}) |
@ -0,0 +1,640 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import { defineComponent, onMounted, PropType, ref, watch } from 'vue' |
||||
import { NInputNumber, NRadio, NRadioGroup, NSelect } from 'naive-ui' |
||||
import { useI18n } from 'vue-i18n' |
||||
import { isStr, isWeek, week, specificWeek, lastWeeks } from '../common' |
||||
import styles from '../index.module.scss' |
||||
|
||||
const props = { |
||||
dayValue: { |
||||
type: String as PropType<string>, |
||||
default: '*' |
||||
}, |
||||
weekValue: { |
||||
type: String as PropType<string>, |
||||
default: '?' |
||||
} |
||||
} |
||||
|
||||
export default defineComponent({ |
||||
name: 'CrontabDay', |
||||
props, |
||||
emits: ['update:dayValue', 'update:weekValue'], |
||||
setup(props, ctx) { |
||||
const { t } = useI18n() |
||||
|
||||
const options = Array.from({ length: 60 }, (x, i) => ({ |
||||
label: i.toString(), |
||||
value: i |
||||
})) |
||||
|
||||
const weekOptions = week.map((v) => ({ |
||||
label: t(v.label), |
||||
value: v.value |
||||
})) |
||||
|
||||
const lastWeekOptions = lastWeeks.map((v) => ({ |
||||
label: t(v.label), |
||||
value: v.value |
||||
})) |
||||
|
||||
const radioRef = ref() |
||||
const dayRef = ref() |
||||
const weekRef = ref() |
||||
const WkintervalWeekStartRef = ref(2) |
||||
const WkintervalWeekPerformRef = ref(2) |
||||
const intervalDayStartRef = ref(1) |
||||
const intervalDayPerformRef = ref(1) |
||||
const WkspecificDayRef = ref<Array<number>>([]) |
||||
const WkspecificWeekRef = ref<Array<number>>([]) |
||||
const monthLastDaysRef = ref('L') |
||||
const monthLastWorkingDaysRef = ref('LW') |
||||
const monthLastWeeksRef = ref('?') |
||||
const monthTailBeforeRef = ref(1) |
||||
const recentlyWorkingDaysMonthRef = ref(1) |
||||
const WkmonthNumWeeksDayRef = ref(1) |
||||
const WkmonthNumWeeksWeekRef = ref(1) |
||||
|
||||
/** |
||||
* Parse parameter value |
||||
*/ |
||||
const analyticalValue = () => { |
||||
const $dayVal = props.dayValue |
||||
const $weekVal = props.weekValue |
||||
const isWeek1 = $weekVal.indexOf('/') !== -1 |
||||
const isWeek2 = $weekVal.indexOf('#') !== -1 |
||||
|
||||
// Initialization
|
||||
if ($dayVal === '*' && $weekVal === '?') { |
||||
radioRef.value = 'everyDay' |
||||
return |
||||
} |
||||
|
||||
// week
|
||||
if (isWeek1 || isWeek2 || isWeek($weekVal)) { |
||||
dayRef.value = '?' |
||||
|
||||
/** |
||||
* Processing by sequence number (excluding days) |
||||
* @param [ |
||||
* WkintervalWeek=>(/), |
||||
* WkspecificWeek=>(TUE,WED), |
||||
* WkmonthNumWeeks=>(#) |
||||
* ] |
||||
*/ |
||||
const hanleWeekOne = () => { |
||||
const a = isStr($weekVal, '/') as string[] |
||||
WkintervalWeekStartRef.value = parseInt(a[0]) |
||||
WkintervalWeekPerformRef.value = parseInt(a[1]) |
||||
dayRef.value = '?' |
||||
weekRef.value = `${WkintervalWeekPerformRef.value}/${WkintervalWeekStartRef.value}` |
||||
radioRef.value = 'WkintervalWeek' |
||||
} |
||||
|
||||
const hanleWeekTwo = () => { |
||||
WkspecificWeekRef.value = $weekVal |
||||
.split(',') |
||||
.map((item) => parseInt(item)) |
||||
radioRef.value = 'WkspecificWeek' |
||||
} |
||||
|
||||
const hanleWeekThree = () => { |
||||
const a = isStr($weekVal, '#') as string[] |
||||
WkmonthNumWeeksDayRef.value = parseInt(a[0]) |
||||
WkmonthNumWeeksDayRef.value = parseInt(a[1]) |
||||
radioRef.value = 'WkmonthNumWeeks' |
||||
} |
||||
|
||||
// Processing week
|
||||
if (isStr($weekVal, '/')) { |
||||
hanleWeekOne() |
||||
} else if (isStr($weekVal, '#')) { |
||||
hanleWeekThree() |
||||
} else if (isWeek($weekVal)) { |
||||
hanleWeekTwo() |
||||
} |
||||
} else { |
||||
weekRef.value = '?' |
||||
|
||||
/** |
||||
* Processing by sequence number (excluding week) |
||||
* @param [ |
||||
* everyDay=>(*), |
||||
* intervalDay=>(1/1), |
||||
* specificDay=>(1,2,5,3,4), |
||||
* monthLastDays=>(L), |
||||
* monthLastWorkingDays=>(LW), |
||||
* monthLastWeeks=>(3L), |
||||
* monthTailBefore=>(L-4), |
||||
* recentlyWorkingDaysMonth=>(6W) |
||||
* ] |
||||
*/ |
||||
const hanleDayOne = () => { |
||||
radioRef.value = 'everyDay' |
||||
} |
||||
|
||||
const hanleDayTwo = () => { |
||||
const a = isStr($dayVal, '/') as string[] |
||||
intervalDayStartRef.value = parseInt(a[0]) |
||||
intervalDayPerformRef.value = parseInt(a[1]) |
||||
radioRef.value = 'intervalDay' |
||||
} |
||||
|
||||
const hanleDayThree = () => { |
||||
WkspecificDayRef.value = $dayVal |
||||
.split(',') |
||||
.map((item) => parseInt(item)) |
||||
radioRef.value = 'specificDay' |
||||
} |
||||
|
||||
const hanleDayFour = () => { |
||||
radioRef.value = 'monthLastDays' |
||||
} |
||||
|
||||
const hanleDayFive = () => { |
||||
radioRef.value = 'monthLastWorkingDays' |
||||
} |
||||
|
||||
const hanleDaySix = () => { |
||||
monthLastWeeksRef.value = $dayVal |
||||
radioRef.value = 'monthLastWeeks' |
||||
} |
||||
|
||||
const hanleDaySeven = () => { |
||||
const a = isStr($dayVal, '-') as string[] |
||||
monthTailBeforeRef.value = parseInt(a[1]) |
||||
radioRef.value = 'monthTailBefore' |
||||
} |
||||
|
||||
const hanleDayEight = () => { |
||||
recentlyWorkingDaysMonthRef.value = parseInt( |
||||
$dayVal.slice(0, $dayVal.length - 1) |
||||
) |
||||
radioRef.value = 'recentlyWorkingDaysMonth' |
||||
} |
||||
|
||||
if ($dayVal === '*') { |
||||
hanleDayOne() |
||||
} else if (isStr($dayVal, '/')) { |
||||
hanleDayTwo() |
||||
} else if ($dayVal === 'L') { |
||||
hanleDayFour() |
||||
} else if ($dayVal === 'LW') { |
||||
hanleDayFive() |
||||
} else if ($dayVal.charAt($dayVal.length - 1) === 'L') { |
||||
hanleDaySix() |
||||
} else if (isStr($dayVal, '-')) { |
||||
hanleDaySeven() |
||||
} else if ($dayVal.charAt($dayVal.length - 1) === 'W') { |
||||
hanleDayEight() |
||||
} else { |
||||
hanleDayThree() |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Every few weeks
|
||||
const onWkintervalWeekPerform = (value: number | null) => { |
||||
WkintervalWeekPerformRef.value = value || 0 |
||||
if (radioRef.value === 'WkintervalWeek') { |
||||
dayRef.value = '?' |
||||
weekRef.value = `${WkintervalWeekStartRef.value}/${WkintervalWeekPerformRef.value}` |
||||
} |
||||
} |
||||
|
||||
// Every few weeks
|
||||
const onWkintervalWeekStart = (value: number | null) => { |
||||
WkintervalWeekStartRef.value = value || 0 |
||||
if (radioRef.value === 'WkintervalWeek') { |
||||
dayRef.value = '?' |
||||
weekRef.value = `${WkintervalWeekStartRef.value}/${WkintervalWeekPerformRef.value}` |
||||
} |
||||
} |
||||
|
||||
// Interval start time(1)
|
||||
const onIntervalDayStart = (value: number | null) => { |
||||
intervalDayStartRef.value = value || 0 |
||||
if (radioRef.value === 'intervalDay') { |
||||
intervalDaySet() |
||||
} |
||||
} |
||||
|
||||
// Interval execution time(2)
|
||||
const onIntervalDayPerform = (value: number | null) => { |
||||
intervalDayPerformRef.value = value || 0 |
||||
if (radioRef.value === 'intervalDay') { |
||||
intervalDaySet() |
||||
} |
||||
} |
||||
|
||||
// Specific day of the week (multiple choice)
|
||||
const onWkspecificWeek = (arr: Array<number>) => { |
||||
WkspecificWeekRef.value = arr |
||||
if (radioRef.value === 'WkspecificWeek') { |
||||
dayRef.value = '?' |
||||
weekRef.value = arr.join(',') |
||||
} |
||||
} |
||||
|
||||
// Specific days (multiple choices)
|
||||
const onWkspecificDay = (arr: Array<number>) => { |
||||
WkspecificDayRef.value = arr |
||||
if (radioRef.value === 'specificDay') { |
||||
weekRef.value = '?' |
||||
dayRef.value = arr.join(',') |
||||
} |
||||
} |
||||
|
||||
const onMonthLastWeeks = (value: string | null) => { |
||||
monthLastWeeksRef.value = value || '?' |
||||
if (radioRef.value === 'monthLastWeeks') { |
||||
weekRef.value = value |
||||
dayRef.value = '?' |
||||
} |
||||
} |
||||
|
||||
// Specific days
|
||||
const onSpecificDays = (arr: Array<number>) => { |
||||
WkspecificDayRef.value = arr |
||||
if (radioRef.value === 'specificDay') { |
||||
specificSet() |
||||
} |
||||
} |
||||
|
||||
// By the end of this month
|
||||
const onMonthTailBefore = (value: number | null) => { |
||||
monthTailBeforeRef.value = value || 0 |
||||
if (radioRef.value === 'monthTailBefore') { |
||||
dayRef.value = `L-${monthTailBeforeRef.value}` |
||||
} |
||||
} |
||||
|
||||
// Last working day
|
||||
const onRecentlyWorkingDaysMonth = (value: number | null) => { |
||||
recentlyWorkingDaysMonthRef.value = value || 0 |
||||
if (radioRef.value === 'recentlyWorkingDaysMonth') { |
||||
dayRef.value = `${recentlyWorkingDaysMonthRef.value}W` |
||||
} |
||||
} |
||||
|
||||
// On the day of this month
|
||||
const onWkmonthNumWeeksDay = (value: number | null) => { |
||||
WkmonthNumWeeksDayRef.value = value || 0 |
||||
if (radioRef.value === 'WkmonthNumWeeks') { |
||||
weekRef.value = `${WkmonthNumWeeksWeekRef.value}#${WkmonthNumWeeksDayRef.value}` |
||||
} |
||||
} |
||||
|
||||
// On the week of this month
|
||||
const onWkmonthNumWeeksWeek = (value: number | null) => { |
||||
if (radioRef.value === 'WkmonthNumWeeks') { |
||||
dayRef.value = '?' |
||||
weekRef.value = `${value}#${WkmonthNumWeeksDayRef.value}` |
||||
} |
||||
} |
||||
|
||||
// Reset every day
|
||||
const everyDaySet = () => { |
||||
dayRef.value = '*' |
||||
} |
||||
|
||||
// Reset interval week starts from *
|
||||
const WkintervalWeekReset = () => { |
||||
weekRef.value = `${WkintervalWeekStartRef.value}/${WkintervalWeekPerformRef.value}` |
||||
} |
||||
|
||||
// Reset interval days
|
||||
const intervalDaySet = () => { |
||||
dayRef.value = `${intervalDayStartRef.value}/${intervalDayPerformRef.value}` |
||||
} |
||||
|
||||
// Specific week (multiple choices)
|
||||
const WkspecificWeekReset = () => { |
||||
weekRef.value = WkspecificWeekRef.value.length |
||||
? WkspecificWeekRef.value.join(',') |
||||
: '*' |
||||
} |
||||
|
||||
// Reset specific days
|
||||
const specificSet = () => { |
||||
if (WkspecificDayRef.value.length) { |
||||
dayRef.value = WkspecificDayRef.value.join(',') |
||||
} else { |
||||
dayRef.value = '*' |
||||
} |
||||
} |
||||
|
||||
// On the last day of the month
|
||||
const monthLastDaysReset = () => { |
||||
dayRef.value = monthLastDaysRef.value |
||||
} |
||||
|
||||
// On the last working day of the month
|
||||
const monthLastWorkingDaysReset = () => { |
||||
dayRef.value = monthLastWorkingDaysRef.value |
||||
} |
||||
|
||||
// At the end of the month*
|
||||
const monthLastWeeksReset = () => { |
||||
dayRef.value = monthLastWeeksRef.value |
||||
} |
||||
|
||||
// By the end of this month
|
||||
const monthTailBeforeReset = () => { |
||||
dayRef.value = `L-${monthTailBeforeRef.value}` |
||||
} |
||||
|
||||
// Last working day (Monday to Friday) to this month
|
||||
const recentlyWorkingDaysMonthReset = () => { |
||||
dayRef.value = `${recentlyWorkingDaysMonthRef.value}W` |
||||
} |
||||
|
||||
// On the day of this month
|
||||
const WkmonthNumReset = () => { |
||||
weekRef.value = `${WkmonthNumWeeksWeekRef.value}#${WkmonthNumWeeksDayRef.value}` |
||||
} |
||||
|
||||
const updateRadioDay = (value: string) => { |
||||
switch (value) { |
||||
case 'everyDay': |
||||
weekRef.value = '?' |
||||
everyDaySet() |
||||
break |
||||
case 'WkintervalWeek': |
||||
dayRef.value = '?' |
||||
WkintervalWeekReset() |
||||
break |
||||
case 'intervalDay': |
||||
weekRef.value = '?' |
||||
intervalDaySet() |
||||
break |
||||
case 'WkspecificWeek': |
||||
dayRef.value = '?' |
||||
WkspecificWeekReset() |
||||
break |
||||
case 'specificDay': |
||||
weekRef.value = '?' |
||||
specificSet() |
||||
break |
||||
case 'monthLastDays': |
||||
weekRef.value = '?' |
||||
monthLastDaysReset() |
||||
break |
||||
case 'monthLastWorkingDays': |
||||
weekRef.value = '?' |
||||
monthLastWorkingDaysReset() |
||||
break |
||||
case 'monthLastWeeks': |
||||
weekRef.value = '1L' |
||||
monthLastWeeksReset() |
||||
break |
||||
case 'monthTailBefore': |
||||
weekRef.value = '?' |
||||
monthTailBeforeReset() |
||||
break |
||||
case 'recentlyWorkingDaysMonth': |
||||
weekRef.value = '?' |
||||
recentlyWorkingDaysMonthReset() |
||||
break |
||||
case 'WkmonthNumWeeks': |
||||
dayRef.value = '?' |
||||
WkmonthNumReset() |
||||
break |
||||
} |
||||
} |
||||
|
||||
watch( |
||||
() => dayRef.value, |
||||
() => ctx.emit('update:dayValue', dayRef.value.toString()) |
||||
) |
||||
|
||||
watch( |
||||
() => weekRef.value, |
||||
() => ctx.emit('update:weekValue', weekRef.value.toString()) |
||||
) |
||||
|
||||
onMounted(() => analyticalValue()) |
||||
|
||||
return { |
||||
options, |
||||
weekOptions, |
||||
lastWeekOptions, |
||||
radioRef, |
||||
WkintervalWeekStartRef, |
||||
WkintervalWeekPerformRef, |
||||
intervalDayStartRef, |
||||
intervalDayPerformRef, |
||||
WkspecificWeekRef, |
||||
WkspecificDayRef, |
||||
monthLastWeeksRef, |
||||
monthTailBeforeRef, |
||||
recentlyWorkingDaysMonthRef, |
||||
WkmonthNumWeeksDayRef, |
||||
WkmonthNumWeeksWeekRef, |
||||
updateRadioDay, |
||||
onWkintervalWeekStart, |
||||
onWkintervalWeekPerform, |
||||
onIntervalDayStart, |
||||
onIntervalDayPerform, |
||||
onSpecificDays, |
||||
onWkspecificWeek, |
||||
onWkspecificDay, |
||||
onMonthLastWeeks, |
||||
onMonthTailBefore, |
||||
onRecentlyWorkingDaysMonth, |
||||
onWkmonthNumWeeksDay, |
||||
onWkmonthNumWeeksWeek |
||||
} |
||||
}, |
||||
render() { |
||||
const { t } = useI18n() |
||||
|
||||
return ( |
||||
<NRadioGroup |
||||
v-model:value={this.radioRef} |
||||
onUpdateValue={this.updateRadioDay} |
||||
> |
||||
<NRadio class={styles['crontab-list']} value={'everyDay'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t('crontab.every_day')}</div> |
||||
</div> |
||||
</NRadio> |
||||
<NRadio class={styles['crontab-list']} value={'WkintervalWeek'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t('crontab.every')}</div> |
||||
<div> |
||||
<NInputNumber |
||||
defaultValue={0} |
||||
min={0} |
||||
max={7} |
||||
v-model:value={this.WkintervalWeekPerformRef} |
||||
onUpdateValue={this.onWkintervalWeekPerform} |
||||
/> |
||||
</div> |
||||
<div>{t('crontab.day_carried_out')}</div> |
||||
<div> |
||||
<NSelect |
||||
style={{ width: '150px' }} |
||||
options={this.weekOptions} |
||||
defaultValue={this.WkintervalWeekStartRef} |
||||
v-model:value={this.WkintervalWeekStartRef} |
||||
onUpdateValue={this.onWkintervalWeekStart} |
||||
/> |
||||
</div> |
||||
<div>{t('crontab.start')}</div> |
||||
</div> |
||||
</NRadio> |
||||
<NRadio class={styles['crontab-list']} value={'intervalDay'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t('crontab.every')}</div> |
||||
<div> |
||||
<NInputNumber |
||||
defaultValue={0} |
||||
min={0} |
||||
max={31} |
||||
v-model:value={this.intervalDayPerformRef} |
||||
onUpdateValue={this.onIntervalDayPerform} |
||||
/> |
||||
</div> |
||||
<div>{t('crontab.day_carried_out')}</div> |
||||
<div> |
||||
<NInputNumber |
||||
defaultValue={0} |
||||
min={1} |
||||
max={31} |
||||
v-model:value={this.intervalDayStartRef} |
||||
onUpdateValue={this.onIntervalDayStart} |
||||
/> |
||||
</div> |
||||
<div>{t('crontab.day_start')}</div> |
||||
</div> |
||||
</NRadio> |
||||
<NRadio class={styles['crontab-list']} value={'WkspecificWeek'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t('crontab.specific_week')}</div> |
||||
<div> |
||||
<NSelect |
||||
style={{ width: '300px' }} |
||||
multiple |
||||
options={specificWeek} |
||||
placeholder={t('crontab.specific_week_tip')} |
||||
v-model:value={this.WkspecificWeekRef} |
||||
onUpdateValue={this.onWkspecificWeek} |
||||
/> |
||||
</div> |
||||
</div> |
||||
</NRadio> |
||||
<NRadio class={styles['crontab-list']} value={'specificDay'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t('crontab.specific_day')}</div> |
||||
<div> |
||||
<NSelect |
||||
style={{ width: '300px' }} |
||||
multiple |
||||
options={this.options} |
||||
placeholder={t('crontab.specific_day_tip')} |
||||
v-model:value={this.WkspecificDayRef} |
||||
onUpdateValue={this.onWkspecificDay} |
||||
/> |
||||
</div> |
||||
</div> |
||||
</NRadio> |
||||
<NRadio class={styles['crontab-list']} value={'monthLastDays'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t('crontab.last_day_of_month')}</div> |
||||
</div> |
||||
</NRadio> |
||||
<NRadio class={styles['crontab-list']} value={'monthLastWorkingDays'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t('crontab.last_work_day_of_month')}</div> |
||||
</div> |
||||
</NRadio> |
||||
<NRadio class={styles['crontab-list']} value={'monthLastWeeks'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t('crontab.last_of_month')}</div> |
||||
<div> |
||||
<NSelect |
||||
style={{ width: '150px' }} |
||||
options={this.lastWeekOptions} |
||||
defaultValue={this.monthLastWeeksRef} |
||||
v-model:value={this.monthLastWeeksRef} |
||||
onUpdateValue={this.onMonthLastWeeks} |
||||
/> |
||||
</div> |
||||
</div> |
||||
</NRadio> |
||||
<NRadio class={styles['crontab-list']} value={'monthTailBefore'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div> |
||||
<NInputNumber |
||||
defaultValue={0} |
||||
min={0} |
||||
max={31} |
||||
v-model:value={this.monthTailBeforeRef} |
||||
onUpdateValue={this.onMonthTailBefore} |
||||
/> |
||||
</div> |
||||
<div>{t('crontab.before_end_of_month')}</div> |
||||
</div> |
||||
</NRadio> |
||||
<NRadio |
||||
class={styles['crontab-list']} |
||||
value={'recentlyWorkingDaysMonth'} |
||||
> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t('crontab.recent_business_day_to_month')}</div> |
||||
<div> |
||||
<NInputNumber |
||||
defaultValue={0} |
||||
min={0} |
||||
max={31} |
||||
v-model:value={this.recentlyWorkingDaysMonthRef} |
||||
onUpdateValue={this.onRecentlyWorkingDaysMonth} |
||||
/> |
||||
</div> |
||||
<div>{t('crontab.one_day')}</div> |
||||
</div> |
||||
</NRadio> |
||||
<NRadio class={styles['crontab-list']} value={'WkmonthNumWeeks'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t('crontab.in_this_months')}</div> |
||||
<div> |
||||
<NInputNumber |
||||
defaultValue={0} |
||||
min={0} |
||||
max={31} |
||||
v-model:value={this.WkmonthNumWeeksDayRef} |
||||
onUpdateValue={this.onWkmonthNumWeeksDay} |
||||
/> |
||||
</div> |
||||
<div> |
||||
<NSelect |
||||
style={{ width: '150px' }} |
||||
options={this.weekOptions} |
||||
defaultValue={this.WkmonthNumWeeksWeekRef} |
||||
v-model:value={this.WkmonthNumWeeksWeekRef} |
||||
onUpdateValue={this.onWkmonthNumWeeksWeek} |
||||
/> |
||||
</div> |
||||
</div> |
||||
</NRadio> |
||||
</NRadioGroup> |
||||
) |
||||
} |
||||
}) |
@ -0,0 +1,296 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import _ from 'lodash' |
||||
import { defineComponent, onMounted, PropType, ref, toRefs, watch } from 'vue' |
||||
import { NInputNumber, NRadio, NRadioGroup, NSelect } from 'naive-ui' |
||||
import { useI18n } from 'vue-i18n' |
||||
import { ICrontabI18n } from '../types' |
||||
import { isStr } from '../common' |
||||
import styles from '../index.module.scss' |
||||
|
||||
const props = { |
||||
timeValue: { |
||||
type: String as PropType<string>, |
||||
default: '*' |
||||
}, |
||||
timeI18n: { |
||||
type: Object as PropType<ICrontabI18n>, |
||||
require: true |
||||
} |
||||
} |
||||
|
||||
export default defineComponent({ |
||||
name: 'CrontabTime', |
||||
props, |
||||
emits: ['update:timeValue'], |
||||
setup(props, ctx) { |
||||
const options = Array.from({ length: 60 }, (x, i) => ({ |
||||
label: i.toString(), |
||||
value: i |
||||
})) |
||||
|
||||
const timeRef = ref() |
||||
const radioRef = ref() |
||||
const intervalStartRef = ref(0) |
||||
const intervalPerformRef = ref(0) |
||||
const specificTimesRef = ref<Array<number>>([]) |
||||
const cycleStartRef = ref(0) |
||||
const cycleEndRef = ref(0) |
||||
|
||||
/** |
||||
* Parse parameter value |
||||
*/ |
||||
const analyticalValue = () => { |
||||
const $timeVal = props.timeValue |
||||
// Interval time
|
||||
const $interval = isStr($timeVal, '/') |
||||
// Specific time
|
||||
const $specific = isStr($timeVal, ',') |
||||
// Cycle time
|
||||
const $cycle = isStr($timeVal, '-') |
||||
|
||||
// Every time
|
||||
if ($timeVal === '*') { |
||||
radioRef.value = 'everyTime' |
||||
timeRef.value = '*' |
||||
return |
||||
} |
||||
|
||||
// Positive integer (times)
|
||||
if ( |
||||
($timeVal.length === 1 && _.isInteger(parseInt($timeVal))) || |
||||
($timeVal.length === 2 && _.isInteger(parseInt($timeVal))) |
||||
) { |
||||
radioRef.value = 'specificTime' |
||||
specificTimesRef.value = [parseInt($timeVal)] |
||||
return |
||||
} |
||||
|
||||
// Interval times
|
||||
if ($interval) { |
||||
radioRef.value = 'intervalTime' |
||||
intervalStartRef.value = parseInt($interval[0]) |
||||
intervalPerformRef.value = parseInt($interval[1]) |
||||
timeRef.value = `${intervalStartRef.value}/${intervalPerformRef.value}` |
||||
return |
||||
} |
||||
|
||||
// Specific times
|
||||
if ($specific) { |
||||
radioRef.value = 'specificTime' |
||||
specificTimesRef.value = $specific.map((item) => parseInt(item)) |
||||
return |
||||
} |
||||
|
||||
// Cycle time
|
||||
if ($cycle) { |
||||
radioRef.value = 'cycleTime' |
||||
cycleStartRef.value = parseInt($cycle[0]) |
||||
cycleEndRef.value = parseInt($cycle[1]) |
||||
timeRef.value = `${cycleStartRef.value}-${cycleEndRef.value}` |
||||
return |
||||
} |
||||
} |
||||
|
||||
// Interval start time(1)
|
||||
const onIntervalStart = (value: number | null) => { |
||||
intervalStartRef.value = value || 0 |
||||
if (radioRef.value === 'intervalTime') { |
||||
timeRef.value = `${intervalStartRef.value}/${intervalPerformRef.value}` |
||||
} |
||||
} |
||||
|
||||
// Interval execution time(2)
|
||||
const onIntervalPerform = (value: number | null) => { |
||||
intervalPerformRef.value = value || 0 |
||||
if (radioRef.value === 'intervalTime') { |
||||
timeRef.value = `${intervalStartRef.value}/${intervalPerformRef.value}` |
||||
} |
||||
} |
||||
|
||||
// Specific time
|
||||
const onSpecificTimes = (arr: Array<number>) => { |
||||
specificTimesRef.value = arr |
||||
if (radioRef.value === 'specificTime') { |
||||
specificReset() |
||||
} |
||||
} |
||||
|
||||
// Cycle start value
|
||||
const onCycleStart = (value: number | null) => { |
||||
cycleStartRef.value = value || 0 |
||||
if (radioRef.value === 'cycleTime') { |
||||
timeRef.value = `${cycleStartRef.value}-${cycleEndRef.value}` |
||||
} |
||||
} |
||||
|
||||
// Cycle end value
|
||||
const onCycleEnd = (value: number | null) => { |
||||
cycleEndRef.value = value || 0 |
||||
if (radioRef.value === 'cycleTime') { |
||||
timeRef.value = `${cycleStartRef.value}-${cycleEndRef.value}` |
||||
} |
||||
} |
||||
|
||||
// Reset every time
|
||||
const everyReset = () => { |
||||
timeRef.value = '*' |
||||
} |
||||
|
||||
// Reset interval time
|
||||
const intervalReset = () => { |
||||
timeRef.value = `${intervalStartRef.value}/${intervalPerformRef.value}` |
||||
} |
||||
|
||||
// Reset specific time
|
||||
const specificReset = () => { |
||||
let timeValue = '*' |
||||
if (specificTimesRef.value.length) { |
||||
timeValue = specificTimesRef.value.join(',') |
||||
} |
||||
timeRef.value = timeValue |
||||
} |
||||
|
||||
// Reset cycle time
|
||||
const cycleReset = () => { |
||||
timeRef.value = `${cycleStartRef.value}-${cycleEndRef.value}` |
||||
} |
||||
|
||||
const updateRadioTime = (value: string) => { |
||||
switch (value) { |
||||
case 'everyTime': |
||||
everyReset() |
||||
break |
||||
case 'intervalTime': |
||||
intervalReset() |
||||
break |
||||
case 'specificTime': |
||||
specificReset() |
||||
break |
||||
case 'cycleTime': |
||||
cycleReset() |
||||
break |
||||
} |
||||
} |
||||
|
||||
watch( |
||||
() => timeRef.value, |
||||
() => ctx.emit('update:timeValue', timeRef.value.toString()) |
||||
) |
||||
|
||||
onMounted(() => analyticalValue()) |
||||
|
||||
return { |
||||
options, |
||||
radioRef, |
||||
intervalStartRef, |
||||
intervalPerformRef, |
||||
specificTimesRef, |
||||
cycleStartRef, |
||||
cycleEndRef, |
||||
updateRadioTime, |
||||
onIntervalStart, |
||||
onIntervalPerform, |
||||
onSpecificTimes, |
||||
onCycleStart, |
||||
onCycleEnd, |
||||
...toRefs(props) |
||||
} |
||||
}, |
||||
render() { |
||||
const { t } = useI18n() |
||||
|
||||
return ( |
||||
<NRadioGroup |
||||
v-model:value={this.radioRef} |
||||
onUpdateValue={this.updateRadioTime} |
||||
> |
||||
<NRadio class={styles['crontab-list']} value={'everyTime'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t(this.timeI18n!.everyTime)}</div> |
||||
</div> |
||||
</NRadio> |
||||
<NRadio class={styles['crontab-list']} value={'intervalTime'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t(this.timeI18n!.every)}</div> |
||||
<div> |
||||
<NInputNumber |
||||
defaultValue={0} |
||||
min={0} |
||||
max={59} |
||||
v-model:value={this.intervalStartRef} |
||||
onUpdateValue={this.onIntervalStart} |
||||
/> |
||||
</div> |
||||
<div>{t(this.timeI18n!.timeCarriedOut)}</div> |
||||
<div> |
||||
<NInputNumber |
||||
defaultValue={0} |
||||
min={0} |
||||
max={59} |
||||
v-model:value={this.intervalPerformRef} |
||||
onUpdateValue={this.onIntervalPerform} |
||||
/> |
||||
</div> |
||||
<div>{t(this.timeI18n!.timeStart)}</div> |
||||
</div> |
||||
</NRadio> |
||||
<NRadio class={styles['crontab-list']} value={'specificTime'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t(this.timeI18n!.specificTime)}</div> |
||||
<div> |
||||
<NSelect |
||||
style={{ width: '300px' }} |
||||
multiple |
||||
options={this.options} |
||||
placeholder={t(this.timeI18n!.specificTimeTip)} |
||||
v-model:value={this.specificTimesRef} |
||||
onUpdateValue={this.onSpecificTimes} |
||||
/> |
||||
</div> |
||||
</div> |
||||
</NRadio> |
||||
<NRadio class={styles['crontab-list']} value={'cycleTime'}> |
||||
<div class={styles['crontab-list-item']}> |
||||
<div>{t(this.timeI18n!.cycleFrom)}</div> |
||||
<div> |
||||
<NInputNumber |
||||
defaultValue={0} |
||||
min={0} |
||||
max={59} |
||||
v-model:value={this.cycleStartRef} |
||||
onUpdateValue={this.onCycleStart} |
||||
/> |
||||
</div> |
||||
<div>{t(this.timeI18n!.to)}</div> |
||||
<div> |
||||
<NInputNumber |
||||
defaultValue={0} |
||||
min={0} |
||||
max={59} |
||||
v-model:value={this.cycleEndRef} |
||||
onUpdateValue={this.onCycleEnd} |
||||
/> |
||||
</div> |
||||
<div>{t(this.timeI18n!.time)}</div> |
||||
</div> |
||||
</NRadio> |
||||
</NRadioGroup> |
||||
) |
||||
} |
||||
}) |
@ -0,0 +1,30 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
interface ICrontabI18n { |
||||
everyTime: string |
||||
every: string |
||||
timeCarriedOut: string |
||||
timeStart: string |
||||
cycleFrom: string |
||||
specificTime: string |
||||
specificTimeTip: string |
||||
to: string |
||||
time: string |
||||
} |
||||
|
||||
export { ICrontabI18n } |
Loading…
Reference in new issue