Quartz的应用之Cron生成表达式html(基于vue、element)

5 篇文章 0 订阅
1 篇文章 0 订阅

一、先看效果

在这里插入图片描述
在这里插入图片描述

二、怎么使用

1、引用组件(注意修改文件路径)

import CustomCronInput from '../../../components/common/CustomCronInput.vue';

2、页面使用

<custom-cron-input v-model="cronExpression"></custom-cron-input>

三、源码如下

CustomCronInput.vue(注意修改引入的文件路径)

<template>
  <div>
    <el-input :value="cron" @input="handleInput" :size="size" placeholder="请输入内容" :readonly="inputReadOnly">
      <el-button slot="append" icon="el-icon-setting" :disabled="buttonDisabled" @click="cronExpDialog">{{buttonText}}
      </el-button>
    </el-input>

    <el-dialog title="Cron表达式"
               v-if="dialogCronExpVisible"
               :visible.sync="dialogCronExpVisible"
               :close-on-click-modal="false">
      <cron-expression :cron="cron" @cancelCron="cancelCron" @saveCron="saveCron"></cron-expression>
    </el-dialog>
  </div>
</template>

<script>
  import CronExpression from '../../components/common/cronExpression/CronExpression.vue';

  export default {
    components: {
      CronExpression
    },
    name: "CustomCronInput",
    model: {
      // 双向绑定
      prop: 'cron',
      event: 'change'
    },
    props: {
      // 输入域大小
      size: {
        type: String,
        default: ''
      },
      // button 显示的文字
      buttonText: {
        type: String,
        default: '配置'
      },
      // 是否禁用button
      buttonDisabled: {
        type: Boolean,
        default: false
      },
      // 是否只读input
      inputReadOnly: {
        type: Boolean,
        default: false
      },
      // 双向绑定
      cron: {
        type: String,
        default: ''
      }
    },
    data() {
      return {
        dialogCronExpVisible: false
      }
    },
    methods: {
      // 打开 cron 表达式选择窗口
      cronExpDialog() {
        this.dialogCronExpVisible = true;
      },
      cancelCron() {
        this.dialogCronExpVisible = false;
      },
      handleInput(value) {
        this.$emit('change', value)
      },
      // 保存cron
      saveCron(cron) {
        this.$emit('change', cron);
        this.dialogCronExpVisible = false;
      }
    }
  }
</script>

CronExpression.vue(注意修改引入的文件路径)
el-dialog 里面弹出的内容

