cron表达式可视化配置替换成自定义组件
This commit is contained in:
330
src/components/CronExpressionEditor.vue
Normal file
330
src/components/CronExpressionEditor.vue
Normal file
@@ -0,0 +1,330 @@
|
||||
<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>
|
||||
@@ -57,15 +57,10 @@
|
||||
label="执行频率"
|
||||
prop="cron_expression"
|
||||
v-if="formData.execution_type === 'automatic'">
|
||||
<el-input
|
||||
<cron-expression-editor
|
||||
v-model="formData.cron_expression"
|
||||
placeholder="请输入cron表达式,如:0 0 6 * * *"
|
||||
>
|
||||
<template #append>
|
||||
<el-button @click="showCronDialog = true">可视化配置</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<div class="form-item-tip">Cron表达式格式:秒 分 时 日 月 周</div>
|
||||
/>
|
||||
<div class="form-item-tip">Cron表达式格式:分 时 日 月 周</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
@@ -81,35 +76,17 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- Cron表达式可视化配置对话框 -->
|
||||
<el-dialog
|
||||
v-model="showCronDialog"
|
||||
title="可视化配置执行频率"
|
||||
width="800px"
|
||||
:before-close="handleCronDialogClose"
|
||||
>
|
||||
<div style="padding: 10px 20px;">
|
||||
<vue3-cron-plus-picker
|
||||
@fill="handleCronFill"
|
||||
@hide="handleCronDialogClose"
|
||||
:expression="tempCronExpression"
|
||||
:hide-year="true"
|
||||
/>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, reactive, computed, watch } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { Vue3CronPlusPicker } from 'vue3-cron-plus-picker';
|
||||
import 'vue3-cron-plus-picker/style.css';
|
||||
import CronExpressionEditor from './CronExpressionEditor.vue';
|
||||
|
||||
export default {
|
||||
name: 'PlanForm',
|
||||
components: {
|
||||
Vue3CronPlusPicker
|
||||
CronExpressionEditor
|
||||
},
|
||||
props: {
|
||||
visible: {
|
||||
@@ -133,12 +110,6 @@ export default {
|
||||
// 加载状态
|
||||
const loading = ref(false);
|
||||
|
||||
// 是否显示Cron表达式配置对话框
|
||||
const showCronDialog = ref(false);
|
||||
|
||||
// 临时存储cron表达式
|
||||
const tempCronExpression = ref('');
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
id: null,
|
||||
@@ -183,18 +154,6 @@ export default {
|
||||
}
|
||||
};
|
||||
|
||||
// 处理Cron表达式填充
|
||||
const handleCronFill = (cronExpression) => {
|
||||
formData.cron_expression = cronExpression;
|
||||
tempCronExpression.value = cronExpression;
|
||||
showCronDialog.value = false;
|
||||
};
|
||||
|
||||
// 处理Cron对话框关闭
|
||||
const handleCronDialogClose = () => {
|
||||
showCronDialog.value = false;
|
||||
};
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
emit('update:visible', false);
|
||||
@@ -239,9 +198,6 @@ export default {
|
||||
formData[key] = newVal[key];
|
||||
}
|
||||
});
|
||||
|
||||
// 初始化临时cron表达式
|
||||
tempCronExpression.value = newVal.cron_expression || '';
|
||||
} else {
|
||||
// 重置表单数据
|
||||
Object.keys(formData).forEach(key => {
|
||||
@@ -253,21 +209,16 @@ export default {
|
||||
});
|
||||
// 默认值
|
||||
formData.execution_type = 'automatic';
|
||||
tempCronExpression.value = '';
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
return {
|
||||
formRef,
|
||||
loading,
|
||||
showCronDialog,
|
||||
tempCronExpression,
|
||||
formData,
|
||||
rules,
|
||||
title,
|
||||
handleExecutionTypeChange,
|
||||
handleCronFill,
|
||||
handleCronDialogClose,
|
||||
handleClose,
|
||||
handleSubmit
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user