refactor(Crontab): 重构vue3版本

- 优化了 radioValue 的赋值方式,使用 :value 替代 label
- 调整了 input-number 和 select 组件的样式,增加空格和对齐
- 重构了计算逻辑,简化了 cycleTotal、averageTotal 等计算属性
- 优化了 watch 监听和 radio 变化处理逻辑
- 新增 changeRadioValue 函数处理 radio 值的变化
- 统一了 emit 方法的调用方式
master
zch
parent b6ad3ffb3b
commit c068f8ce8e

@ -1,171 +1,174 @@
<template> <template>
<el-form size="small"> <el-form>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="1"> <el-radio v-model='radioValue' :value="1">
允许的通配符[, - * ? / L W] 允许的通配符[, - * ? / L W]
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="2"> <el-radio v-model='radioValue' :value="2">
不指定 不指定
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="3"> <el-radio v-model='radioValue' :value="3">
周期从 周期从
<el-input-number v-model='cycle01' :min="1" :max="30" /> - <el-input-number v-model='cycle01' :min="1" :max="30" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 2" :max="31" /> <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="31" />
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="4"> <el-radio v-model='radioValue' :value="4">
<el-input-number v-model='average01' :min="1" :max="30" /> 号开始 <el-input-number v-model='average01' :min="1" :max="30" /> 号开始
<el-input-number v-model='average02' :min="1" :max="31 - average01 || 1" /> 日执行一次 <el-input-number v-model='average02' :min="1" :max="31 - average01" /> 日执行一次
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="5"> <el-radio v-model='radioValue' :value="5">
每月 每月
<el-input-number v-model='workday' :min="1" :max="31" /> 号最近的那个工作日 <el-input-number v-model='workday' :min="1" :max="31" /> 号最近的那个工作日
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="6"> <el-radio v-model='radioValue' :value="6">
本月最后一天 本月最后一天
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="7"> <el-radio v-model='radioValue' :value="7">
指定 指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> <el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 31" :key="item" :value="item">{{item}}</el-option> <el-option v-for="item in 31" :key="item" :label="item" :value="item" />
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<script setup>
<script setup lang="ts" name="CrontabDay"> const emit = defineEmits(['update'])
import { ref, computed, watch, defineProps, defineEmits } from 'vue';
const props = defineProps({ const props = defineProps({
check: { cron: {
type: Function, type: Object,
required: true default: {
}, second: "*",
cron: { min: "*",
type: Object, hour: "*",
default: () => ({}) day: "*",
} month: "*",
}); week: "?",
year: "",
const emit = defineEmits(['update']); }
},
const radioValue = ref(1); check: {
const workday = ref(1); type: Function,
const cycle01 = ref(1); default: () => {
const cycle02 = ref(2); }
const average01 = ref(1); }
const average02 = ref(1); })
const checkboxList = ref([]); const radioValue = ref(1)
const cycle01 = ref(1)
// const cycle02 = ref(2)
const average01 = ref(1)
const average02 = ref(1)
const workday = ref(1)
const checkboxList = ref([])
const checkCopy = ref([1])
const cycleTotal = computed(() => { const cycleTotal = computed(() => {
const cycleVal01 = props.check(cycle01.value, 1, 30); cycle01.value = props.check(cycle01.value, 1, 30)
const cycleVal02 = props.check(cycle02.value, cycleVal01 ? cycleVal01 + 1 : 2, 31, 31); cycle02.value = props.check(cycle02.value, cycle01.value + 1, 31)
return `${cycleVal01}-${cycleVal02}`; return cycle01.value + '-' + cycle02.value
}); })
//
const averageTotal = computed(() => { const averageTotal = computed(() => {
const averageVal01 = props.check(average01.value, 1, 30); average01.value = props.check(average01.value, 1, 30)
const averageVal02 = props.check(average02.value, 1, 31 - averageVal01 || 0); average02.value = props.check(average02.value, 1, 31 - average01.value)
return `${averageVal01}/${averageVal02}`; return average01.value + '/' + average02.value
}); })
const workdayTotal = computed(() => {
// workday.value = props.check(workday.value, 1, 31)
const workdayCheck = computed(() => { return workday.value + 'W'
return props.check(workday.value, 1, 31); })
});
// checkbox
const checkboxString = computed(() => { const checkboxString = computed(() => {
let str = checkboxList.value.join(); return checkboxList.value.join(',')
return str === '' ? '*' : str; })
}); watch(() => props.cron.day, value => changeRadioValue(value))
watch([radioValue, cycleTotal, averageTotal, workdayTotal, checkboxString], () => onRadioChange())
function changeRadioValue(value) {
if (value === "*") {
radioValue.value = 1
} else if (value === "?") {
radioValue.value = 2
} else if (value.indexOf("-") > -1) {
const indexArr = value.split('-')
cycle01.value = Number(indexArr[0])
cycle02.value = Number(indexArr[1])
radioValue.value = 3
} else if (value.indexOf("/") > -1) {
const indexArr = value.split('/')
average01.value = Number(indexArr[0])
average02.value = Number(indexArr[1])
radioValue.value = 4
} else if (value.indexOf("W") > -1) {
const indexArr = value.split("W")
workday.value = Number(indexArr[0])
radioValue.value = 5
} else if (value === "L") {
radioValue.value = 6
} else {
checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
radioValue.value = 7
}
}
// //
const radioChange = () => { function onRadioChange() {
console.log('day rachange'); if (radioValue.value === 2 && props.cron.week === '?') {
if (radioValue.value !== 2 && props.cron.week !== '?') { emit('update', 'week', '*', 'day')
emit('update', 'week', '?', 'day'); }
} if (radioValue.value !== 2 && props.cron.week !== '?') {
emit('update', 'week', '?', 'day')
switch (radioValue.value) { }
case 1: switch (radioValue.value) {
emit('update', 'day', '*'); case 1:
break; emit('update', 'day', '*', 'day')
case 2: break
emit('update', 'day', '?'); case 2:
break; emit('update', 'day', '?', 'day')
case 3: break
emit('update', 'day', cycleTotal.value); case 3:
break; emit('update', 'day', cycleTotal.value, 'day')
case 4: break
emit('update', 'day', averageTotal.value); case 4:
break; emit('update', 'day', averageTotal.value, 'day')
case 5: break
emit('update', 'day', workdayCheck.value + 'W'); case 5:
break; emit('update', 'day', workdayTotal.value, 'day')
case 6: break
emit('update', 'day', 'L'); case 6:
break; emit('update', 'day', 'L', 'day')
case 7: break
emit('update', 'day', checkboxString.value); case 7:
break; if (checkboxList.value.length === 0) {
} checkboxList.value.push(checkCopy.value[0])
console.log('day rachange end'); } else {
}; checkCopy.value = checkboxList.value
}
// emit('update', 'day', checkboxString.value, 'day')
const cycleChange = () => { break
if (radioValue.value === 3) { }
emit('update', 'day', cycleTotal.value); }
}
};
//
const averageChange = () => {
if (radioValue.value === 4) {
emit('update', 'day', averageTotal.value);
}
};
//
const workdayChange = () => {
if (radioValue.value === 5) {
emit('update', 'day', workdayCheck.value + 'W');
}
};
// checkbox
const checkboxChange = () => {
if (radioValue.value === 7) {
emit('update', 'day', checkboxString.value);
}
};
//
watch(() => radioValue.value, radioChange);
watch(() => cycleTotal.value, cycleChange);
watch(() => averageTotal.value, averageChange);
watch(() => workdayCheck.value, workdayChange);
watch(() => checkboxString.value, checkboxChange);
</script> </script>
<style lang="scss" scoped>
.el-input-number--small, .el-select, .el-select--small {
margin: 0 0.2rem;
}
.el-select, .el-select--small {
width: 18.8rem;
}
</style>