<template>
  <table cellpadding="0" cellspacing="0" style="width: 100%;">
    <tr style="height: 350px">
      <el-tabs v-model="cron_tabs" type="border-card"">
        <el-tab-pane v-for="obj in timeArray"
                     :key="obj.resultNum"
                     :label="obj.name"
                     :name="obj.resultNum">
          <div style="margin-top: 5px">
            <el-radio @change="changeRadio" v-model="obj.radio" label="1">{{obj.label}}</el-radio>
          </div>
          <!-- 天,月,周 公共的 -->
          <div v-if="obj.resultNum == 'day' || obj.resultNum == 'month' || obj.resultNum == 'week'">
            <div style="margin-top: 5px">
              <el-radio @change="changeRadio" v-model="obj.radio" label="2">不指定</el-radio>
            </div>
          </div>
          <div style="margin-top: 5px">
            <el-radio @change="changeRadio" v-model="obj.radio" label="3">周期 从
              <template>
                <template v-if="obj.resultNum == 'week'">{{obj.name}}</template>
                <el-input-number size="mini" v-model="obj.num.cycle1" controls-position="right"
                                 :max="maxNum" :min="minNum" @change="changeNumber"
                                 @focus="changeNumber('3')"></el-input-number>
                -
                <el-input-number size="mini" v-model="obj.num.cycle2" controls-position="right"
                                 :max="maxNum" :min="minNum" @change="changeNumber"
                                 @focus="changeNumber('3')"></el-input-number>
                <template v-if="obj.resultNum != 'week'">{{obj.name}}</template>
              </template>
            </el-radio>
          </div>
          <div style="margin-top: 5px">
            <el-radio @change="changeRadio" v-model="obj.radio" label="4"><template>
                <el-input-number size="mini" v-model="obj.num.begin" controls-position="right" :max="maxNum" :min="minNum"
                                 @change="changeNumber" @focus="changeNumber('4')"></el-input-number>
                {{obj.name}}开始,每
                <el-input-number size="mini" v-model="obj.num.end" controls-position="right" :max="maxNum" :min="minNum"
                                 @change="changeNumber" @focus="changeNumber('4')"></el-input-number>
                {{obj.name}}执行一次
              </template>
            </el-radio>
          </div>
          <!-- 天 -->
          <div v-if="obj.resultNum == 'day'">
            <div style="margin-top: 5px">
              <el-radio @change="changeRadio" v-model="obj.radio" label="5">每月
                <template>
                  <el-input-number size="mini" v-model="obj.num.workDay" controls-position="right" :max="maxNum"
                                   :min="minNum" @change="changeNumber" @focus="changeNumber('5')"></el-input-number>
                  号最近的那个工作日
                </template>
              </el-radio>
            </div>
            <div style="margin-top: 5px">
              <el-radio @change="changeRadio" v-model="obj.radio" label="6">本月最后一天</el-radio>
            </div>
          </div>
          <!-- 周 -->
          <div v-if="obj.resultNum == 'week'">
            <div style="margin-top: 5px">
              <el-radio @change="changeRadio" v-model="obj.radio" label="7"><template>
                  <el-input-number size="mini" v-model="obj.num.weekNum1" controls-position="right" :max="maxNum"
                                   :min="minNum" @change="changeNumber" @focus="changeNumber('7')"></el-input-number>
                  周的星期
                  <el-input-number size="mini" v-model="obj.num.weekNum2" controls-position="right" :max="maxNum"
                                   :min="minNum" @change="changeNumber" @focus="changeNumber('7')"></el-input-number>
                </template>
              </el-radio>
            </div>
            <div style="margin-top: 5px">
              <el-radio @change="changeRadio" v-model="obj.radio" label="8">本月最后一个星期
                <template>
                  <el-input-number size="mini" v-model="obj.num.weekLast" controls-position="right" :max="maxNum"
                                   :min="minNum" @change="changeNumber" @focus="changeNumber('8')"></el-input-number>
                </template>
              </el-radio>
            </div>
          </div>

          <div style="margin-top: 5px" v-if="obj.allElement.length > 0">
            <el-radio @change="changeRadio" v-model="obj.radio" label="9">指定
              <template>
                <el-checkbox-group v-model="obj.checked" @change="changeChecked">
                  <el-checkbox v-for="item in obj.allElement"
                               :label="item"
                               :key="item"
                               style="float:left;margin-left: 15px;">
                    {{item}}
                  </el-checkbox>
                </el-checkbox-group>
              </template>
            </el-radio>
          </div>
        </el-tab-pane>
      </el-tabs>
    </tr>
    <tr>
      <next-run-time :cronExp="triggerCron" :isTestRun="false"></next-run-time>
    </tr>
    <tr>
      <el-button type="primary" @click="saveCron" size="mini">确定</el-button>
      <el-button @click="cancelCron" size="mini">取消</el-button>
    </tr>
  </table>
</template>

