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> |