@ -1,123 +1,133 @@
<template> <template>
<el-form size="small"> <el-form>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="1"> <el-radio v-model='radioValue' :value="1">
小时允许的通配符[, - * /] 小时允许的通配符[, - * /]
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="2"> <el-radio v-model='radioValue' :value="2">
周期从 周期从
<el-input-number v-model='cycle01' :min="0" :max="22" /> - <el-input-number v-model='cycle01' :min="0" :max="22" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="23" /> <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="23" />
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="3"> <el-radio v-model='radioValue' :value="3">
<el-input-number v-model='average01' :min="0" :max="22" /> 时开始 <el-input-number v-model='average01' :min="0" :max="22" /> 时开始
<el-input-number v-model='average02' :min="1" :max="23 - average01 || 0" /> 小时执行一次 <el-input-number v-model='average02' :min="1" :max="23 - average01" /> 小时执行一次
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="4"> <el-radio v-model='radioValue' :value="4">
指定 指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> <el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 24" :key="item" :value="item-1">{{item-1}}</el-option> <el-option v-for="item in 24" :key="item" :label="item - 1" :value="item - 1" />
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<script setup lang="ts" name="CrontabHour"> <script setup>
import { ref, computed, watch, defineProps, defineEmits } from 'vue'; const emit = defineEmits(['update'])
const props = defineProps({ const props = defineProps({
check: { cron: {
type: Function, type: Object,
required: true default: {
}, second: "*",
cron: { min: "*",
type: Object, hour: "*",
default: () => ({}) day: "*",
} month: "*",
}); week: "?",
year: "",
const emit = defineEmits(['update']); }
},
const radioValue = ref(1); check: {
const cycle01 = ref(0); type: Function,
const cycle02 = ref(1); default: () => {
const average01 = ref(0); }
const average02 = ref(1); }
const checkboxList = ref([]); })
const radioValue = ref(1)
// const cycle01 = ref(0)
const cycle02 = ref(1)
const average01 = ref(0)
const average02 = ref(1)
const checkboxList = ref([])
const checkCopy = ref([0])
const cycleTotal = computed(() => { const cycleTotal = computed(() => {
const cycleVal01 = props.check(cycle01.value, 0, 22); cycle01.value = props.check(cycle01.value, 0, 22)
const cycleVal02 = props.check(cycle02.value, cycleVal01 ? cycleVal01 + 1 : 1, 23); cycle02.value = props.check(cycle02.value, cycle01.value + 1, 23)
return `${cycleVal01}-${cycleVal02}`; return cycle01.value + '-' + cycle02.value
}); })
//
const averageTotal = computed(() => { const averageTotal = computed(() => {
const averageVal01 = props.check(average01.value, 0, 22); average01.value = props.check(average01.value, 0, 22)
const averageVal02 = props.check(average02.value, 1, 23 - averageVal01 || 0); average02.value = props.check(average02.value, 1, 23 - average01.value)
return `${averageVal01}/${averageVal02}`; return average01.value + '/' + average02.value
}); })
// checkbox
const checkboxString = computed(() => { const checkboxString = computed(() => {
let str = checkboxList.value.join(); return checkboxList.value.join(',')
return str === '' ? '*' : str; })
}); watch(() => props.cron.hour, value => changeRadioValue(value))
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
// function changeRadioValue(value) {
const radioChange = () => { if (props.cron.min === '*') {
switch (radioValue.value) { emit('update', 'min', '0', 'hour');
case 1: }
emit('update', 'hour', '*'); if (props.cron.second === '*') {
break; emit('update', 'second', '0', 'hour');
case 2: }
emit('update', 'hour', cycleTotal.value); if (value === '*') {
break; radioValue.value = 1
case 3: } else if (value.indexOf('-') > -1) {
emit('update', 'hour', averageTotal.value); const indexArr = value.split('-')
break; cycle01.value = Number(indexArr[0])
case 4: cycle02.value = Number(indexArr[1])
emit('update', 'hour', checkboxString.value); radioValue.value = 2
break; } else if (value.indexOf('/') > -1) {
} const indexArr = value.split('/')
}; average01.value = Number(indexArr[0])
average02.value = Number(indexArr[1])
// radioValue.value = 3
const cycleChange = () => { } else {
if (radioValue.value === 2) { checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
emit('update', 'hour', cycleTotal.value); radioValue.value = 4
} }
}; }
function onRadioChange() {
// switch (radioValue.value) {
const averageChange = () => { case 1:
if (radioValue.value === 3) { emit('update', 'hour', '*', 'hour')
emit('update', 'hour', averageTotal.value); break
} case 2:
}; emit('update', 'hour', cycleTotal.value, 'hour')
break
// checkbox case 3:
const checkboxChange = () => { emit('update', 'hour', averageTotal.value, 'hour')
if (radioValue.value === 4) { break
emit('update', 'hour', checkboxString.value); case 4:
} if (checkboxList.value.length === 0) {
}; checkboxList.value.push(checkCopy.value[0])
} else {
// checkCopy.value = checkboxList.value
watch(() => radioValue.value, radioChange); }
watch(() => cycleTotal.value, cycleChange); emit('update', 'hour', checkboxString.value, 'hour')
watch(() => averageTotal.value, averageChange); break
watch(() => checkboxString.value, checkboxChange); }
}
</script> </script>
<style lang="scss" scoped>
.el-input-number--small, .el-select, .el-select--small {
margin: 0 0.2rem;
}
.el-select, .el-select--small {
width: 18.8rem;
}
</style>