<script>
  import NextRunTime from './NextRunTime'

  export default {
    components: {
      NextRunTime
    },
    props: {
      cron: {
        type: String,
        default: '* * * * * ? *'
      }
    },
    data() {
      return {
        triggerCron: '',// 传入后台
        cron_tabs: 'second', // 默认选中的tab
        second: {},
        minute: {},
        hour: {},
        day: {},
        month: {},
        week: {},
        year: {},
        // 用于el-tab-pane 循环
        timeArray: [],
      }
    },
    created() {
      this.initData();
      this.triggerCron = this.cron;
      this.cronTempToRadio();
    },
    methods: {
      initData: function () {
        // 初始化页面数据
        this.second = this.TimeBase('second', '秒');
        this.minute = this.TimeBase('minute', '分钟');
        this.hour = this.TimeBase('hour', '小时');
        this.day = this.TimeBase('day', '天');
        this.month = this.TimeBase('month', '月');
        this.week = this.TimeBase('week', '周');
        this.year = this.TimeBase('year', '年');

        this.timeArray.push(this.second);
        this.timeArray.push(this.minute);
        this.timeArray.push(this.hour);
        this.timeArray.push(this.day);
        this.timeArray.push(this.month);
        this.timeArray.push(this.week);
        this.timeArray.push(this.year);
        for (var i = 0; i < 60; i++) {
          // 秒
          this.second.allElement.push(i + '');
          // 分
          this.minute.allElement = this.second.allElement;
          var value = (i + 1) + '';
          // 时
          if (i < 24) {
            this.hour.allElement.push(value);
          }
          // 天
          if (i < 31) {
            this.day.allElement.push(value);
          }
          // 周
          if (i < 7) {
            this.week.allElement.push(value);
          }
          // 月
          if (i < 12) {
            this.month.allElement.push(value);
          }
        }
      },
      // 时间基类
      TimeBase: function (resultNum, name) {
        var radio = '1';
        var label = '每' + name + ' 允许的通配符[, - * /]';
        if (resultNum === 'day') {
          label = '每天 允许的通配符[, - * / L W]';
        } else if (resultNum === 'week') {
          label = '每周 允许的通配符[, - * / L #]';
          radio = '2';
        }
        var begin = 1;
        if (resultNum === 'second' || resultNum === 'minute' || resultNum === 'hour') {
          begin = 0;
        }

        var rs = {
          name: name,
          resultNum: resultNum,
          allElement: [],
          radio: radio,
          checked: [],
          label: label,
          num: {
            cycle1: 1,
            cycle2: 2,
            begin: begin,
            end: 1,
            workDay: 1,
            weekNum1: 1,
            weekNum2: 1,
            weekLast: 1
          }
        };
        return rs;
      },
      getObject: function () {
        switch (this.cron_tabs) {
          case 'second':
            return this.second;
          case 'minute':
            return this.minute;
          case 'hour':
            return this.hour;
          case 'day':
            return this.day;
          case 'month':
            return this.month;
          case 'week':
            return this.week;
          case 'year':
            return this.year;
          default:
            return null;
        }
      },
      changeRadio() {
        var temp = this.getObject();
        if (temp.radio != 9) {
          temp.checked = [];
        }
        this.changetriggerCron();
      },
      changeNumber(radio) {
        if (radio && typeof(radio) == 'string') {
          var temp = this.getObject();
          temp.radio = radio;
        }
        this.changetriggerCron();
      },
      changeChecked() {
        var temp = this.getObject();
        temp.radio = '9';
        this.changetriggerCron();
      },
      changetriggerCron() {
        var cronTemp = ['*', '*', '*', '*', '*', '?', '*'];
        for (var index in this.timeArray) {
          var temp = this.timeArray[index];
          cronTemp[index] = this.radioToCronTemp(temp);
        }
        this.triggerCron = cronTemp.join(" ");
        // console.info(this.triggerCron);
      },
      radioToCronTemp(temp) {
        switch (temp.radio) {
          case '1':
            return '*';
          case '2':
            return '?';
          case '3':
            return temp.num.cycle1 + '-' + temp.num.cycle2;
          case '4':
            return temp.num.begin + '/' + temp.num.end;
          case '5':
            return temp.num.workDay + 'W';
          case '6':
            return 'L';
          case '7':
            return temp.num.weekNum1 + '#' + temp.num.weekNum2;
          case '8':
            return temp.num.weekLast + 'L';
          case '9':
            return temp.checked.join();
          default:
            return '*';
        }
      },
      cronTempToRadio() {
        if (this.triggerCron && this.triggerCron !== '') {
          var cronTempArray = this.triggerCron.split(" ");
          for (var index in cronTempArray) {
            var cronTemp = cronTempArray[index];
            var temp = this.timeArray[index];
            if (cronTemp === '*') {
              temp.radio = '1';
            } else if (cronTemp === '?') {
              temp.radio = '2';
            } else if (cronTemp.includes("-")) {
              temp.radio = '3';
              temp.num.cycle1 = cronTemp.split("-")[0];
              temp.num.cycle2 = cronTemp.split("-")[1];
            } else if (cronTemp.includes("/")) {
              temp.radio = '4';
              temp.num.begin = cronTemp.split("/")[0];
              temp.num.end = cronTemp.split("/")[1];
            } else if (cronTemp.includes("W")) {
              temp.radio = '5';
              temp.num.workDay = cronTemp.replace("W", "");
            } else if (cronTemp === "L") {
              temp.radio = '6';
            } else if (cronTemp.includes("#")) {
              temp.radio = '7';
              temp.num.weekNum1 = cronTemp.split("#")[0];
              temp.num.weekNum2 = cronTemp.split("#")[1];
            } else if (cronTemp.includes("L")) {
              temp.radio = '8';
              temp.num.weekLast = cronTemp.replace("W", "");
            } else {
              temp.radio = '9';
              cronTemp.includes(",") ? temp.checked = cronTemp.split(",") : temp.checked.push(cronTemp);
            }
          }
        }
      },
      saveCron() {
        this.$emit("saveCron", this.triggerCron);
      },
      cancelCron() {
        this.$emit("cancelCron", this.triggerCron);
      }
    },
    computed: {
      maxNum() {
        var obj = this.cron_tabs;
        return (obj === 'second' || obj === 'minute') ? 59 : obj === 'hour' ? 23 : obj === 'month' ? 12 : obj === 'day' ? 31 : 7;
      },
      minNum() {
        var obj = this.cron_tabs;
        return (obj === 'second' || obj === 'minute' || obj === 'hour') ? 0 : 1;
      }
    }
  }
