330 lines
9.9 KiB
Vue
330 lines
9.9 KiB
Vue
<template>
|
||
<div class="cron-expression-editor">
|
||
<el-input
|
||
v-model="cronExpression"
|
||
placeholder="请输入标准Unix 5位cron表达式,如: 0 0 * * *"
|
||
readonly
|
||
>
|
||
<template #append>
|
||
<el-button @click="openCronDialog">可视化配置</el-button>
|
||
</template>
|
||
</el-input>
|
||
|
||
<el-dialog
|
||
v-model="showCronDialog"
|
||
title="可视化配置Cron表达式"
|
||
width="600px"
|
||
:before-close="handleCronDialogClose"
|
||
>
|
||
<div class="cron-dialog-content">
|
||
<el-form :model="cronConfig" label-width="100px">
|
||
<!-- 分 -->
|
||
<el-form-item label="分">
|
||
<el-select
|
||
v-model="cronConfig.minute"
|
||
placeholder="请选择分钟"
|
||
clearable
|
||
filterable
|
||
allow-create
|
||
default-first-option
|
||
>
|
||
<el-option label="*" value="*">
|
||
<span>*</span>
|
||
<span class="option-desc">每分钟</span>
|
||
</el-option>
|
||
<el-option label="*/5" value="*/5">
|
||
<span>*/5</span>
|
||
<span class="option-desc">每隔5分钟</span>
|
||
</el-option>
|
||
<el-option label="*/10" value="*/10">
|
||
<span>*/10</span>
|
||
<span class="option-desc">每隔10分钟</span>
|
||
</el-option>
|
||
<el-option label="*/15" value="*/15">
|
||
<span>*/15</span>
|
||
<span class="option-desc">每隔15分钟</span>
|
||
</el-option>
|
||
<el-option label="*/30" value="*/30">
|
||
<span>*/30</span>
|
||
<span class="option-desc">每隔30分钟</span>
|
||
</el-option>
|
||
<el-option
|
||
v-for="minute in 60"
|
||
:key="minute-1"
|
||
:label="minute-1"
|
||
:value="(minute-1).toString()"
|
||
>
|
||
<span>{{ minute-1 }}</span>
|
||
<span class="option-desc">第{{ minute-1 }}分钟</span>
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<!-- 时 -->
|
||
<el-form-item label="时">
|
||
<el-select
|
||
v-model="cronConfig.hour"
|
||
placeholder="请选择小时"
|
||
clearable
|
||
filterable
|
||
allow-create
|
||
default-first-option
|
||
>
|
||
<el-option label="*" value="*">
|
||
<span>*</span>
|
||
<span class="option-desc">每小时</span>
|
||
</el-option>
|
||
<el-option label="*/2" value="*/2">
|
||
<span>*/2</span>
|
||
<span class="option-desc">每隔2小时</span>
|
||
</el-option>
|
||
<el-option label="*/3" value="*/3">
|
||
<span>*/3</span>
|
||
<span class="option-desc">每隔3小时</span>
|
||
</el-option>
|
||
<el-option label="*/6" value="*/6">
|
||
<span>*/6</span>
|
||
<span class="option-desc">每隔6小时</span>
|
||
</el-option>
|
||
<el-option label="*/12" value="*/12">
|
||
<span>*/12</span>
|
||
<span class="option-desc">每隔12小时</span>
|
||
</el-option>
|
||
<el-option
|
||
v-for="hour in 24"
|
||
:key="hour-1"
|
||
:label="hour-1"
|
||
:value="(hour-1).toString()"
|
||
>
|
||
<span>{{ hour-1 }}</span>
|
||
<span class="option-desc">{{ hour-1 }}点</span>
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<!-- 日 -->
|
||
<el-form-item label="日">
|
||
<el-select
|
||
v-model="cronConfig.day"
|
||
placeholder="请选择日期"
|
||
clearable
|
||
filterable
|
||
allow-create
|
||
default-first-option
|
||
>
|
||
<el-option label="*" value="*">
|
||
<span>*</span>
|
||
<span class="option-desc">每天</span>
|
||
</el-option>
|
||
<el-option label="*/2" value="*/2">
|
||
<span>*/2</span>
|
||
<span class="option-desc">每隔2天</span>
|
||
</el-option>
|
||
<el-option label="*/7" value="*/7">
|
||
<span>*/7</span>
|
||
<span class="option-desc">每隔7天</span>
|
||
</el-option>
|
||
<el-option label="*/15" value="*/15">
|
||
<span>*/15</span>
|
||
<span class="option-desc">每隔15天</span>
|
||
</el-option>
|
||
<el-option
|
||
v-for="day in 31"
|
||
:key="day"
|
||
:label="day"
|
||
:value="day.toString()"
|
||
>
|
||
<span>{{ day }}</span>
|
||
<span class="option-desc">每月{{ day }}日</span>
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<!-- 月 -->
|
||
<el-form-item label="月">
|
||
<el-select
|
||
v-model="cronConfig.month"
|
||
placeholder="请选择月份"
|
||
clearable
|
||
filterable
|
||
allow-create
|
||
default-first-option
|
||
>
|
||
<el-option label="*" value="*">
|
||
<span>*</span>
|
||
<span class="option-desc">每月</span>
|
||
</el-option>
|
||
<el-option label="*/2" value="*/2">
|
||
<span>*/2</span>
|
||
<span class="option-desc">每隔2个月</span>
|
||
</el-option>
|
||
<el-option label="*/3" value="*/3">
|
||
<span>*/3</span>
|
||
<span class="option-desc">每隔3个月</span>
|
||
</el-option>
|
||
<el-option label="*/6" value="*/6">
|
||
<span>*/6</span>
|
||
<span class="option-desc">每隔6个月</span>
|
||
</el-option>
|
||
<el-option
|
||
v-for="month in 12"
|
||
:key="month"
|
||
:label="month"
|
||
:value="month.toString()"
|
||
>
|
||
<span>{{ month }}</span>
|
||
<span class="option-desc">第{{ month }}月</span>
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<!-- 周 -->
|
||
<el-form-item label="周">
|
||
<el-select
|
||
v-model="cronConfig.week"
|
||
placeholder="请选择星期"
|
||
clearable
|
||
filterable
|
||
allow-create
|
||
default-first-option
|
||
>
|
||
<el-option label="*" value="*">
|
||
<span>*</span>
|
||
<span class="option-desc">每周</span>
|
||
</el-option>
|
||
<el-option label="1-5" value="1-5">
|
||
<span>1-5</span>
|
||
<span class="option-desc">工作日</span>
|
||
</el-option>
|
||
<el-option
|
||
v-for="(week, index) in weekOptions"
|
||
:key="index"
|
||
:label="week.label"
|
||
:value="index.toString()"
|
||
>
|
||
<span>{{ week.label }}</span>
|
||
<span class="option-desc">{{ week.desc }}</span>
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<el-button @click="handleCronDialogClose">取消</el-button>
|
||
<el-button type="primary" @click="confirmCronExpression">确认</el-button>
|
||
</div>
|
||
</template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { ref, computed, watch, reactive } from 'vue'
|
||
|
||
export default {
|
||
name: 'CronExpressionEditor',
|
||
props: {
|
||
modelValue: {
|
||
type: String,
|
||
default: ''
|
||
}
|
||
},
|
||
emits: ['update:modelValue'],
|
||
setup(props, { emit }) {
|
||
// 是否显示Cron表达式配置对话框
|
||
const showCronDialog = ref(false)
|
||
|
||
// 星期选项
|
||
const weekOptions = [
|
||
{ label: '日', desc: '星期日' },
|
||
{ label: '一', desc: '星期一' },
|
||
{ label: '二', desc: '星期二' },
|
||
{ label: '三', desc: '星期三' },
|
||
{ label: '四', desc: '星期四' },
|
||
{ label: '五', desc: '星期五' },
|
||
{ label: '六', desc: '星期六' }
|
||
]
|
||
|
||
// cron配置
|
||
const cronConfig = reactive({
|
||
minute: '*',
|
||
hour: '*',
|
||
day: '*',
|
||
month: '*',
|
||
week: '*'
|
||
})
|
||
|
||
// 计算属性:cron表达式
|
||
const cronExpression = computed({
|
||
get: () => props.modelValue,
|
||
set: (value) => emit('update:modelValue', value)
|
||
})
|
||
|
||
// 打开Cron对话框
|
||
const openCronDialog = () => {
|
||
// 解析当前的cron表达式
|
||
if (cronExpression.value) {
|
||
const parts = cronExpression.value.split(' ')
|
||
if (parts.length === 5) {
|
||
cronConfig.minute = parts[0]
|
||
cronConfig.hour = parts[1]
|
||
cronConfig.day = parts[2]
|
||
cronConfig.month = parts[3]
|
||
cronConfig.week = parts[4]
|
||
}
|
||
} else {
|
||
// 默认值
|
||
cronConfig.minute = '*'
|
||
cronConfig.hour = '*'
|
||
cronConfig.day = '*'
|
||
cronConfig.month = '*'
|
||
cronConfig.week = '*'
|
||
}
|
||
showCronDialog.value = true
|
||
}
|
||
|
||
// 确认Cron表达式
|
||
const confirmCronExpression = () => {
|
||
cronExpression.value = `${cronConfig.minute} ${cronConfig.hour} ${cronConfig.day} ${cronConfig.month} ${cronConfig.week}`
|
||
showCronDialog.value = false
|
||
}
|
||
|
||
// 处理Cron对话框关闭
|
||
const handleCronDialogClose = () => {
|
||
showCronDialog.value = false
|
||
}
|
||
|
||
return {
|
||
showCronDialog,
|
||
cronConfig,
|
||
cronExpression,
|
||
weekOptions,
|
||
openCronDialog,
|
||
confirmCronExpression,
|
||
handleCronDialogClose
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.cron-expression-editor {
|
||
width: 100%;
|
||
}
|
||
|
||
.cron-dialog-content {
|
||
padding: 20px;
|
||
}
|
||
|
||
.dialog-footer {
|
||
text-align: right;
|
||
}
|
||
|
||
.option-desc {
|
||
float: right;
|
||
color: #8492a6;
|
||
font-size: 13px;
|
||
}
|
||
</style> |