@ -1,389 +1,151 @@
<template> <template>
<div> <div>
<el-tabs type="border-card"> <el-tabs type="border-card">
<el-tab-pane label="秒" v-if="shouldHide('second')"> <el-tab-pane label="秒" v-if="shouldHide('second')">
<CrontabSecond <CrontabSecond
@update="updateCrontabValue" @update="updateCrontabValue"
:check="checkNumber" :check="checkNumber"
:cron="crontabValueObj" :cron="crontabValueObj"
ref="cronsecond" ref="cronsecond"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="分钟" v-if="shouldHide('min')"> <el-tab-pane label="分钟" v-if="shouldHide('min')">
<CrontabMin <CrontabMin
@update="updateCrontabValue" @update="updateCrontabValue"
:check="checkNumber" :check="checkNumber"
:cron="crontabValueObj" :cron="crontabValueObj"
ref="cronmin" ref="cronmin"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="小时" v-if="shouldHide('hour')"> <el-tab-pane label="小时" v-if="shouldHide('hour')">
<CrontabHour <CrontabHour
@update="updateCrontabValue" @update="updateCrontabValue"
:check="checkNumber" :check="checkNumber"
:cron="crontabValueObj" :cron="crontabValueObj"
ref="cronhour" ref="cronhour"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="日" v-if="shouldHide('day')"> <el-tab-pane label="日" v-if="shouldHide('day')">
<CrontabDay <CrontabDay
@update="updateCrontabValue" @update="updateCrontabValue"
:check="checkNumber" :check="checkNumber"
:cron="crontabValueObj" :cron="crontabValueObj"
ref="cronday" ref="cronday"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="月" v-if="shouldHide('month')"> <el-tab-pane label="月" v-if="shouldHide('month')">
<CrontabMonth <CrontabMonth
@update="updateCrontabValue" @update="updateCrontabValue"
:check="checkNumber" :check="checkNumber"
:cron="crontabValueObj" :cron="crontabValueObj"
ref="cronmonth" ref="cronmonth"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="周" v-if="shouldHide('week')"> <el-tab-pane label="周" v-if="shouldHide('week')">
<CrontabWeek <CrontabWeek
@update="updateCrontabValue" @update="updateCrontabValue"
:check="checkNumber" :check="checkNumber"
:cron="crontabValueObj" :cron="crontabValueObj"
ref="cronweek" ref="cronweek"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="年" v-if="shouldHide('year')"> <el-tab-pane label="年" v-if="shouldHide('year')">
<CrontabYear <CrontabYear
@update="updateCrontabValue" @update="updateCrontabValue"
:check="checkNumber" :check="checkNumber"
:cron="crontabValueObj" :cron="crontabValueObj"
ref="cronyear" ref="cronyear"
/> />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<div class="popup-main"> <div class="popup-main">
<div class="popup-result"> <div class="popup-result">
<p class="title">时间表达式</p> <p class="title">时间表达式</p>
<table> <table>
<thead> <thead>
<th v-for="item of tabTitles" width="40" :key="item">{{item}}</th> <th v-for="item of tabTitles" :key="item">{{item}}</th>
<th>Cron 表达式</th> <th>Cron 表达式</th>
</thead> </thead>
<tbody> <tbody>
<td> <td>
<span>{{crontabValueObj.second}}</span> <span v-if="crontabValueObj.second.length < 10">{{crontabValueObj.second}}</span>
</td> <el-tooltip v-else :content="crontabValueObj.second" placement="top"><span>{{crontabValueObj.second}}</span></el-tooltip>
<td> </td>
<span>{{crontabValueObj.min}}</span> <td>
</td> <span v-if="crontabValueObj.min.length < 10">{{crontabValueObj.min}}</span>
<td> <el-tooltip v-else :content="crontabValueObj.min" placement="top"><span>{{crontabValueObj.min}}</span></el-tooltip>
<span>{{crontabValueObj.hour}}</span> </td>
</td> <td>
<td> <span v-if="crontabValueObj.hour.length < 10">{{crontabValueObj.hour}}</span>
<span>{{crontabValueObj.day}}</span> <el-tooltip v-else :content="crontabValueObj.hour" placement="top"><span>{{crontabValueObj.hour}}</span></el-tooltip>
</td> </td>
<td> <td>
<span>{{crontabValueObj.month}}</span> <span v-if="crontabValueObj.day.length < 10">{{crontabValueObj.day}}</span>
</td> <el-tooltip v-else :content="crontabValueObj.day" placement="top"><span>{{crontabValueObj.day}}</span></el-tooltip>
<td> </td>
<span>{{crontabValueObj.week}}</span> <td>
</td> <span v-if="crontabValueObj.month.length < 10">{{crontabValueObj.month}}</span>
<td> <el-tooltip v-else :content="crontabValueObj.month" placement="top"><span>{{crontabValueObj.month}}</span></el-tooltip>
<span>{{crontabValueObj.year}}</span> </td>
</td> <td>
<td> <span v-if="crontabValueObj.week.length < 10">{{crontabValueObj.week}}</span>
<span>{{crontabValueString}}</span> <el-tooltip v-else :content="crontabValueObj.week" placement="top"><span>{{crontabValueObj.week}}</span></el-tooltip>
</td> </td>
</tbody> <td>
</table> <span v-if="crontabValueObj.year.length < 10">{{crontabValueObj.year}}</span>
</div> <el-tooltip v-else :content="crontabValueObj.year" placement="top"><span>{{crontabValueObj.year}}</span></el-tooltip>
<CrontabResult :ex="crontabValueString"></CrontabResult> </td>
<td class="result">
<span v-if="crontabValueString.length < 90">{{crontabValueString}}</span>
<el-tooltip v-else :content="crontabValueString" placement="top"><span>{{crontabValueString}}</span></el-tooltip>
</td>
</tbody>
</table>
</div>
<CrontabResult :ex="crontabValueString"></CrontabResult>
<div class="pop_btn"> <div class="pop_btn">
<el-button size="small" type="primary" @click="submitFill"></el-button> <el-button type="primary" @click="submitFill"></el-button>
<el-button size="small" type="warning" @click="clearCron"></el-button> <el-button type="warning" @click="clearCron"></el-button>
<el-button size="small" @click="hidePopup"></el-button> <el-button @click="hidePopup"></el-button>
</div> </div>
</div>
</div> </div>
</div>
</template> </template>
<script setup lang="ts" name="Crontab"> <script setup>
import { ref, reactive, computed, watch, onMounted } from 'vue'; import CrontabSecond from "./second.vue"
import CrontabSecond from "./second.vue"; import CrontabMin from "./min.vue"
import CrontabMin from "./min.vue"; import CrontabHour from "./hour.vue"
import CrontabHour from "./hour.vue"; import CrontabDay from "./day.vue"
import CrontabDay from "./day.vue"; import CrontabMonth from "./month.vue"
import CrontabMonth from "./month.vue"; import CrontabWeek from "./week.vue"
import CrontabWeek from "./week.vue"; import CrontabYear from "./year.vue"
import CrontabYear from "./year.vue"; import CrontabResult from "./result.vue"
import CrontabResult from "./result.vue"; const { proxy } = getCurrentInstance()
const emit = defineEmits(['hide', 'fill'])
const props = defineProps({ const props = defineProps({
expression: { hideComponent: {
type: String, type: Array,
default: '' default: () => [],
}, },
hideComponent: { expression: {
type: Array as () => string[], type: String,
default: () => [] default: ""
}
});
const emit = defineEmits(['hide', 'fill']);
const tabTitles = ref(["秒", "分钟", "小时", "日", "月", "周", "年"]);
const tabActive = ref(0);
const myindex = ref(0);
const crontabValueObj = reactive({
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: "",
});
const cronsecond = ref(null);
const cronmin = ref(null);
const cronhour = ref(null);
const cronday = ref(null);
const cronmonth = ref(null);
const cronweek = ref(null);
const cronyear = ref(null);
//
const shouldHide = (key: string) => {
if (props.hideComponent && props.hideComponent.includes(key)) {
return false;
}
return true;
};
//
const resolveExp = () => {
//
if (props.expression) {
const arr = props.expression.split(" ");
if (arr.length >= 6) {
// 6
const obj = {
second: arr[0],
min: arr[1],
hour: arr[2],
day: arr[3],
month: arr[4],
week: arr[5],
year: arr[6] ? arr[6] : "",
};
Object.assign(crontabValueObj, obj);
for (let i in obj) {
if (obj[i]) {
changeRadio(i, obj[i]);
}
}
}
} else {
//
clearCron();
}
};
// tab
const tabCheck = (index: number) => {
tabActive.value = index;
};
//
const updateCrontabValue = (name: string, value: string, from?: string) => {
console.log("updateCrontabValue", name, value, from);
crontabValueObj[name] = value;
if (from && from !== name) {
console.log(`来自组件 ${from} 改变了 ${name} ${value}`);
changeRadio(name, value);
}
};
// ref
const getRefComponent = (refName: string) => {
switch(refName) {
case 'cronsecond': return cronsecond.value;
case 'cronmin': return cronmin.value;
case 'cronhour': return cronhour.value;
case 'cronday': return cronday.value;
case 'cronmonth': return cronmonth.value;
case 'cronweek': return cronweek.value;
case 'cronyear': return cronyear.value;
default: return null;
}
};
//
const changeRadio = (name: string, value: string) => {
const arr = ["second", "min", "hour", "month"];
const refName = "cron" + name;
let insValue;
const refComponent = getRefComponent(refName);
if (!refComponent) return;
if (arr.includes(name)) {
if (value === "*") {
insValue = 1;
} else if (value.indexOf("-") > -1) {
const indexArr = value.split("-");
if (refComponent.cycle01 !== undefined) {
refComponent.cycle01 = isNaN(parseInt(indexArr[0])) ? 0 : parseInt(indexArr[0]);
}
if (refComponent.cycle02 !== undefined) {
refComponent.cycle02 = parseInt(indexArr[1]);
}
insValue = 2;
} else if (value.indexOf("/") > -1) {
const indexArr = value.split("/");
if (refComponent.average01 !== undefined) {
refComponent.average01 = isNaN(parseInt(indexArr[0])) ? 0 : parseInt(indexArr[0]);
}
if (refComponent.average02 !== undefined) {
refComponent.average02 = parseInt(indexArr[1]);
}
insValue = 3;
} else {
insValue = 4;
if (refComponent.checkboxList !== undefined) {
refComponent.checkboxList = value.split(",");
}
}
} else if (name == "day") {
if (value === "*") {
insValue = 1;
} else if (value == "?") {
insValue = 2;
} else if (value.indexOf("-") > -1) {
const indexArr = value.split("-");
if (refComponent.cycle01 !== undefined) {
refComponent.cycle01 = isNaN(parseInt(indexArr[0])) ? 0 : parseInt(indexArr[0]);
}
if (refComponent.cycle02 !== undefined) {
refComponent.cycle02 = parseInt(indexArr[1]);
}
insValue = 3;
} else if (value.indexOf("/") > -1) {
const indexArr = value.split("/");
if (refComponent.average01 !== undefined) {
refComponent.average01 = isNaN(parseInt(indexArr[0])) ? 0 : parseInt(indexArr[0]);
}
if (refComponent.average02 !== undefined) {
refComponent.average02 = parseInt(indexArr[1]);
}
insValue = 4;
} else if (value.indexOf("W") > -1) {
const indexArr = value.split("W");
if (refComponent.workday !== undefined) {
refComponent.workday = isNaN(parseInt(indexArr[0])) ? 0 : parseInt(indexArr[0]);
}
insValue = 5;
} else if (value === "L") {
insValue = 6;
} else {
if (refComponent.checkboxList !== undefined) {
refComponent.checkboxList = value.split(",");
}
insValue = 7;
} }
} else if (name == "week") { })
if (value === "*") { const tabTitles = ref(["秒", "分钟", "小时", "日", "月", "周", "年"])
insValue = 1; const tabActive = ref(0)
} else if (value == "?") { const hideComponent = ref([])
insValue = 2; const expression = ref('')
} else if (value.indexOf("-") > -1) { const crontabValueObj = ref({
const indexArr = value.split("-");
if (refComponent.cycle01 !== undefined) {
refComponent.cycle01 = isNaN(parseInt(indexArr[0])) ? 0 : parseInt(indexArr[0]);
}
if (refComponent.cycle02 !== undefined) {
refComponent.cycle02 = parseInt(indexArr[1]);
}
insValue = 3;
} else if (value.indexOf("#") > -1) {
const indexArr = value.split("#");
if (refComponent.average01 !== undefined) {
refComponent.average01 = isNaN(parseInt(indexArr[1])) ? 1 : parseInt(indexArr[1]);
}
if (refComponent.average02 !== undefined) {
refComponent.average02 = parseInt(indexArr[0]);
}
insValue = 4;
} else if (value.indexOf("L") > -1) {
const indexArr = value.split("L");
if (refComponent.weekday !== undefined) {
refComponent.weekday = isNaN(parseInt(indexArr[0])) ? 1 : parseInt(indexArr[0]);
}
insValue = 5;
} else {
if (refComponent.checkboxList !== undefined) {
refComponent.checkboxList = value.split(",");
}
insValue = 6;
}
} else if (name == "year") {
if (value == "") {
insValue = 1;
} else if (value == "*") {
insValue = 2;
} else if (value.indexOf("-") > -1) {
insValue = 3;
} else if (value.indexOf("/") > -1) {
insValue = 4;
} else {
if (refComponent.checkboxList !== undefined) {
refComponent.checkboxList = value.split(",");
}
insValue = 5;
}
}
if (refComponent.radioValue !== undefined) {
refComponent.radioValue = insValue;
}
};
//
const checkNumber = (value: number, minLimit: number, maxLimit: number): number => {
//
value = Math.floor(value);
if (value < minLimit) {
value = minLimit;
} else if (value > maxLimit) {
value = maxLimit;
}
return value;
};
//
const hidePopup = () => {
emit("hide");
};
//
const submitFill = () => {
emit("fill", crontabValueString.value);
hidePopup();
};
//
const clearCron = () => {
//
console.log("准备还原");
Object.assign(crontabValueObj, {
second: "*", second: "*",
min: "*", min: "*",
hour: "*", hour: "*",
@ -391,100 +153,157 @@ const clearCron = () => {
month: "*", month: "*",
week: "?", week: "?",
year: "", year: "",
}); })
for (let j in crontabValueObj) {
changeRadio(j, crontabValueObj[j]);
}
};
// cron
const crontabValueString = computed(() => { const crontabValueString = computed(() => {
const obj = crontabValueObj; const obj = crontabValueObj.value
const str = return obj.second
obj.second + + " "
" " + + obj.min
obj.min + + " "
" " + + obj.hour
obj.hour + + " "
" " + + obj.day
obj.day + + " "
" " + + obj.month
obj.month + + " "
" " + + obj.week
obj.week + + (obj.year === "" ? "" : " " + obj.year)
(obj.year == "" ? "" : " " + obj.year); })
return str; watch(expression, () => resolveExp())
}); function shouldHide(key) {
return !(hideComponent.value && hideComponent.value.includes(key))
// props }
watch(() => props.expression, resolveExp); function resolveExp() {
watch(() => props.hideComponent, (value) => { //
// if (expression.value) {
}); const arr = expression.value.split(/\s+/)
if (arr.length >= 6) {
// //6
let obj = {
second: arr[0],
min: arr[1],
hour: arr[2],
day: arr[3],
month: arr[4],
week: arr[5],
year: arr[6] ? arr[6] : ""
}
crontabValueObj.value = {
...obj,
}
}
} else {
//
clearCron()
}
}
// tab
function tabCheck(index) {
tabActive.value = index
}
//
function updateCrontabValue(name, value, from) {
crontabValueObj.value[name] = value
}
// -props
function checkNumber(value, minLimit, maxLimit) {
//
value = Math.floor(value)
if (value < minLimit) {
value = minLimit
} else if (value > maxLimit) {
value = maxLimit
}
return value
}
//
function hidePopup() {
emit("hide")
}
//
function submitFill() {
emit("fill", crontabValueString.value)
hidePopup()
}
function clearCron() {
//
crontabValueObj.value = {
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: "",
}
}
onMounted(() => { onMounted(() => {
resolveExp(); expression.value = props.expression
}); hideComponent.value = props.hideComponent
})
</script> </script>
<style scoped>
<style lang="scss" scoped>
.pop_btn { .pop_btn {
text-align: center; text-align: center;
margin-top: 20px; margin-top: 20px;
} }
.popup-main { .popup-main {
position: relative; position: relative;
margin: 10px auto; margin: 10px auto;
background: #fff; border-radius: 5px;
border-radius: 5px; font-size: 12px;
font-size: 12px; overflow: hidden;
overflow: hidden;
} }
.popup-title { .popup-title {
overflow: hidden; overflow: hidden;
line-height: 34px; line-height: 34px;
padding-top: 6px; padding-top: 6px;
background: #f2f2f2; background: #f2f2f2;
} }
.popup-result { .popup-result {
box-sizing: border-box; box-sizing: border-box;
line-height: 24px; line-height: 24px;
margin: 25px auto; margin: 25px auto;
padding: 15px 10px 10px; padding: 15px 10px 10px;
border: 1px solid #ccc; border: 1px solid #ccc;
position: relative; position: relative;
} }
.popup-result .title { .popup-result .title {
position: absolute; position: absolute;
top: -28px; top: -28px;
left: 50%; left: 50%;
width: 140px; width: 140px;
font-size: 14px; font-size: 14px;
margin-left: -70px; margin-left: -70px;
text-align: center; text-align: center;
line-height: 30px; line-height: 30px;
background: #fff; background: #fff;
} }
.popup-result table { .popup-result table {
text-align: center; text-align: center;
width: 100%; width: 100%;
margin: 0 auto; margin: 0 auto;
}
.popup-result table td:not(.result) {
width: 3.5rem;
min-width: 3.5rem;
max-width: 3.5rem;
} }
.popup-result table span { .popup-result table span {
display: block; display: block;
width: 100%; width: 100%;
font-family: arial; font-family: arial;
line-height: 30px; line-height: 30px;
height: 30px; height: 30px;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
border: 1px solid #e8e8e8; border: 1px solid #e8e8e8;
} }
.popup-result-scroll { .popup-result-scroll {
font-size: 12px; font-size: 12px;
line-height: 24px; line-height: 24px;
height: 10em; height: 10em;
overflow-y: auto; overflow-y: auto;
} }
</style> </style>

@ -1,124 +1,126 @@
<template> <template>
<el-form size="small"> <el-form>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="1"> <el-radio v-model='radioValue' :value="1">
分钟允许的通配符[, - * /] 分钟允许的通配符[, - * /]
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="2"> <el-radio v-model='radioValue' :value="2">
周期从 周期从
<el-input-number v-model='cycle01' :min="0" :max="58" /> - <el-input-number v-model='cycle01' :min="0" :max="58" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> 分钟 <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="59" /> 分钟
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="3"> <el-radio v-model='radioValue' :value="3">
<el-input-number v-model='average01' :min="0" :max="58" /> 分钟开始 <el-input-number v-model='average01' :min="0" :max="58" /> 分钟开始
<el-input-number v-model='average02' :min="1" :max="59 - average01 || 0" /> 分钟执行一次 <el-input-number v-model='average02' :min="1" :max="59 - average01" /> 分钟执行一次
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="4"> <el-radio v-model='radioValue' :value="4">
指定 指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> <el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option> <el-option v-for="item in 60" :key="item" :label="item - 1" :value="item - 1" />
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<script setup>
<script setup lang="ts" name="CrontabMin"> const emit = defineEmits(['update'])
import { ref, computed, watch, defineProps, defineEmits } from 'vue';
const props = defineProps({ const props = defineProps({
check: { cron: {
type: Function, type: Object,
required: true default: {
}, second: "*",
cron: { min: "*",
type: Object, hour: "*",
default: () => ({}) day: "*",
} month: "*",
}); week: "?",
year: "",
const emit = defineEmits(['update']); }
},
const radioValue = ref(1); check: {
const cycle01 = ref(1); type: Function,
const cycle02 = ref(2); default: () => {
const average01 = ref(0); }
const average02 = ref(1); }
const checkboxList = ref([]); })
const radioValue = ref(1)
// const cycle01 = ref(0)
const cycle02 = ref(1)
const average01 = ref(0)
const average02 = ref(1)
const checkboxList = ref([])
const checkCopy = ref([0])
const cycleTotal = computed(() => { const cycleTotal = computed(() => {
const cycleVal01 = props.check(cycle01.value, 0, 58); cycle01.value = props.check(cycle01.value, 0, 58)
const cycleVal02 = props.check(cycle02.value, cycleVal01 ? cycleVal01 + 1 : 1, 59); cycle02.value = props.check(cycle02.value, cycle01.value + 1, 59)
return `${cycleVal01}-${cycleVal02}`; return cycle01.value + '-' + cycle02.value
}); })
//
const averageTotal = computed(() => { const averageTotal = computed(() => {
const averageVal01 = props.check(average01.value, 0, 58); average01.value = props.check(average01.value, 0, 58)
const averageVal02 = props.check(average02.value, 1, 59 - averageVal01 || 0); average02.value = props.check(average02.value, 1, 59 - average01.value)
return `${averageVal01}/${averageVal02}`; return average01.value + '/' + average02.value
}); })
// checkbox
const checkboxString = computed(() => { const checkboxString = computed(() => {
let str = checkboxList.value.join(); return checkboxList.value.join(',')
return str === '' ? '*' : str; })
}); watch(() => props.cron.min, value => changeRadioValue(value))
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
// function changeRadioValue(value) {
const radioChange = () => { if (value === '*') {
switch (radioValue.value) { radioValue.value = 1
case 1: } else if (value.indexOf('-') > -1) {
emit('update', 'min', '*', 'min'); const indexArr = value.split('-')
break; cycle01.value = Number(indexArr[0])
case 2: cycle02.value = Number(indexArr[1])
emit('update', 'min', cycleTotal.value, 'min'); radioValue.value = 2
break; } else if (value.indexOf('/') > -1) {
case 3: const indexArr = value.split('/')
emit('update', 'min', averageTotal.value, 'min'); average01.value = Number(indexArr[0])
break; average02.value = Number(indexArr[1])
case 4: radioValue.value = 3
emit('update', 'min', checkboxString.value, 'min'); } else {
break; checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
} radioValue.value = 4
}; }
}
// function onRadioChange() {
const cycleChange = () => { switch (radioValue.value) {
if (radioValue.value === 2) { case 1:
emit('update', 'min', cycleTotal.value, 'min'); emit('update', 'min', '*', 'min')
} break
}; case 2:
emit('update', 'min', cycleTotal.value, 'min')
// break
const averageChange = () => { case 3:
if (radioValue.value === 3) { emit('update', 'min', averageTotal.value, 'min')
emit('update', 'min', averageTotal.value, 'min'); break
} case 4:
}; if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0])
// checkbox } else {
const checkboxChange = () => { checkCopy.value = checkboxList.value
if (radioValue.value === 4) { }
emit('update', 'min', checkboxString.value, 'min'); emit('update', 'min', checkboxString.value, 'min')
} break
}; }
}
// </script>
watch(() => radioValue.value, radioChange);
watch(() => cycleTotal.value, cycleChange); <style lang="scss" scoped>
watch(() => averageTotal.value, averageChange); .el-input-number--small, .el-select, .el-select--small {
watch(() => checkboxString.value, checkboxChange); margin: 0 0.2rem;
</script> }
.el-select, .el-select--small {
width: 19.8rem;
}
</style>