</script>

NextRunTime.vue(注意修改引入的文件路径)
显示执行计划的部分

<template>
  <section>
    <div>
      <el-row>
        <el-col :span="3">Cron表达式:</el-col>
        <el-col :span="20">
          <el-input v-model="cronExp" :readonly="true" size="mini">
            <el-button slot="append" icon="el-icon-search" @click="testRun">执行计划</el-button>
          </el-input>
        </el-col>
      </el-row>
    </div>
    <div>最后{{times}}次的运行时间:</div>
    <div style="padding-top: 10px;padding-left: 25px;">
      <template v-for="(str,index) in rs">
        {{str}}<br/>
      </template>
    </div>
  </section>
</template>
<script>

  import {TestRunCron} from "../../../api/job/jobMag";

  export default {
    props: {
      // cron 表达式
      cronExp: {
        type: String,
        default: ''
      },
      // 是否立即运行
      isTestRun: {
        type: Boolean,
        default: false
      },
      // 运行的次数
      times: {
        type: Number,
        default: 5
      }
    },
    data() {
      return {
        rs: [],
        testRunCronEx: {}
      }
    },
    created() {
      if (this.isTestRun) {
        this.testRun();
      }
    },
    methods: {
      testRun() {
        if (this.cronExp !== '') {
          this.testRunCronEx.times = this.times;
          this.testRunCronEx.cron = this.cronExp;
          TestRunCron(this.testRunCronEx).then(res => {
            this.rs = res.resData;
          });
        }
      }
    }
  }
</script>

注意此处引入的

import {TestRunCron} from "../../../api/job/jobMag";

这个是请求后台方法,用于生成最近5次运行的时间,需要两个参数(cron表达和运行的次数times)。以下是关键代码