@ -1,123 +1,141 @@
<template> <template>
<el-form size='small'> <el-form>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="1"> <el-radio v-model='radioValue' :value="1">
允许的通配符[, - * /] 允许的通配符[, - * /]
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="2"> <el-radio v-model='radioValue' :value="2">
周期从 周期从
<el-input-number v-model='cycle01' :min="1" :max="11" /> - <el-input-number v-model='cycle01' :min="1" :max="11" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 2" :max="12" /> <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="12" />
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="3"> <el-radio v-model='radioValue' :value="3">
<el-input-number v-model='average01' :min="1" :max="11" /> 月开始 <el-input-number v-model='average01' :min="1" :max="11" /> 月开始
<el-input-number v-model='average02' :min="1" :max="12 - average01 || 0" /> 月月执行一次 <el-input-number v-model='average02' :min="1" :max="12 - average01" /> 月月执行一次
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="4"> <el-radio v-model='radioValue' :value="4">
指定 指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> <el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="8">
<el-option v-for="item in 12" :key="item" :value="item">{{item}}</el-option> <el-option v-for="item in monthList" :key="item.key" :label="item.value" :value="item.key" />
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<script setup lang="ts" name="CrontabMonth"> <script setup>
import { ref, computed, watch, defineProps, defineEmits } from 'vue'; const emit = defineEmits(['update'])
const props = defineProps({ const props = defineProps({
check: { cron: {
type: Function, type: Object,
required: true default: {
}, second: "*",
cron: { min: "*",
type: Object, hour: "*",
default: () => ({}) day: "*",
} month: "*",
}); week: "?",
year: "",
const emit = defineEmits(['update']); }
},
const radioValue = ref(1); check: {
const cycle01 = ref(1); type: Function,
const cycle02 = ref(2); default: () => {
const average01 = ref(1); }
const average02 = ref(1); }
const checkboxList = ref([]); })
const radioValue = ref(1)
// const cycle01 = ref(1)
const cycle02 = ref(2)
const average01 = ref(1)
const average02 = ref(1)
const checkboxList = ref([])
const checkCopy = ref([1])
const monthList = ref([
{key: 1, value: '一月'},
{key: 2, value: '二月'},
{key: 3, value: '三月'},
{key: 4, value: '四月'},
{key: 5, value: '五月'},
{key: 6, value: '六月'},
{key: 7, value: '七月'},
{key: 8, value: '八月'},
{key: 9, value: '九月'},
{key: 10, value: '十月'},
{key: 11, value: '十一月'},
{key: 12, value: '十二月'}
])
const cycleTotal = computed(() => { const cycleTotal = computed(() => {
const cycleVal01 = props.check(cycle01.value, 1, 11); cycle01.value = props.check(cycle01.value, 1, 11)
const cycleVal02 = props.check(cycle02.value, cycleVal01 ? cycleVal01 + 1 : 2, 12); cycle02.value = props.check(cycle02.value, cycle01.value + 1, 12)
return `${cycleVal01}-${cycleVal02}`; return cycle01.value + '-' + cycle02.value
}); })
//
const averageTotal = computed(() => { const averageTotal = computed(() => {
const averageVal01 = props.check(average01.value, 1, 11); average01.value = props.check(average01.value, 1, 11)
const averageVal02 = props.check(average02.value, 1, 12 - averageVal01 || 0); average02.value = props.check(average02.value, 1, 12 - average01.value)
return `${averageVal01}/${averageVal02}`; return average01.value + '/' + average02.value
}); })
// checkbox
const checkboxString = computed(() => { const checkboxString = computed(() => {
let str = checkboxList.value.join(); return checkboxList.value.join(',')
return str === '' ? '*' : str; })
}); watch(() => props.cron.month, value => changeRadioValue(value))
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
// function changeRadioValue(value) {
const radioChange = () => { if (value === '*') {
switch (radioValue.value) { radioValue.value = 1
case 1: } else if (value.indexOf('-') > -1) {
emit('update', 'month', '*'); const indexArr = value.split('-')
break; cycle01.value = Number(indexArr[0])
case 2: cycle02.value = Number(indexArr[1])
emit('update', 'month', cycleTotal.value); radioValue.value = 2
break; } else if (value.indexOf('/') > -1) {
case 3: const indexArr = value.split('/')
emit('update', 'month', averageTotal.value); average01.value = Number(indexArr[0])
break; average02.value = Number(indexArr[1])
case 4: radioValue.value = 3
emit('update', 'month', checkboxString.value); } else {
break; checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
} radioValue.value = 4
}; }
}
// function onRadioChange() {
const cycleChange = () => { switch (radioValue.value) {
if (radioValue.value === 2) { case 1:
emit('update', 'month', cycleTotal.value); emit('update', 'month', '*', 'month')
} break
}; case 2:
emit('update', 'month', cycleTotal.value, 'month')
// break
const averageChange = () => { case 3:
if (radioValue.value === 3) { emit('update', 'month', averageTotal.value, 'month')
emit('update', 'month', averageTotal.value); break
} case 4:
}; if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0])
// checkbox } else {
const checkboxChange = () => { checkCopy.value = checkboxList.value
if (radioValue.value === 4) { }
emit('update', 'month', checkboxString.value); emit('update', 'month', checkboxString.value, 'month')
} break
}; }
}
//
watch(() => radioValue.value, radioChange);
watch(() => cycleTotal.value, cycleChange);
watch(() => averageTotal.value, averageChange);
watch(() => checkboxString.value, checkboxChange);
</script> </script>
<style lang="scss" scoped>
.el-input-number--small, .el-select, .el-select--small {
margin: 0 0.2rem;
}
.el-select, .el-select--small {
width: 18.8rem;
}
</style>

File diff suppressed because it is too large Load Diff

@ -1,132 +1,128 @@
<template> <template>
<el-form size="small"> <el-form>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="1"> <el-radio v-model='radioValue' :value="1">
允许的通配符[, - * /] 允许的通配符[, - * /]
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="2"> <el-radio v-model='radioValue' :value="2">
周期从 周期从
<el-input-number v-model='cycle01' :min="0" :max="58" /> - <el-input-number v-model='cycle01' :min="0" :max="58" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="59" />
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="3"> <el-radio v-model='radioValue' :value="3">
<el-input-number v-model='average01' :min="0" :max="58" /> 秒开始 <el-input-number v-model='average01' :min="0" :max="58" /> 秒开始
<el-input-number v-model='average02' :min="1" :max="59 - average01 || 0" /> 秒执行一次 <el-input-number v-model='average02' :min="1" :max="59 - average01" /> 秒执行一次
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="4"> <el-radio v-model='radioValue' :value="4">
指定 指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> <el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option> <el-option v-for="item in 60" :key="item" :label="item - 1" :value="item - 1" />
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<script setup lang="ts" name="CrontabSecond"> <script setup>
import { ref, computed, watch, defineProps, defineEmits } from 'vue'; const emit = defineEmits(['update'])
const props = defineProps({ const props = defineProps({
check: { cron: {
type: Function, type: Object,
required: true default: {
}, second: "*",
radioParent: { min: "*",
type: Number, hour: "*",
default: undefined day: "*",
}, month: "*",
cron: { week: "?",
type: Object, year: "",
default: () => ({}) }
} },
}); check: {
type: Function,
const emit = defineEmits(['update']); default: () => {
}
const radioValue = ref(1); }
const cycle01 = ref(1); })
const cycle02 = ref(2); const radioValue = ref(1)
const average01 = ref(0); const cycle01 = ref(0)
const average02 = ref(1); const cycle02 = ref(1)
const checkboxList = ref([]); const average01 = ref(0)
const average02 = ref(1)
// const checkboxList = ref([])
const checkCopy = ref([0])
const cycleTotal = computed(() => { const cycleTotal = computed(() => {
const cycleVal01 = props.check(cycle01.value, 0, 58); cycle01.value = props.check(cycle01.value, 0, 58)
const cycleVal02 = props.check(cycle02.value, cycleVal01 ? cycleVal01 + 1 : 1, 59); cycle02.value = props.check(cycle02.value, cycle01.value + 1, 59)
return `${cycleVal01}-${cycleVal02}`; return cycle01.value + '-' + cycle02.value
}); })
//
const averageTotal = computed(() => { const averageTotal = computed(() => {
const averageVal01 = props.check(average01.value, 0, 58); average01.value = props.check(average01.value, 0, 58)
const averageVal02 = props.check(average02.value, 1, 59 - averageVal01 || 0); average02.value = props.check(average02.value, 1, 59 - average01.value)
return `${averageVal01}/${averageVal02}`; return average01.value + '/' + average02.value
}); })
// checkbox
const checkboxString = computed(() => { const checkboxString = computed(() => {
let str = checkboxList.value.join(); return checkboxList.value.join(',')
return str === '' ? '*' : str; })
}); watch(() => props.cron.second, value => changeRadioValue(value))
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
function changeRadioValue(value) {
if (value === '*') {
radioValue.value = 1
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-')
cycle01.value = Number(indexArr[0])
cycle02.value = Number(indexArr[1])
radioValue.value = 2
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/')
average01.value = Number(indexArr[0])
average02.value = Number(indexArr[1])
radioValue.value = 3
} else {
checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
radioValue.value = 4
}
}
// //
const radioChange = () => { function onRadioChange() {
switch (radioValue.value) { switch (radioValue.value) {
case 1: case 1:
emit('update', 'second', '*', 'second'); emit('update', 'second', '*', 'second')
break; break
case 2: case 2:
emit('update', 'second', cycleTotal.value); emit('update', 'second', cycleTotal.value, 'second')
break; break
case 3: case 3:
emit('update', 'second', averageTotal.value); emit('update', 'second', averageTotal.value, 'second')
break; break
case 4: case 4:
emit('update', 'second', checkboxString.value); if (checkboxList.value.length === 0) {
break; checkboxList.value.push(checkCopy.value[0])
} } else {
}; checkCopy.value = checkboxList.value
}
// emit('update', 'second', checkboxString.value, 'second')
const cycleChange = () => { break
if (radioValue.value === 2) { }
emit('update', 'second', cycleTotal.value); }
}
};
//
const averageChange = () => {
if (radioValue.value === 3) {
emit('update', 'second', averageTotal.value);
}
};
// checkbox
const checkboxChange = () => {
if (radioValue.value === 4) {
emit('update', 'second', checkboxString.value);
}
};
//
watch(() => radioValue.value, radioChange);
watch(() => cycleTotal.value, cycleChange);
watch(() => averageTotal.value, averageChange);
watch(() => checkboxString.value, checkboxChange);
watch(() => props.radioParent, (newVal) => {
if (newVal !== undefined) {
radioValue.value = newVal;
}
});
</script> </script>
<style lang="scss" scoped>
.el-input-number--small, .el-select, .el-select--small {
margin: 0 0.2rem;
}
.el-select, .el-select--small {
width: 18.8rem;
}
</style>