CronExpression ce = new CronExpression(cron);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = new Date();
for (int i = 0; i < times; i++) {
    d = ce.getNextValidTimeAfter(d);
    if (d != null) {
        rs.add(format.format(d));
    } else {
        break;
    }
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式: Seconds Minutes Hours DayofMonth Month DayofWeek Year或 Seconds Minutes Hours DayofMonth Month DayofWeek 每一个域可出现的字符如下: Seconds:可出现", - * /"四个字符,有效范围为0-59的整数 Minutes:可出现", - * /"四个字符,有效范围为0-59的整数 Hours:可出现", - * /"四个字符,有效范围为0-23的整数 DayofMonth:可出现", - * / ? L W C"八个字符,有效范围为0-31的整数 Month:可出现", - * /"四个字符,有效范围为1-12的整数或JAN-DEc DayofWeek:可出现", - * / ? L C #"八个字符,有效范围为1-7的整数或SUN-SAT两个范围。1表示星期天,2表示星期一, 依次类推 Year:可出现", - * /"四个字符,有效范围为1970-2099年 每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是: (1)*:表示匹配该域的任意值,假如在Minutes域使用*, 即表示每分钟都会触发事件。 (2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。 (3)-:表示范围,例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次 (4)/:表示起始时间开始触发,然后每隔固定时间触发一次,例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次. (5),:表示列出枚举值值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。 (6)L:表示最后,只能出现在DayofWeek和DayofMonth域,如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。 (7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 (8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。 (9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。 举几个例子: 0 0 2 1 * ? * 表示在每月的1日的凌晨2点调度任务 0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业 0 15 10 ? 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作 0 0 10,14,16 * * ? 每天上午10点,下午2点,4点 0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时 0 0 12 ? * WED 表示每个星期三中午12点 "0 0 12 * * ?" 每天中午12点触发 "0 15 10 ? * *" 每天上午10:15触发 "0 15 10 * * ?" 每天上午10:15触发 "0 15 10 * * ? *" 每天上午10:15触发 "0 15 10 * * ? 2005" 2005年的每天上午10:15触发 "0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发 "0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发 "0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 "0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发 "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发 "0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发 "0 15 10 15 * ?" 每月15日上午10:15触发 "0 15 10 L * ?" 每月最后一日的上午10:15触发 "0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 "0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发 "0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发
cron表达式是用于定义定时任务调度的一种时间表达式。在Vue中,可以使用vue-quartz插件来实现定时任务的调度。 首先,需要在项目中安装vue-quartz插件。可以通过npm或yarn进行安装: ``` npm install vue-quartz ``` 或 ``` yarn add vue-quartz ``` 安装完成后,在Vue的入口文件main.js中引入并注册vue-quartz插件: ```javascript import Vue from 'vue'; import VueQuartz from 'vue-quartz'; Vue.use(VueQuartz); ``` 接下来,在需要定义定时任务的组件中,使用`<cron>`标签来设置cron表达式: ```vue <template> <div> <h1>定时任务</h1> <cron v-model="cronExpression" @change="handleCronChange"></cron> </div> </template> <script> export default { data() { return { cronExpression: '' }; }, methods: { handleCronChange(cronExpression) { // 在这里可以处理cron表达式的变化,并执行相应的操作 console.log('cron表达式变化:', cronExpression); } } }; </script> ``` 在上面的示例中,通过`v-model`指令将cron表达式绑定到组件的data属性`cronExpression`上,并通过`@change`事件监听cron表达式的变化。 当用户在页面上选择或输入cron表达式时,`handleCronChange`方法会被调用,并入新的cron表达式。在该方法中可以根据cron表达式执行相应的定时任务逻辑。 请注意,以上只是一个简单的示例,具体的定时任务逻辑需要根据实际需求进行实现。同时,需要了解cron表达式的语法规则和含义,以确保正确设置定时任务的执行时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值