@ -1,212 +1,197 @@
<template> <template>
<el-form size='small'> <el-form>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="1"> <el-radio v-model='radioValue' :value="1">
允许的通配符[, - * ? / L #] 允许的通配符[, - * ? / L #]
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="2"> <el-radio v-model='radioValue' :value="2">
不指定 不指定
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="3"> <el-radio v-model='radioValue' :value="3">
周期从星期 周期从
<el-select clearable v-model="cycle01"> <el-select clearable v-model="cycle01">
<el-option <el-option
v-for="(item,index) of weekList" v-for="(item,index) of weekList"
:key="index" :key="index"
:label="item.value" :label="item.value"
:value="item.key" :value="item.key"
:disabled="item.key === 1" :disabled="item.key === 7"
>{{item.value}}</el-option> >{{item.value}}</el-option>
</el-select> </el-select>
- -
<el-select clearable v-model="cycle02"> <el-select clearable v-model="cycle02">
<el-option <el-option
v-for="(item,index) of weekList" v-for="(item,index) of weekList"
:key="index" :key="index"
:label="item.value" :label="item.value"
:value="item.key" :value="item.key"
:disabled="item.key < cycle01 && item.key !== 1" :disabled="item.key <= cycle01"
>{{item.value}}</el-option> >{{item.value}}</el-option>
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="4"> <el-radio v-model='radioValue' :value="4">
<el-input-number v-model='average01' :min="1" :max="4" /> 周的星期 <el-input-number v-model='average01' :min="1" :max="4" /> 周的
<el-select clearable v-model="average02"> <el-select clearable v-model="average02">
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key">{{item.value}}</el-option> <el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" />
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="5"> <el-radio v-model='radioValue' :value="5">
本月最后一个星期 本月最后一个
<el-select clearable v-model="weekday"> <el-select clearable v-model="weekday">
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key">{{item.value}}</el-option> <el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" />
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="6"> <el-radio v-model='radioValue' :value="6">
指定 指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> <el-select class="multiselect" clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="6">
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="String(item.key)">{{item.value}}</el-option> <el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" />
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<script setup lang="ts" name="CrontabWeek"> <script setup>
import { ref, computed, watch, defineProps, defineEmits } from 'vue'; const emit = defineEmits(['update'])
const props = defineProps({ const props = defineProps({
check: { cron: {
type: Function, type: Object,
required: true default: {
}, second: "*",
cron: { min: "*",
type: Object, hour: "*",
default: () => ({}) day: "*",
} month: "*",
}); week: "?",
year: ""
const emit = defineEmits(['update']); }
},
const radioValue = ref(2); check: {
const weekday = ref(2); type: Function,
const cycle01 = ref(2); default: () => {
const cycle02 = ref(3); }
const average01 = ref(1); }
const average02 = ref(2); })
const checkboxList = ref([]); const radioValue = ref(2)
const cycle01 = ref(2)
const cycle02 = ref(3)
const average01 = ref(1)
const average02 = ref(2)
const weekday = ref(2)
const checkboxList = ref([])
const checkCopy = ref([2])
const weekList = ref([ const weekList = ref([
{ {key: 1, value: '星期日'},
key: 2, {key: 2, value: '星期一'},
value: '星期一' {key: 3, value: '星期二'},
}, {key: 4, value: '星期三'},
{ {key: 5, value: '星期四'},
key: 3, {key: 6, value: '星期五'},
value: '星期二' {key: 7, value: '星期六'}
}, ])
{
key: 4,
value: '星期三'
},
{
key: 5,
value: '星期四'
},
{
key: 6,
value: '星期五'
},
{
key: 7,
value: '星期六'
},
{
key: 1,
value: '星期日'
}
]);
//
const cycleTotal = computed(() => { const cycleTotal = computed(() => {
const cycleVal01 = props.check(cycle01.value, 1, 7); cycle01.value = props.check(cycle01.value, 1, 6)
const cycleVal02 = props.check(cycle02.value, 1, 7); cycle02.value = props.check(cycle02.value, cycle01.value + 1, 7)
return `${cycleVal01}-${cycleVal02}`; return cycle01.value + '-' + cycle02.value
}); })
//
const averageTotal = computed(() => { const averageTotal = computed(() => {
const averageVal01 = props.check(average01.value, 1, 4); average01.value = props.check(average01.value, 1, 4)
const averageVal02 = props.check(average02.value, 1, 7); average02.value = props.check(average02.value, 1, 7)
return `${averageVal02}#${averageVal01}`; return average02.value + '#' + average01.value
}); })
const weekdayTotal = computed(() => {
// weekday.value = props.check(weekday.value, 1, 7)
const weekdayCheck = computed(() => { return weekday.value + 'L'
return props.check(weekday.value, 1, 7); })
});
// checkbox
const checkboxString = computed(() => { const checkboxString = computed(() => {
let str = checkboxList.value.join(); return checkboxList.value.join(',')
return str === '' ? '*' : str; })
}); watch(() => props.cron.week, value => changeRadioValue(value))
watch([radioValue, cycleTotal, averageTotal, weekdayTotal, checkboxString], () => onRadioChange())
// function changeRadioValue(value) {
const radioChange = () => { if (value === "*") {
if (radioValue.value !== 2 && props.cron.day !== '?') { radioValue.value = 1
emit('update', 'day', '?', 'week'); } else if (value === "?") {
} radioValue.value = 2
switch (radioValue.value) { } else if (value.indexOf("-") > -1) {
case 1: const indexArr = value.split('-')
emit('update', 'week', '*'); cycle01.value = Number(indexArr[0])
break; cycle02.value = Number(indexArr[1])
case 2: radioValue.value = 3
emit('update', 'week', '?'); } else if (value.indexOf("#") > -1) {
break; const indexArr = value.split('#')
case 3: average01.value = Number(indexArr[1])
emit('update', 'week', cycleTotal.value); average02.value = Number(indexArr[0])
break; radioValue.value = 4
case 4: } else if (value.indexOf("L") > -1) {
emit('update', 'week', averageTotal.value); const indexArr = value.split("L")
break; weekday.value = Number(indexArr[0])
case 5: radioValue.value = 5
emit('update', 'week', weekdayCheck.value + 'L'); } else {
break; checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
case 6: radioValue.value = 6
emit('update', 'week', checkboxString.value); }
break; }
} function onRadioChange() {
}; if (radioValue.value === 2 && props.cron.day === '?') {
emit('update', 'day', '*', 'week')
// }
const cycleChange = () => { if (radioValue.value !== 2 && props.cron.day !== '?') {
if (radioValue.value === 3) { emit('update', 'day', '?', 'week')
emit('update', 'week', cycleTotal.value); }
} switch (radioValue.value) {
}; case 1:
emit('update', 'week', '*', 'week')
// break
const averageChange = () => { case 2:
if (radioValue.value === 4) { emit('update', 'week', '?', 'week')
emit('update', 'week', averageTotal.value); break
} case 3:
}; emit('update', 'week', cycleTotal.value, 'week')
break
// case 4:
const weekdayChange = () => { emit('update', 'week', averageTotal.value, 'week')
if (radioValue.value === 5) { break
emit('update', 'week', weekday.value + 'L'); case 5:
} emit('update', 'week', weekdayTotal.value, 'week')
}; break
case 6:
// checkbox if (checkboxList.value.length === 0) {
const checkboxChange = () => { checkboxList.value.push(checkCopy.value[0])
if (radioValue.value === 6) { } else {
emit('update', 'week', checkboxString.value); checkCopy.value = checkboxList.value
} }
}; emit('update', 'week', checkboxString.value, 'week')
break
// }
watch(() => radioValue.value, radioChange); }
watch(() => cycleTotal.value, cycleChange);
watch(() => averageTotal.value, averageChange);
watch(() => weekdayCheck.value, weekdayChange);
watch(() => checkboxString.value, checkboxChange);
</script> </script>
<style lang="scss" scoped>
.el-input-number--small, .el-select, .el-select--small {
margin: 0 0.5rem;
}
.el-select, .el-select--small {
width: 8rem;
}
.el-select.multiselect, .el-select--small.multiselect {
width: 17.8rem;
}
</style>

@ -1,145 +1,149 @@
<template> <template>
<el-form size="small"> <el-form>
<el-form-item> <el-form-item>
<el-radio :label="1" v-model='radioValue'> <el-radio :value="1" v-model='radioValue'>
不填允许的通配符[, - * /] 不填允许的通配符[, - * /]
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio :label="2" v-model='radioValue'> <el-radio :value="2" v-model='radioValue'>
每年 每年
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio :label="3" v-model='radioValue'> <el-radio :value="3" v-model='radioValue'>
周期从 周期从
<el-input-number v-model='cycle01' :min='fullYear' :max="2098" /> - <el-input-number v-model='cycle01' :min='fullYear' :max="2098"/> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : fullYear + 1" :max="2099" /> <el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : fullYear + 1" :max="2099"/>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio :label="4" v-model='radioValue'> <el-radio :value="4" v-model='radioValue'>
<el-input-number v-model='average01' :min='fullYear' :max="2098"/> 年开始 <el-input-number v-model='average01' :min='fullYear' :max="2098"/> 年开始
<el-input-number v-model='average02' :min="1" :max="2099 - average01 || fullYear" /> 年执行一次 <el-input-number v-model='average02' :min="1" :max="2099 - average01 || fullYear"/> 年执行一次
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio :label="5" v-model='radioValue'> <el-radio :value="5" v-model='radioValue'>
指定 指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple> <el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="8">
<el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear" :label="item -1 + fullYear" /> <el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear" :label="item -1 + fullYear" />
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<script setup lang="ts" name="CrontabYear"> <script setup>
import { ref, computed, watch, defineProps, defineEmits, onMounted } from 'vue'; const emit = defineEmits(['update'])
const props = defineProps({ const props = defineProps({
check: { cron: {
type: Function, type: Object,
required: true default: {
}, second: "*",
month: { min: "*",
type: [String, Number], hour: "*",
default: '' day: "*",
}, month: "*",
cron: { week: "?",
type: Object, year: ""
default: () => ({}) }
} },
}); check: {
type: Function,
const emit = defineEmits(['update']); default: () => {
}
const fullYear = ref(0); }
const radioValue = ref(1); })
const cycle01 = ref(0); const fullYear = ref(0)
const cycle02 = ref(0); const maxFullYear = ref(0)
const average01 = ref(0); const radioValue = ref(1)
const average02 = ref(1); const cycle01 = ref(0)
const checkboxList = ref([]); const cycle02 = ref(0)
const average01 = ref(0)
// const average02 = ref(1)
const checkboxList = ref([])
const checkCopy = ref([])
const cycleTotal = computed(() => { const cycleTotal = computed(() => {
const cycleVal01 = props.check(cycle01.value, fullYear.value, 2098); cycle01.value = props.check(cycle01.value, fullYear.value, maxFullYear.value - 1)
const cycleVal02 = props.check(cycle02.value, cycleVal01 ? cycleVal01 + 1 : fullYear.value + 1, 2099); cycle02.value = props.check(cycle02.value, cycle01.value + 1, maxFullYear.value)
return `${cycleVal01}-${cycleVal02}`; return cycle01.value + '-' + cycle02.value
}); })
//
const averageTotal = computed(() => { const averageTotal = computed(() => {
const averageVal01 = props.check(average01.value, fullYear.value, 2098); average01.value = props.check(average01.value, fullYear.value, maxFullYear.value - 1)
const averageVal02 = props.check(average02.value, 1, 2099 - averageVal01 || fullYear.value); average02.value = props.check(average02.value, 1, 10)
return `${averageVal01}/${averageVal02}`; return average01.value + '/' + average02.value
}); })
// checkbox
const checkboxString = computed(() => { const checkboxString = computed(() => {
return checkboxList.value.join(); return checkboxList.value.join(',')
}); })
watch(() => props.cron.year, value => changeRadioValue(value))
// watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
const radioChange = () => { function changeRadioValue(value) {
switch (radioValue.value) { if (value === '') {
case 1: radioValue.value = 1
emit('update', 'year', ''); } else if (value === "*") {
break; radioValue.value = 2
case 2: } else if (value.indexOf("-") > -1) {
emit('update', 'year', '*'); const indexArr = value.split('-')
break; cycle01.value = Number(indexArr[0])
case 3: cycle02.value = Number(indexArr[1])
emit('update', 'year', cycleTotal.value); radioValue.value = 3
break; } else if (value.indexOf("/") > -1) {
case 4: const indexArr = value.split('/')
emit('update', 'year', averageTotal.value); average01.value = Number(indexArr[1])
break; average02.value = Number(indexArr[0])
case 5: radioValue.value = 4
emit('update', 'year', checkboxString.value); } else {
break; checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
} radioValue.value = 5
}; }
}
// function onRadioChange() {
const cycleChange = () => { switch (radioValue.value) {
if (radioValue.value === 3) { case 1:
emit('update', 'year', cycleTotal.value); emit('update', 'year', '', 'year')
} break
}; case 2:
emit('update', 'year', '*', 'year')
// break
const averageChange = () => { case 3:
if (radioValue.value === 4) { emit('update', 'year', cycleTotal.value, 'year')
emit('update', 'year', averageTotal.value); break
} case 4:
}; emit('update', 'year', averageTotal.value, 'year')
break
// checkbox case 5:
const checkboxChange = () => { if (checkboxList.value.length === 0) {
if (radioValue.value === 5) { checkboxList.value.push(checkCopy.value[0])
emit('update', 'year', checkboxString.value); } else {
} checkCopy.value = checkboxList.value
}; }
emit('update', 'year', checkboxString.value, 'year')
// break
watch(() => radioValue.value, radioChange); }
watch(() => cycleTotal.value, cycleChange); }
watch(() => averageTotal.value, averageChange);
watch(() => checkboxString.value, checkboxChange);
//
onMounted(() => { onMounted(() => {
// fullYear.value = Number(new Date().getFullYear())
fullYear.value = Number(new Date().getFullYear()); maxFullYear.value = fullYear.value + 10
cycle01.value = fullYear.value; cycle01.value = fullYear.value
average01.value = fullYear.value; cycle02.value = cycle01.value + 1
}); average01.value = fullYear.value
checkCopy.value = [fullYear.value]
})
</script> </script>
<style lang="scss" scoped>
.el-input-number--small, .el-select, .el-select--small {
margin: 0 0.2rem;
}
.el-select, .el-select--small {
width: 18.8rem;
}
</style>
Loading…
Cancel
Save