作者 RuoYi

定时任务支持在线生成cron表达式

@@ -60,10 +60,17 @@ @@ -60,10 +60,17 @@
60 color: inherit; 60 color: inherit;
61 } 61 }
62 62
63 -.el-dialog:not(.is-fullscreen){ 63 +.el-dialog:not(.is-fullscreen) {
64 margin-top: 6vh !important; 64 margin-top: 6vh !important;
65 } 65 }
66 66
  67 +.el-dialog .el-dialog__body {
  68 + overflow: auto;
  69 + overflow-x: hidden;
  70 + max-height: 70vh;
  71 + padding: 10px 20px 0;
  72 +}
  73 +
67 .el-table { 74 .el-table {
68 .el-table__header-wrapper, .el-table__fixed-header-wrapper { 75 .el-table__header-wrapper, .el-table__fixed-header-wrapper {
69 th { 76 th {
  1 +<template>
  2 + <el-form size="small">
  3 + <el-form-item>
  4 + <el-radio v-model='radioValue' :label="1">
  5 + 日,允许的通配符[, - * / L M]
  6 + </el-radio>
  7 + </el-form-item>
  8 +
  9 + <el-form-item>
  10 + <el-radio v-model='radioValue' :label="2">
  11 + 不指定
  12 + </el-radio>
  13 + </el-form-item>
  14 +
  15 + <el-form-item>
  16 + <el-radio v-model='radioValue' :label="3">
  17 + 周期从
  18 + <el-input-number v-model='cycle01' :min="0" :max="31" /> -
  19 + <el-input-number v-model='cycle02' :min="0" :max="31" /> 日
  20 + </el-radio>
  21 + </el-form-item>
  22 +
  23 + <el-form-item>
  24 + <el-radio v-model='radioValue' :label="4">
  25 +
  26 + <el-input-number v-model='average01' :min="0" :max="31" /> 号开始,每
  27 + <el-input-number v-model='average02' :min="0" :max="31" /> 日执行一次
  28 + </el-radio>
  29 + </el-form-item>
  30 +
  31 + <el-form-item>
  32 + <el-radio v-model='radioValue' :label="5">
  33 + 每月
  34 + <el-input-number v-model='workday' :min="0" :max="31" /> 号最近的那个工作日
  35 + </el-radio>
  36 + </el-form-item>
  37 +
  38 + <el-form-item>
  39 + <el-radio v-model='radioValue' :label="6">
  40 + 本月最后一天
  41 + </el-radio>
  42 + </el-form-item>
  43 +
  44 + <el-form-item>
  45 + <el-radio v-model='radioValue' :label="7">
  46 + 指定
  47 + <el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
  48 + <el-option v-for="item in 31" :key="item" :value="item">{{item}}</el-option>
  49 + </el-select>
  50 + </el-radio>
  51 + </el-form-item>
  52 + </el-form>
  53 +</template>
  54 +
  55 +<script>
  56 +export default {
  57 + data() {
  58 + return {
  59 + radioValue: 1,
  60 + workday: 1,
  61 + cycle01: 1,
  62 + cycle02: 2,
  63 + average01: 1,
  64 + average02: 1,
  65 + checkboxList: [],
  66 + checkNum: this.$options.propsData.check
  67 + }
  68 + },
  69 + name: 'crontab-day',
  70 + props: ['check', 'cron'],
  71 + methods: {
  72 + // 单选按钮值变化时
  73 + radioChange() {
  74 + ('day rachange');
  75 + if (this.radioValue === 1) {
  76 + this.$emit('update', 'day', '*', 'day');
  77 + this.$emit('update', 'week', '?', 'day');
  78 + this.$emit('update', 'mouth', '*', 'day');
  79 + } else {
  80 + if (this.cron.hour === '*') {
  81 + this.$emit('update', 'hour', '0', 'day');
  82 + }
  83 + if (this.cron.min === '*') {
  84 + this.$emit('update', 'min', '0', 'day');
  85 + }
  86 + if (this.cron.second === '*') {
  87 + this.$emit('update', 'second', '0', 'day');
  88 + }
  89 + }
  90 +
  91 + switch (this.radioValue) {
  92 + case 2:
  93 + this.$emit('update', 'day', '?');
  94 + break;
  95 + case 3:
  96 + this.$emit('update', 'day', this.cycle01 + '-' + this.cycle02);
  97 + break;
  98 + case 4:
  99 + this.$emit('update', 'day', this.average01 + '/' + this.average02);
  100 + break;
  101 + case 5:
  102 + this.$emit('update', 'day', this.workday + 'W');
  103 + break;
  104 + case 6:
  105 + this.$emit('update', 'day', 'L');
  106 + break;
  107 + case 7:
  108 + this.$emit('update', 'day', this.checkboxString);
  109 + break;
  110 + }
  111 + ('day rachange end');
  112 + },
  113 + // 周期两个值变化时
  114 + cycleChange() {
  115 + if (this.radioValue == '3') {
  116 + this.$emit('update', 'day', this.cycleTotal);
  117 + }
  118 + },
  119 + // 平均两个值变化时
  120 + averageChange() {
  121 + if (this.radioValue == '4') {
  122 + this.$emit('update', 'day', this.averageTotal);
  123 + }
  124 + },
  125 + // 最近工作日值变化时
  126 + workdayChange() {
  127 + if (this.radioValue == '5') {
  128 + this.$emit('update', 'day', this.workday + 'W');
  129 + }
  130 + },
  131 + // checkbox值变化时
  132 + checkboxChange() {
  133 + if (this.radioValue == '7') {
  134 + this.$emit('update', 'day', this.checkboxString);
  135 + }
  136 + },
  137 + // 父组件传递的week发生变化触发
  138 + weekChange() {
  139 + //判断week值与day不能同时为“?”
  140 + if (this.cron.week == '?' && this.radioValue == '2') {
  141 + this.radioValue = '1';
  142 + } else if (this.cron.week !== '?' && this.radioValue != '2') {
  143 + this.radioValue = '2';
  144 + }
  145 + },
  146 + },
  147 + watch: {
  148 + "radioValue": "radioChange",
  149 + 'cycleTotal': 'cycleChange',
  150 + 'averageTotal': 'averageChange',
  151 + 'workdayCheck': 'workdayChange',
  152 + 'checkboxString': 'checkboxChange',
  153 + },
  154 + computed: {
  155 + // 计算两个周期值
  156 + cycleTotal: function () {
  157 + this.cycle01 = this.checkNum(this.cycle01, 1, 31)
  158 + this.cycle02 = this.checkNum(this.cycle02, 1, 31)
  159 + return this.cycle01 + '-' + this.cycle02;
  160 + },
  161 + // 计算平均用到的值
  162 + averageTotal: function () {
  163 + this.average01 = this.checkNum(this.average01, 1, 31)
  164 + this.average02 = this.checkNum(this.average02, 1, 31)
  165 + return this.average01 + '/' + this.average02;
  166 + },
  167 + // 计算工作日格式
  168 + workdayCheck: function () {
  169 + this.workday = this.checkNum(this.workday, 1, 31)
  170 + return this.workday;
  171 + },
  172 + // 计算勾选的checkbox值合集
  173 + checkboxString: function () {
  174 + let str = this.checkboxList.join();
  175 + return str == '' ? '*' : str;
  176 + }
  177 + }
  178 +}
  179 +</script>
  1 +<template>
  2 + <el-form size="small">
  3 + <el-form-item>
  4 + <el-radio v-model='radioValue' :label="1">
  5 + 小时,允许的通配符[, - * /]
  6 + </el-radio>
  7 + </el-form-item>
  8 +
  9 + <el-form-item>
  10 + <el-radio v-model='radioValue' :label="2">
  11 + 周期从
  12 + <el-input-number v-model='cycle01' :min="0" :max="60" /> -
  13 + <el-input-number v-model='cycle02' :min="0" :max="60" /> 小时
  14 + </el-radio>
  15 + </el-form-item>
  16 +
  17 + <el-form-item>
  18 + <el-radio v-model='radioValue' :label="3">
  19 +
  20 + <el-input-number v-model='average01' :min="0" :max="60" /> 小时开始,每
  21 + <el-input-number v-model='average02' :min="0" :max="60" /> 小时执行一次
  22 + </el-radio>
  23 + </el-form-item>
  24 +
  25 + <el-form-item>
  26 + <el-radio v-model='radioValue' :label="4">
  27 + 指定
  28 + <el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
  29 + <el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
  30 + </el-select>
  31 + </el-radio>
  32 + </el-form-item>
  33 + </el-form>
  34 +</template>
  35 +
  36 +<script>
  37 +export default {
  38 + data() {
  39 + return {
  40 + radioValue: 1,
  41 + cycle01: 0,
  42 + cycle02: 1,
  43 + average01: 0,
  44 + average02: 1,
  45 + checkboxList: [],
  46 + checkNum: this.$options.propsData.check
  47 + }
  48 + },
  49 + name: 'crontab-hour',
  50 + props: ['check', 'cron'],
  51 + methods: {
  52 + // 单选按钮值变化时
  53 + radioChange() {
  54 + if (this.radioValue === 1) {
  55 + this.$emit('update', 'hour', '*', 'hour');
  56 + this.$emit('update', 'day', '*', 'hour');
  57 + } else {
  58 + if (this.cron.min === '*') {
  59 + this.$emit('update', 'min', '0', 'hour');
  60 + }
  61 + if (this.cron.second === '*') {
  62 + this.$emit('update', 'second', '0', 'hour');
  63 + }
  64 + }
  65 + switch (this.radioValue) {
  66 + case 2:
  67 + this.$emit('update', 'hour', this.cycle01 + '-' + this.cycle02);
  68 + break;
  69 + case 3:
  70 + this.$emit('update', 'hour', this.average01 + '/' + this.average02);
  71 + break;
  72 + case 4:
  73 + this.$emit('update', 'hour', this.checkboxString);
  74 + break;
  75 + }
  76 + },
  77 + // 周期两个值变化时
  78 + cycleChange() {
  79 + if (this.radioValue == '2') {
  80 + this.$emit('update', 'hour', this.cycleTotal);
  81 + }
  82 + },
  83 + // 平均两个值变化时
  84 + averageChange() {
  85 + if (this.radioValue == '3') {
  86 + this.$emit('update', 'hour', this.averageTotal);
  87 + }
  88 + },
  89 + // checkbox值变化时
  90 + checkboxChange() {
  91 + if (this.radioValue == '4') {
  92 + this.$emit('update', 'hour', this.checkboxString);
  93 + }
  94 + }
  95 + },
  96 + watch: {
  97 + "radioValue": "radioChange",
  98 + 'cycleTotal': 'cycleChange',
  99 + 'averageTotal': 'averageChange',
  100 + 'checkboxString': 'checkboxChange'
  101 + },
  102 + computed: {
  103 + // 计算两个周期值
  104 + cycleTotal: function () {
  105 + this.cycle01 = this.checkNum(this.cycle01, 0, 23)
  106 + this.cycle02 = this.checkNum(this.cycle02, 0, 23)
  107 + return this.cycle01 + '-' + this.cycle02;
  108 + },
  109 + // 计算平均用到的值
  110 + averageTotal: function () {
  111 + this.average01 = this.checkNum(this.average01, 0, 23)
  112 + this.average02 = this.checkNum(this.average02, 1, 23)
  113 + return this.average01 + '/' + this.average02;
  114 + },
  115 + // 计算勾选的checkbox值合集
  116 + checkboxString: function () {
  117 + let str = this.checkboxList.join();
  118 + return str == '' ? '*' : str;
  119 + }
  120 + }
  121 +}
  122 +</script>
  1 +<template>
  2 + <div>
  3 + <el-tabs type="border-card">
  4 + <el-tab-pane label="秒" v-if="shouldHide('second')">
  5 + <CrontabSecond @update="updateContabValue" :check="checkNumber" ref="cronsecond" />
  6 + </el-tab-pane>
  7 +
  8 + <el-tab-pane label="分钟" v-if="shouldHide('min')">
  9 + <CrontabMin
  10 + @update="updateContabValue"
  11 + :check="checkNumber"
  12 + :cron="contabValueObj"
  13 + ref="cronmin"
  14 + />
  15 + </el-tab-pane>
  16 +
  17 + <el-tab-pane label="小时" v-if="shouldHide('hour')">
  18 + <CrontabHour
  19 + @update="updateContabValue"
  20 + :check="checkNumber"
  21 + :cron="contabValueObj"
  22 + ref="cronhour"
  23 + />
  24 + </el-tab-pane>
  25 +
  26 + <el-tab-pane label="日" v-if="shouldHide('day')">
  27 + <CrontabDay
  28 + @update="updateContabValue"
  29 + :check="checkNumber"
  30 + :cron="contabValueObj"
  31 + ref="cronday"
  32 + />
  33 + </el-tab-pane>
  34 +
  35 + <el-tab-pane label="月" v-if="shouldHide('mouth')">
  36 + <CrontabMouth
  37 + @update="updateContabValue"
  38 + :check="checkNumber"
  39 + :cron="contabValueObj"
  40 + ref="cronmouth"
  41 + />
  42 + </el-tab-pane>
  43 +
  44 + <el-tab-pane label="周" v-if="shouldHide('week')">
  45 + <CrontabWeek
  46 + @update="updateContabValue"
  47 + :check="checkNumber"
  48 + :cron="contabValueObj"
  49 + ref="cronweek"
  50 + />
  51 + </el-tab-pane>
  52 +
  53 + <el-tab-pane label="年" v-if="shouldHide('year')">
  54 + <CrontabYear
  55 + @update="updateContabValue"
  56 + :check="checkNumber"
  57 + :cron="contabValueObj"
  58 + ref="cronyear"
  59 + />
  60 + </el-tab-pane>
  61 + </el-tabs>
  62 +
  63 + <div class="popup-main">
  64 + <div class="popup-result">
  65 + <p class="title">时间表达式</p>
  66 + <table>
  67 + <thead>
  68 + <th v-for="item of tabTitles" width="40" :key="item">{{item}}</th>
  69 + <th>Cron 表达式</th>
  70 + </thead>
  71 + <tbody>
  72 + <td>
  73 + <span>{{contabValueObj.second}}</span>
  74 + </td>
  75 + <td>
  76 + <span>{{contabValueObj.min}}</span>
  77 + </td>
  78 + <td>
  79 + <span>{{contabValueObj.hour}}</span>
  80 + </td>
  81 + <td>
  82 + <span>{{contabValueObj.day}}</span>
  83 + </td>
  84 + <td>
  85 + <span>{{contabValueObj.mouth}}</span>
  86 + </td>
  87 + <td>
  88 + <span>{{contabValueObj.week}}</span>
  89 + </td>
  90 + <td>
  91 + <span>{{contabValueObj.year}}</span>
  92 + </td>
  93 + <td>
  94 + <span>{{contabValueString}}</span>
  95 + </td>
  96 + </tbody>
  97 + </table>
  98 + </div>
  99 + <CrontabResult :ex="contabValueString"></CrontabResult>
  100 +
  101 + <div class="pop_btn">
  102 + <el-button size="small" type="primary" @click="submitFill">确定</el-button>
  103 + <el-button size="small" type="warning" @click="clearCron">重置</el-button>
  104 + <el-button size="small" @click="hidePopup">取消</el-button>
  105 + </div>
  106 + </div>
  107 + </div>
  108 +</template>
  109 +
  110 +<script>
  111 +import CrontabSecond from "./second.vue";
  112 +import CrontabMin from "./min.vue";
  113 +import CrontabHour from "./hour.vue";
  114 +import CrontabDay from "./day.vue";
  115 +import CrontabMouth from "./mouth.vue";
  116 +import CrontabWeek from "./week.vue";
  117 +import CrontabYear from "./year.vue";
  118 +import CrontabResult from "./result.vue";
  119 +
  120 +export default {
  121 + data() {
  122 + return {
  123 + tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"],
  124 + tabActive: 0,
  125 + myindex: 0,
  126 + contabValueObj: {
  127 + second: "*",
  128 + min: "*",
  129 + hour: "*",
  130 + day: "*",
  131 + mouth: "*",
  132 + week: "?",
  133 + year: "",
  134 + },
  135 + };
  136 + },
  137 + name: "vcrontab",
  138 + props: ["expression", "hideComponent"],
  139 + methods: {
  140 + shouldHide(key) {
  141 + if (this.hideComponent && this.hideComponent.includes(key)) return false;
  142 + return true;
  143 + },
  144 + resolveExp() {
  145 + //反解析 表达式
  146 + if (this.expression) {
  147 + let arr = this.expression.split(" ");
  148 + if (arr.length >= 6) {
  149 + //6 位以上是合法表达式
  150 + let obj = {
  151 + second: arr[0],
  152 + min: arr[1],
  153 + hour: arr[2],
  154 + day: arr[3],
  155 + mouth: arr[4],
  156 + week: arr[5],
  157 + year: arr[6] ? arr[6] : "",
  158 + };
  159 + this.contabValueObj = {
  160 + ...obj,
  161 + };
  162 + for (let i in obj) {
  163 + if (obj[i]) this.changeRadio(i, obj[i]);
  164 + }
  165 + }
  166 + } else {
  167 + //没有传入的表达式 则还原
  168 + this.clearCron();
  169 + }
  170 + },
  171 + // tab切换值
  172 + tabCheck(index) {
  173 + this.tabActive = index;
  174 + },
  175 + // 由子组件触发,更改表达式组成的字段值
  176 + updateContabValue(name, value, from) {
  177 + "updateContabValue", name, value, from;
  178 + this.contabValueObj[name] = value;
  179 + if (from && from !== name) {
  180 + console.log(`来自组件 ${from} 改变了 ${name} ${value}`);
  181 + this.changeRadio(name, value);
  182 + }
  183 + },
  184 + //赋值到组件
  185 + changeRadio(name, value) {
  186 + let arr = ["second", "min", "hour", "mouth"],
  187 + refName = "cron" + name,
  188 + insVlaue;
  189 +
  190 + if (!this.$refs[refName]) return;
  191 +
  192 + if (arr.includes(name)) {
  193 + if (value === "*") {
  194 + insVlaue = 1;
  195 + } else if (value.indexOf("-") > -1) {
  196 + let indexArr = value.split("-");
  197 + isNaN(indexArr[0])
  198 + ? (this.$refs[refName].cycle01 = 0)
  199 + : (this.$refs[refName].cycle01 = indexArr[0]);
  200 + this.$refs[refName].cycle02 = indexArr[1];
  201 + insVlaue = 2;
  202 + } else if (value.indexOf("/") > -1) {
  203 + let indexArr = value.split("/");
  204 + isNaN(indexArr[0])
  205 + ? (this.$refs[refName].average01 = 0)
  206 + : (this.$refs[refName].average01 = indexArr[0]);
  207 + this.$refs[refName].average02 = indexArr[1];
  208 + insVlaue = 3;
  209 + } else {
  210 + insVlaue = 4;
  211 + this.$refs[refName].checkboxList = value.split(",");
  212 + }
  213 + } else if (name == "day") {
  214 + if (value === "*") {
  215 + insVlaue = 1;
  216 + } else if (value == "?") {
  217 + insVlaue = 2;
  218 + } else if (value.indexOf("-") > -1) {
  219 + let indexArr = value.split("-");
  220 + isNaN(indexArr[0])
  221 + ? (this.$refs[refName].cycle01 = 0)
  222 + : (this.$refs[refName].cycle01 = indexArr[0]);
  223 + this.$refs[refName].cycle02 = indexArr[1];
  224 + insVlaue = 3;
  225 + } else if (value.indexOf("/") > -1) {
  226 + let indexArr = value.split("/");
  227 + isNaN(indexArr[0])
  228 + ? (this.$refs[refName].average01 = 0)
  229 + : (this.$refs[refName].average01 = indexArr[0]);
  230 + this.$refs[refName].average02 = indexArr[1];
  231 + insVlaue = 4;
  232 + } else if (value.indexOf("W") > -1) {
  233 + let indexArr = value.split("W");
  234 + isNaN(indexArr[0])
  235 + ? (this.$refs[refName].workday = 0)
  236 + : (this.$refs[refName].workday = indexArr[0]);
  237 + insVlaue = 5;
  238 + } else if (value === "L") {
  239 + insVlaue = 6;
  240 + } else {
  241 + this.$refs[refName].checkboxList = value.split(",");
  242 + insVlaue = 7;
  243 + }
  244 + } else if (name == "week") {
  245 + if (value === "*") {
  246 + insVlaue = 1;
  247 + } else if (value == "?") {
  248 + insVlaue = 2;
  249 + } else if (value.indexOf("-") > -1) {
  250 + let indexArr = value.split("-");
  251 + isNaN(indexArr[0])
  252 + ? (this.$refs[refName].cycle01 = 0)
  253 + : (this.$refs[refName].cycle01 = indexArr[0]);
  254 + this.$refs[refName].cycle02 = indexArr[1];
  255 + insVlaue = 3;
  256 + } else if (value.indexOf("#") > -1) {
  257 + let indexArr = value.split("#");
  258 + isNaN(indexArr[0])
  259 + ? (this.$refs[refName].average01 = 1)
  260 + : (this.$refs[refName].average01 = indexArr[0]);
  261 + this.$refs[refName].average02 = indexArr[1];
  262 + insVlaue = 4;
  263 + } else if (value.indexOf("L") > -1) {
  264 + let indexArr = value.split("L");
  265 + isNaN(indexArr[0])
  266 + ? (this.$refs[refName].weekday = 1)
  267 + : (this.$refs[refName].weekday = indexArr[0]);
  268 + insVlaue = 5;
  269 + } else {
  270 + this.$refs[refName].checkboxList = value.split(",");
  271 + insVlaue = 7;
  272 + }
  273 + } else if (name == "year") {
  274 + if (value == "") {
  275 + insVlaue = 1;
  276 + } else if (value == "*") {
  277 + insVlaue = 2;
  278 + } else if (value.indexOf("-") > -1) {
  279 + insVlaue = 3;
  280 + } else if (value.indexOf("/") > -1) {
  281 + insVlaue = 4;
  282 + } else {
  283 + this.$refs[refName].checkboxList = value.split(",");
  284 + insVlaue = 5;
  285 + }
  286 + }
  287 + this.$refs[refName].radioValue = insVlaue;
  288 + },
  289 + // 表单选项的子组件校验数字格式(通过-props传递)
  290 + checkNumber(value, minLimit, maxLimit) {
  291 + //检查必须为整数
  292 + value = Math.floor(value);
  293 + if (value < minLimit) {
  294 + value = minLimit;
  295 + } else if (value > maxLimit) {
  296 + value = maxLimit;
  297 + }
  298 + return value;
  299 + },
  300 + // 隐藏弹窗
  301 + hidePopup() {
  302 + this.$emit("hide");
  303 + },
  304 + // 填充表达式
  305 + submitFill() {
  306 + this.$emit("fill", this.contabValueString);
  307 + this.hidePopup();
  308 + },
  309 + clearCron() {
  310 + // 还原选择项
  311 + ("准备还原");
  312 + this.contabValueObj = {
  313 + second: "*",
  314 + min: "*",
  315 + hour: "*",
  316 + day: "*",
  317 + mouth: "*",
  318 + week: "?",
  319 + year: "",
  320 + };
  321 + for (let j in this.contabValueObj) {
  322 + this.changeRadio(j, this.contabValueObj[j]);
  323 + }
  324 + },
  325 + },
  326 + computed: {
  327 + contabValueString: function() {
  328 + let obj = this.contabValueObj;
  329 + let str =
  330 + obj.second +
  331 + " " +
  332 + obj.min +
  333 + " " +
  334 + obj.hour +
  335 + " " +
  336 + obj.day +
  337 + " " +
  338 + obj.mouth +
  339 + " " +
  340 + obj.week +
  341 + (obj.year == "" ? "" : " " + obj.year);
  342 + return str;
  343 + },
  344 + },
  345 + components: {
  346 + CrontabSecond,
  347 + CrontabMin,
  348 + CrontabHour,
  349 + CrontabDay,
  350 + CrontabMouth,
  351 + CrontabWeek,
  352 + CrontabYear,
  353 + CrontabResult,
  354 + },
  355 + watch: {
  356 + expression: "resolveExp",
  357 + hideComponent(value) {
  358 + // 隐藏部分组件
  359 + },
  360 + },
  361 + mounted: function() {
  362 + this.resolveExp();
  363 + },
  364 +};
  365 +</script>
  366 +<style scoped>
  367 +.pop_btn {
  368 + text-align: center;
  369 + margin-top: 20px;
  370 +}
  371 +.popup-main {
  372 + position: relative;
  373 + margin: 10px auto;
  374 + background: #fff;
  375 + border-radius: 5px;
  376 + font-size: 12px;
  377 + overflow: hidden;
  378 +}
  379 +.popup-title {
  380 + overflow: hidden;
  381 + line-height: 34px;
  382 + padding-top: 6px;
  383 + background: #f2f2f2;
  384 +}
  385 +.popup-result {
  386 + box-sizing: border-box;
  387 + line-height: 24px;
  388 + margin: 25px auto;
  389 + padding: 15px 10px 10px;
  390 + border: 1px solid #ccc;
  391 + position: relative;
  392 +}
  393 +.popup-result .title {
  394 + position: absolute;
  395 + top: -28px;
  396 + left: 50%;
  397 + width: 140px;
  398 + font-size: 14px;
  399 + margin-left: -70px;
  400 + text-align: center;
  401 + line-height: 30px;
  402 + background: #fff;
  403 +}
  404 +.popup-result table {
  405 + text-align: center;
  406 + width: 100%;
  407 + margin: 0 auto;
  408 +}
  409 +.popup-result table span {
  410 + display: block;
  411 + width: 100%;
  412 + font-family: arial;
  413 + line-height: 30px;
  414 + height: 30px;
  415 + white-space: nowrap;
  416 + overflow: hidden;
  417 + border: 1px solid #e8e8e8;
  418 +}
  419 +.popup-result-scroll {
  420 + font-size: 12px;
  421 + line-height: 24px;
  422 + height: 10em;
  423 + overflow-y: auto;
  424 +}
  425 +</style>
  1 +<template>
  2 + <el-form size="small">
  3 + <el-form-item>
  4 + <el-radio v-model='radioValue' :label="1">
  5 + 分钟,允许的通配符[, - * /]
  6 + </el-radio>
  7 + </el-form-item>
  8 +
  9 + <el-form-item>
  10 + <el-radio v-model='radioValue' :label="2">
  11 + 周期从
  12 + <el-input-number v-model='cycle01' :min="0" :max="60" /> -
  13 + <el-input-number v-model='cycle02' :min="0" :max="60" /> 分钟
  14 + </el-radio>
  15 + </el-form-item>
  16 +
  17 + <el-form-item>
  18 + <el-radio v-model='radioValue' :label="3">
  19 +
  20 + <el-input-number v-model='average01' :min="0" :max="60" /> 分钟开始,每
  21 + <el-input-number v-model='average02' :min="0" :max="60" /> 分钟执行一次
  22 + </el-radio>
  23 + </el-form-item>
  24 +
  25 + <el-form-item>
  26 + <el-radio v-model='radioValue' :label="4">
  27 + 指定
  28 + <el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
  29 + <el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
  30 + </el-select>
  31 + </el-radio>
  32 + </el-form-item>
  33 + </el-form>
  34 +
  35 +</template>
  36 +
  37 +<script>
  38 +export default {
  39 + data() {
  40 + return {
  41 + radioValue: 1,
  42 + cycle01: 1,
  43 + cycle02: 2,
  44 + average01: 0,
  45 + average02: 1,
  46 + checkboxList: [],
  47 + checkNum: this.$options.propsData.check
  48 + }
  49 + },
  50 + name: 'crontab-min',
  51 + props: ['check', 'cron'],
  52 + methods: {
  53 + // 单选按钮值变化时
  54 + radioChange() {
  55 + if (this.radioValue !== 1 && this.cron.second === '*') {
  56 + this.$emit('update', 'second', '0', 'min');
  57 + }
  58 + switch (this.radioValue) {
  59 + case 1:
  60 + this.$emit('update', 'min', '*', 'min');
  61 + this.$emit('update', 'hour', '*', 'min');
  62 + break;
  63 + case 2:
  64 + this.$emit('update', 'min', this.cycle01 + '-' + this.cycle02, 'min');
  65 + break;
  66 + case 3:
  67 + this.$emit('update', 'min', this.average01 + '/' + this.average02, 'min');
  68 + break;
  69 + case 4:
  70 + this.$emit('update', 'min', this.checkboxString, 'min');
  71 + break;
  72 + }
  73 + },
  74 + // 周期两个值变化时
  75 + cycleChange() {
  76 + if (this.radioValue == '2') {
  77 + this.$emit('update', 'min', this.cycleTotal, 'min');
  78 + }
  79 + },
  80 + // 平均两个值变化时
  81 + averageChange() {
  82 + if (this.radioValue == '3') {
  83 + this.$emit('update', 'min', this.averageTotal, 'min');
  84 + }
  85 + },
  86 + // checkbox值变化时
  87 + checkboxChange() {
  88 + if (this.radioValue == '4') {
  89 + this.$emit('update', 'min', this.checkboxString, 'min');
  90 + }
  91 + },
  92 +
  93 + },
  94 + watch: {
  95 + "radioValue": "radioChange",
  96 + 'cycleTotal': 'cycleChange',
  97 + 'averageTotal': 'averageChange',
  98 + 'checkboxString': 'checkboxChange',
  99 + },
  100 + computed: {
  101 + // 计算两个周期值
  102 + cycleTotal: function () {
  103 + this.cycle01 = this.checkNum(this.cycle01, 0, 59)
  104 + this.cycle02 = this.checkNum(this.cycle02, 0, 59)
  105 + return this.cycle01 + '-' + this.cycle02;
  106 + },
  107 + // 计算平均用到的值
  108 + averageTotal: function () {
  109 + this.average01 = this.checkNum(this.average01, 0, 59)
  110 + this.average02 = this.checkNum(this.average02, 1, 59)
  111 + return this.average01 + '/' + this.average02;
  112 + },
  113 + // 计算勾选的checkbox值合集
  114 + checkboxString: function () {
  115 + let str = this.checkboxList.join();
  116 + return str == '' ? '*' : str;
  117 + }
  118 + }
  119 +}
  120 +</script>
  1 +<template>
  2 + <el-form size='small'>
  3 + <el-form-item>
  4 + <el-radio v-model='radioValue' :label="1">
  5 + 月,允许的通配符[, - * /]
  6 + </el-radio>
  7 + </el-form-item>
  8 +
  9 + <el-form-item>
  10 + <el-radio v-model='radioValue' :label="2">
  11 + 周期从
  12 + <el-input-number v-model='cycle01' :min="1" :max="12" /> -
  13 + <el-input-number v-model='cycle02' :min="1" :max="12" /> 月
  14 + </el-radio>
  15 + </el-form-item>
  16 +
  17 + <el-form-item>
  18 + <el-radio v-model='radioValue' :label="3">
  19 +
  20 + <el-input-number v-model='average01' :min="1" :max="12" /> 月开始,每
  21 + <el-input-number v-model='average02' :min="1" :max="12" /> 月月执行一次
  22 + </el-radio>
  23 + </el-form-item>
  24 +
  25 + <el-form-item>
  26 + <el-radio v-model='radioValue' :label="4">
  27 + 指定
  28 + <el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
  29 + <el-option v-for="item in 12" :key="item" :value="item">{{item}}</el-option>
  30 + </el-select>
  31 + </el-radio>
  32 + </el-form-item>
  33 + </el-form>
  34 +</template>
  35 +
  36 +<script>
  37 +export default {
  38 + data() {
  39 + return {
  40 + radioValue: 1,
  41 + cycle01: 1,
  42 + cycle02: 2,
  43 + average01: 1,
  44 + average02: 1,
  45 + checkboxList: [],
  46 + checkNum: this.check
  47 + }
  48 + },
  49 + name: 'crontab-mouth',
  50 + props: ['check', 'cron'],
  51 + methods: {
  52 + // 单选按钮值变化时
  53 + radioChange() {
  54 + if (this.radioValue === 1) {
  55 + this.$emit('update', 'mouth', '*');
  56 + this.$emit('update', 'year', '*');
  57 + } else {
  58 + if (this.cron.day === '*') {
  59 + this.$emit('update', 'day', '0', 'mouth');
  60 + }
  61 + if (this.cron.hour === '*') {
  62 + this.$emit('update', 'hour', '0', 'mouth');
  63 + }
  64 + if (this.cron.min === '*') {
  65 + this.$emit('update', 'min', '0', 'mouth');
  66 + }
  67 + if (this.cron.second === '*') {
  68 + this.$emit('update', 'second', '0', 'mouth');
  69 + }
  70 + }
  71 + switch (this.radioValue) {
  72 + case 2:
  73 + this.$emit('update', 'mouth', this.cycle01 + '-' + this.cycle02);
  74 + break;
  75 + case 3:
  76 + this.$emit('update', 'mouth', this.average01 + '/' + this.average02);
  77 + break;
  78 + case 4:
  79 + this.$emit('update', 'mouth', this.checkboxString);
  80 + break;
  81 + }
  82 + },
  83 + // 周期两个值变化时
  84 + cycleChange() {
  85 + if (this.radioValue == '2') {
  86 + this.$emit('update', 'mouth', this.cycleTotal);
  87 + }
  88 + },
  89 + // 平均两个值变化时
  90 + averageChange() {
  91 + if (this.radioValue == '3') {
  92 + this.$emit('update', 'mouth', this.averageTotal);
  93 + }
  94 + },
  95 + // checkbox值变化时
  96 + checkboxChange() {
  97 + if (this.radioValue == '4') {
  98 + this.$emit('update', 'mouth', this.checkboxString);
  99 + }
  100 + }
  101 + },
  102 + watch: {
  103 + "radioValue": "radioChange",
  104 + 'cycleTotal': 'cycleChange',
  105 + 'averageTotal': 'averageChange',
  106 + 'checkboxString': 'checkboxChange'
  107 + },
  108 + computed: {
  109 + // 计算两个周期值
  110 + cycleTotal: function () {
  111 + this.cycle01 = this.checkNum(this.cycle01, 1, 12)
  112 + this.cycle02 = this.checkNum(this.cycle02, 1, 12)
  113 + return this.cycle01 + '-' + this.cycle02;
  114 + },
  115 + // 计算平均用到的值
  116 + averageTotal: function () {
  117 + this.average01 = this.checkNum(this.average01, 1, 12)
  118 + this.average02 = this.checkNum(this.average02, 1, 12)
  119 + return this.average01 + '/' + this.average02;
  120 + },
  121 + // 计算勾选的checkbox值合集
  122 + checkboxString: function () {
  123 + let str = this.checkboxList.join();
  124 + return str == '' ? '*' : str;
  125 + }
  126 + }
  127 +}
  128 +</script>
  1 +<template>
  2 + <div class="popup-result">
  3 + <p class="title">最近5次运行时间</p>
  4 + <ul class="popup-result-scroll">
  5 + <template v-if='isShow'>
  6 + <li v-for='item in resultList' :key="item">{{item}}</li>
  7 + </template>
  8 + <li v-else>计算结果中...</li>
  9 + </ul>
  10 + </div>
  11 +</template>
  12 +
  13 +<script>
  14 +export default {
  15 + data() {
  16 + return {
  17 + dayRule: '',
  18 + dayRuleSup: '',
  19 + dateArr: [],
  20 + resultList: [],
  21 + isShow: false
  22 + }
  23 + },
  24 + name: 'crontab-result',
  25 + methods: {
  26 + // 表达式值变化时,开始去计算结果
  27 + expressionChange() {
  28 +
  29 + // 计算开始-隐藏结果
  30 + this.isShow = false;
  31 + // 获取规则数组[0秒、1分、2时、3日、4月、5星期、6年]
  32 + let ruleArr = this.$options.propsData.ex.split(' ');
  33 + // 用于记录进入循环的次数
  34 + let nums = 0;
  35 + // 用于暂时存符号时间规则结果的数组
  36 + let resultArr = [];
  37 + // 获取当前时间精确至[年、月、日、时、分、秒]
  38 + let nTime = new Date();
  39 + let nYear = nTime.getFullYear();
  40 + let nMouth = nTime.getMonth() + 1;
  41 + let nDay = nTime.getDate();
  42 + let nHour = nTime.getHours();
  43 + let nMin = nTime.getMinutes();
  44 + let nSecond = nTime.getSeconds();
  45 + // 根据规则获取到近100年可能年数组、月数组等等
  46 + this.getSecondArr(ruleArr[0]);
  47 + this.getMinArr(ruleArr[1]);
  48 + this.getHourArr(ruleArr[2]);
  49 + this.getDayArr(ruleArr[3]);
  50 + this.getMouthArr(ruleArr[4]);
  51 + this.getWeekArr(ruleArr[5]);
  52 + this.getYearArr(ruleArr[6], nYear);
  53 + // 将获取到的数组赋值-方便使用
  54 + let sDate = this.dateArr[0];
  55 + let mDate = this.dateArr[1];
  56 + let hDate = this.dateArr[2];
  57 + let DDate = this.dateArr[3];
  58 + let MDate = this.dateArr[4];
  59 + let YDate = this.dateArr[5];
  60 + // 获取当前时间在数组中的索引
  61 + let sIdx = this.getIndex(sDate, nSecond);
  62 + let mIdx = this.getIndex(mDate, nMin);
  63 + let hIdx = this.getIndex(hDate, nHour);
  64 + let DIdx = this.getIndex(DDate, nDay);
  65 + let MIdx = this.getIndex(MDate, nMouth);
  66 + let YIdx = this.getIndex(YDate, nYear);
  67 + // 重置月日时分秒的函数(后面用的比较多)
  68 + const resetSecond = function () {
  69 + sIdx = 0;
  70 + nSecond = sDate[sIdx]
  71 + }
  72 + const resetMin = function () {
  73 + mIdx = 0;
  74 + nMin = mDate[mIdx]
  75 + resetSecond();
  76 + }
  77 + const resetHour = function () {
  78 + hIdx = 0;
  79 + nHour = hDate[hIdx]
  80 + resetMin();
  81 + }
  82 + const resetDay = function () {
  83 + DIdx = 0;
  84 + nDay = DDate[DIdx]
  85 + resetHour();
  86 + }
  87 + const resetMouth = function () {
  88 + MIdx = 0;
  89 + nMouth = MDate[MIdx]
  90 + resetDay();
  91 + }
  92 + // 如果当前年份不为数组中当前值
  93 + if (nYear !== YDate[YIdx]) {
  94 + resetMouth();
  95 + }
  96 + // 如果当前月份不为数组中当前值
  97 + if (nMouth !== MDate[MIdx]) {
  98 + resetDay();
  99 + }
  100 + // 如果当前“日”不为数组中当前值
  101 + if (nDay !== DDate[DIdx]) {
  102 + resetHour();
  103 + }
  104 + // 如果当前“时”不为数组中当前值
  105 + if (nHour !== hDate[hIdx]) {
  106 + resetMin();
  107 + }
  108 + // 如果当前“分”不为数组中当前值
  109 + if (nMin !== mDate[mIdx]) {
  110 + resetSecond();
  111 + }
  112 +
  113 + // 循环年份数组
  114 + goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) {
  115 + let YY = YDate[Yi];
  116 + // 如果到达最大值时
  117 + if (nMouth > MDate[MDate.length - 1]) {
  118 + resetMouth();
  119 + continue;
  120 + }
  121 + // 循环月份数组
  122 + goMouth: for (let Mi = MIdx; Mi < MDate.length; Mi++) {
  123 + // 赋值、方便后面运算
  124 + let MM = MDate[Mi];
  125 + MM = MM < 10 ? '0' + MM : MM;
  126 + // 如果到达最大值时
  127 + if (nDay > DDate[DDate.length - 1]) {
  128 + resetDay();
  129 + if (Mi == MDate.length - 1) {
  130 + resetMouth();
  131 + continue goYear;
  132 + }
  133 + continue;
  134 + }
  135 + // 循环日期数组
  136 + goDay: for (let Di = DIdx; Di < DDate.length; Di++) {
  137 + // 赋值、方便后面运算
  138 + let DD = DDate[Di];
  139 + let thisDD = DD < 10 ? '0' + DD : DD;
  140 +
  141 + // 如果到达最大值时
  142 + if (nHour > hDate[hDate.length - 1]) {
  143 + resetHour();
  144 + if (Di == DDate.length - 1) {
  145 + resetDay();
  146 + if (Mi == MDate.length - 1) {
  147 + resetMouth();
  148 + continue goYear;
  149 + }
  150 + continue goMouth;
  151 + }
  152 + continue;
  153 + }
  154 +
  155 + // 判断日期的合法性,不合法的话也是跳出当前循环
  156 + if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true && this.dayRule !== 'workDay' && this.dayRule !== 'lastWeek' && this.dayRule !== 'lastDay') {
  157 + resetDay();
  158 + continue goMouth;
  159 + }
  160 + // 如果日期规则中有值时
  161 + if (this.dayRule == 'lastDay') {
  162 + //如果不是合法日期则需要将前将日期调到合法日期即月末最后一天
  163 +
  164 + if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  165 + while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  166 + DD--;
  167 +
  168 + thisDD = DD < 10 ? '0' + DD : DD;
  169 + }
  170 + }
  171 + } else if (this.dayRule == 'workDay') {
  172 + //校验并调整如果是2月30号这种日期传进来时需调整至正常月底
  173 + if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  174 + while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  175 + DD--;
  176 + thisDD = DD < 10 ? '0' + DD : DD;
  177 + }
  178 + }
  179 + // 获取达到条件的日期是星期X
  180 + let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
  181 + // 当星期日时
  182 + if (thisWeek == 0) {
  183 + //先找下一个日,并判断是否为月底
  184 + DD++;
  185 + thisDD = DD < 10 ? '0' + DD : DD;
  186 + //判断下一日已经不是合法日期
  187 + if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  188 + DD -= 3;
  189 + }
  190 + } else if (thisWeek == 6) {
  191 + //当星期6时只需判断不是1号就可进行操作
  192 + if (this.dayRuleSup !== 1) {
  193 + DD--;
  194 + } else {
  195 + DD += 2;
  196 + }
  197 + }
  198 + } else if (this.dayRule == 'weekDay') {
  199 + //如果指定了是星期几
  200 + //获取当前日期是属于星期几
  201 + let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
  202 + //校验当前星期是否在星期池(dayRuleSup)中
  203 + if (Array.indexOf(this.dayRuleSup, thisWeek) < 0) {
  204 + // 如果到达最大值时
  205 + if (Di == DDate.length - 1) {
  206 + resetDay();
  207 + if (Mi == MDate.length - 1) {
  208 + resetMouth();
  209 + continue goYear;
  210 + }
  211 + continue goMouth;
  212 + }
  213 + continue;
  214 + }
  215 + } else if (this.dayRule == 'assWeek') {
  216 + //如果指定了是第几周的星期几
  217 + //获取每月1号是属于星期几
  218 + let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
  219 + if (this.dayRuleSup[1] >= thisWeek) {
  220 + DD = (this.dayRuleSup[0] - 1) * 7 + this.dayRuleSup[1] - thisWeek + 1;
  221 + } else {
  222 + DD = this.dayRuleSup[0] * 7 + this.dayRuleSup[1] - thisWeek + 1;
  223 + }
  224 + } else if (this.dayRule == 'lastWeek') {
  225 + //如果指定了每月最后一个星期几
  226 + //校验并调整如果是2月30号这种日期传进来时需调整至正常月底
  227 + if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  228 + while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  229 + DD--;
  230 + thisDD = DD < 10 ? '0' + DD : DD;
  231 + }
  232 + }
  233 + //获取月末最后一天是星期几
  234 + let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
  235 + //找到要求中最近的那个星期几
  236 + if (this.dayRuleSup < thisWeek) {
  237 + DD -= thisWeek - this.dayRuleSup;
  238 + } else if (this.dayRuleSup > thisWeek) {
  239 + DD -= 7 - (this.dayRuleSup - thisWeek)
  240 + }
  241 + }
  242 + // 判断时间值是否小于10置换成“05”这种格式
  243 + DD = DD < 10 ? '0' + DD : DD;
  244 +
  245 + // 循环“时”数组
  246 + goHour: for (let hi = hIdx; hi < hDate.length; hi++) {
  247 + let hh = hDate[hi] < 10 ? '0' + hDate[hi] : hDate[hi]
  248 +
  249 + // 如果到达最大值时
  250 + if (nMin > mDate[mDate.length - 1]) {
  251 + resetMin();
  252 + if (hi == hDate.length - 1) {
  253 + resetHour();
  254 + if (Di == DDate.length - 1) {
  255 + resetDay();
  256 + if (Mi == MDate.length - 1) {
  257 + resetMouth();
  258 + continue goYear;
  259 + }
  260 + continue goMouth;
  261 + }
  262 + continue goDay;
  263 + }
  264 + continue;
  265 + }
  266 + // 循环"分"数组
  267 + goMin: for (let mi = mIdx; mi < mDate.length; mi++) {
  268 + let mm = mDate[mi] < 10 ? '0' + mDate[mi] : mDate[mi];
  269 +
  270 + // 如果到达最大值时
  271 + if (nSecond > sDate[sDate.length - 1]) {
  272 + resetSecond();
  273 + if (mi == mDate.length - 1) {
  274 + resetMin();
  275 + if (hi == hDate.length - 1) {
  276 + resetHour();
  277 + if (Di == DDate.length - 1) {
  278 + resetDay();
  279 + if (Mi == MDate.length - 1) {
  280 + resetMouth();
  281 + continue goYear;
  282 + }
  283 + continue goMouth;
  284 + }
  285 + continue goDay;
  286 + }
  287 + continue goHour;
  288 + }
  289 + continue;
  290 + }
  291 + // 循环"秒"数组
  292 + goSecond: for (let si = sIdx; si <= sDate.length - 1; si++) {
  293 + let ss = sDate[si] < 10 ? '0' + sDate[si] : sDate[si];
  294 + // 添加当前时间(时间合法性在日期循环时已经判断)
  295 + if (MM !== '00' && DD !== '00') {
  296 + resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss)
  297 + nums++;
  298 + }
  299 + //如果条数满了就退出循环
  300 + if (nums == 5) break goYear;
  301 + //如果到达最大值时
  302 + if (si == sDate.length - 1) {
  303 + resetSecond();
  304 + if (mi == mDate.length - 1) {
  305 + resetMin();
  306 + if (hi == hDate.length - 1) {
  307 + resetHour();
  308 + if (Di == DDate.length - 1) {
  309 + resetDay();
  310 + if (Mi == MDate.length - 1) {
  311 + resetMouth();
  312 + continue goYear;
  313 + }
  314 + continue goMouth;
  315 + }
  316 + continue goDay;
  317 + }
  318 + continue goHour;
  319 + }
  320 + continue goMin;
  321 + }
  322 + } //goSecond
  323 + } //goMin
  324 + }//goHour
  325 + }//goDay
  326 + }//goMouth
  327 + }
  328 + // 判断100年内的结果条数
  329 + if (resultArr.length == 0) {
  330 + this.resultList = ['没有达到条件的结果!'];
  331 + } else {
  332 + this.resultList = resultArr;
  333 + if (resultArr.length !== 5) {
  334 + this.resultList.push('最近100年内只有上面' + resultArr.length + '条结果!')
  335 + }
  336 + }
  337 + // 计算完成-显示结果
  338 + this.isShow = true;
  339 +
  340 +
  341 + },
  342 + //用于计算某位数字在数组中的索引
  343 + getIndex(arr, value) {
  344 + if (value <= arr[0] || value > arr[arr.length - 1]) {
  345 + return 0;
  346 + } else {
  347 + for (let i = 0; i < arr.length - 1; i++) {
  348 + if (value > arr[i] && value <= arr[i + 1]) {
  349 + return i + 1;
  350 + }
  351 + }
  352 + }
  353 + },
  354 + // 获取"年"数组
  355 + getYearArr(rule, year) {
  356 + this.dateArr[5] = this.getOrderArr(year, year + 100);
  357 + if (rule !== undefined) {
  358 + if (rule.indexOf('-') >= 0) {
  359 + this.dateArr[5] = this.getCycleArr(rule, year + 100, false)
  360 + } else if (rule.indexOf('/') >= 0) {
  361 + this.dateArr[5] = this.getAverageArr(rule, year + 100)
  362 + } else if (rule !== '*') {
  363 + this.dateArr[5] = this.getAssignArr(rule)
  364 + }
  365 + }
  366 + },
  367 + // 获取"月"数组
  368 + getMouthArr(rule) {
  369 + this.dateArr[4] = this.getOrderArr(1, 12);
  370 + if (rule.indexOf('-') >= 0) {
  371 + this.dateArr[4] = this.getCycleArr(rule, 12, false)
  372 + } else if (rule.indexOf('/') >= 0) {
  373 + this.dateArr[4] = this.getAverageArr(rule, 12)
  374 + } else if (rule !== '*') {
  375 + this.dateArr[4] = this.getAssignArr(rule)
  376 + }
  377 + },
  378 + // 获取"日"数组-主要为日期规则
  379 + getWeekArr(rule) {
  380 + //只有当日期规则的两个值均为“”时则表达日期是有选项的
  381 + if (this.dayRule == '' && this.dayRuleSup == '') {
  382 + if (rule.indexOf('-') >= 0) {
  383 + this.dayRule = 'weekDay';
  384 + this.dayRuleSup = this.getCycleArr(rule, 7, false)
  385 + } else if (rule.indexOf('#') >= 0) {
  386 + this.dayRule = 'assWeek';
  387 + let matchRule = rule.match(/[0-9]{1}/g);
  388 + this.dayRuleSup = [Number(matchRule[0]), Number(matchRule[1])];
  389 + this.dateArr[3] = [1];
  390 + if (this.dayRuleSup[1] == 7) {
  391 + this.dayRuleSup[1] = 0;
  392 + }
  393 + } else if (rule.indexOf('L') >= 0) {
  394 + this.dayRule = 'lastWeek';
  395 + this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]);
  396 + this.dateArr[3] = [31];
  397 + if (this.dayRuleSup == 7) {
  398 + this.dayRuleSup = 0;
  399 + }
  400 + } else if (rule !== '*' && rule !== '?') {
  401 + this.dayRule = 'weekDay';
  402 + this.dayRuleSup = this.getAssignArr(rule)
  403 + }
  404 + //如果weekDay时将7调整为0【week值0即是星期日】
  405 + if (this.dayRule == 'weekDay') {
  406 + for (let i = 0; i < this.dayRuleSup.length; i++) {
  407 + if (this.dayRuleSup[i] == 7) {
  408 + this.dayRuleSup[i] = 0;
  409 + }
  410 + }
  411 + }
  412 + }
  413 + },
  414 + // 获取"日"数组-少量为日期规则
  415 + getDayArr(rule) {
  416 + this.dateArr[3] = this.getOrderArr(1, 31);
  417 + this.dayRule = '';
  418 + this.dayRuleSup = '';
  419 + if (rule.indexOf('-') >= 0) {
  420 + this.dateArr[3] = this.getCycleArr(rule, 31, false)
  421 + this.dayRuleSup = 'null';
  422 + } else if (rule.indexOf('/') >= 0) {
  423 + this.dateArr[3] = this.getAverageArr(rule, 31)
  424 + this.dayRuleSup = 'null';
  425 + } else if (rule.indexOf('W') >= 0) {
  426 + this.dayRule = 'workDay';
  427 + this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]);
  428 + this.dateArr[3] = [this.dayRuleSup];
  429 + } else if (rule.indexOf('L') >= 0) {
  430 + this.dayRule = 'lastDay';
  431 + this.dayRuleSup = 'null';
  432 + this.dateArr[3] = [31];
  433 + } else if (rule !== '*' && rule !== '?') {
  434 + this.dateArr[3] = this.getAssignArr(rule)
  435 + this.dayRuleSup = 'null';
  436 + } else if (rule == '*') {
  437 + this.dayRuleSup = 'null';
  438 + }
  439 + },
  440 + // 获取"时"数组
  441 + getHourArr(rule) {
  442 + this.dateArr[2] = this.getOrderArr(0, 23);
  443 + if (rule.indexOf('-') >= 0) {
  444 + this.dateArr[2] = this.getCycleArr(rule, 24, true)
  445 + } else if (rule.indexOf('/') >= 0) {
  446 + this.dateArr[2] = this.getAverageArr(rule, 23)
  447 + } else if (rule !== '*') {
  448 + this.dateArr[2] = this.getAssignArr(rule)
  449 + }
  450 + },
  451 + // 获取"分"数组
  452 + getMinArr(rule) {
  453 + this.dateArr[1] = this.getOrderArr(0, 59);
  454 + if (rule.indexOf('-') >= 0) {
  455 + this.dateArr[1] = this.getCycleArr(rule, 60, true)
  456 + } else if (rule.indexOf('/') >= 0) {
  457 + this.dateArr[1] = this.getAverageArr(rule, 59)
  458 + } else if (rule !== '*') {
  459 + this.dateArr[1] = this.getAssignArr(rule)
  460 + }
  461 + },
  462 + // 获取"秒"数组
  463 + getSecondArr(rule) {
  464 + this.dateArr[0] = this.getOrderArr(0, 59);
  465 + if (rule.indexOf('-') >= 0) {
  466 + this.dateArr[0] = this.getCycleArr(rule, 60, true)
  467 + } else if (rule.indexOf('/') >= 0) {
  468 + this.dateArr[0] = this.getAverageArr(rule, 59)
  469 + } else if (rule !== '*') {
  470 + this.dateArr[0] = this.getAssignArr(rule)
  471 + }
  472 + },
  473 + // 根据传进来的min-max返回一个顺序的数组
  474 + getOrderArr(min, max) {
  475 + let arr = [];
  476 + for (let i = min; i <= max; i++) {
  477 + arr.push(i);
  478 + }
  479 + return arr;
  480 + },
  481 + // 根据规则中指定的零散值返回一个数组
  482 + getAssignArr(rule) {
  483 + let arr = [];
  484 + let assiginArr = rule.split(',');
  485 + for (let i = 0; i < assiginArr.length; i++) {
  486 + arr[i] = Number(assiginArr[i])
  487 + }
  488 + arr.sort(this.compare)
  489 + return arr;
  490 + },
  491 + // 根据一定算术规则计算返回一个数组
  492 + getAverageArr(rule, limit) {
  493 + let arr = [];
  494 + let agArr = rule.split('/');
  495 + let min = Number(agArr[0]);
  496 + let step = Number(agArr[1]);
  497 + while (min <= limit) {
  498 + arr.push(min);
  499 + min += step;
  500 + }
  501 + return arr;
  502 + },
  503 + // 根据规则返回一个具有周期性的数组
  504 + getCycleArr(rule, limit, status) {
  505 + //status--表示是否从0开始(则从1开始)
  506 + let arr = [];
  507 + let cycleArr = rule.split('-');
  508 + let min = Number(cycleArr[0]);
  509 + let max = Number(cycleArr[1]);
  510 + if (min > max) {
  511 + max += limit;
  512 + }
  513 + for (let i = min; i <= max; i++) {
  514 + let add = 0;
  515 + if (status == false && i % limit == 0) {
  516 + add = limit;
  517 + }
  518 + arr.push(Math.round(i % limit + add))
  519 + }
  520 + arr.sort(this.compare)
  521 + return arr;
  522 + },
  523 + //比较数字大小(用于Array.sort)
  524 + compare(value1, value2) {
  525 + if (value2 - value1 > 0) {
  526 + return -1;
  527 + } else {
  528 + return 1;
  529 + }
  530 + },
  531 + // 格式化日期格式如:2017-9-19 18:04:33
  532 + formatDate(value, type) {
  533 + // 计算日期相关值
  534 + let time = typeof value == 'number' ? new Date(value) : value;
  535 + let Y = time.getFullYear();
  536 + let M = time.getMonth() + 1;
  537 + let D = time.getDate();
  538 + let h = time.getHours();
  539 + let m = time.getMinutes();
  540 + let s = time.getSeconds();
  541 + let week = time.getDay();
  542 + // 如果传递了type的话
  543 + if (type == undefined) {
  544 + return Y + '-' + (M < 10 ? '0' + M : M) + '-' + (D < 10 ? '0' + D : D) + ' ' + (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
  545 + } else if (type == 'week') {
  546 + return week;
  547 + }
  548 + },
  549 + // 检查日期是否存在
  550 + checkDate(value) {
  551 + let time = new Date(value);
  552 + let format = this.formatDate(time)
  553 + return value == format ? true : false;
  554 + }
  555 + },
  556 + watch: {
  557 + 'ex': 'expressionChange'
  558 + },
  559 + props: ['ex'],
  560 + mounted: function () {
  561 + // 初始化 获取一次结果
  562 + this.expressionChange();
  563 + }
  564 +}
  565 +
  566 +</script>
  1 +<template>
  2 + <el-form size="small">
  3 + <el-form-item>
  4 + <el-radio v-model='radioValue' :label="1">
  5 + 秒,允许的通配符[, - * /]
  6 + </el-radio>
  7 + </el-form-item>
  8 +
  9 + <el-form-item>
  10 + <el-radio v-model='radioValue' :label="2">
  11 + 周期从
  12 + <el-input-number v-model='cycle01' :min="0" :max="60" /> -
  13 + <el-input-number v-model='cycle02' :min="0" :max="60" /> 秒
  14 + </el-radio>
  15 + </el-form-item>
  16 +
  17 + <el-form-item>
  18 + <el-radio v-model='radioValue' :label="3">
  19 +
  20 + <el-input-number v-model='average01' :min="0" :max="60" /> 秒开始,每
  21 + <el-input-number v-model='average02' :min="0" :max="60" /> 秒执行一次
  22 + </el-radio>
  23 + </el-form-item>
  24 +
  25 + <el-form-item>
  26 + <el-radio v-model='radioValue' :label="4">
  27 + 指定
  28 + <el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
  29 + <el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
  30 + </el-select>
  31 + </el-radio>
  32 + </el-form-item>
  33 + </el-form>
  34 +</template>
  35 +
  36 +<script>
  37 +export default {
  38 + data() {
  39 + return {
  40 + radioValue: 1,
  41 + cycle01: 1,
  42 + cycle02: 2,
  43 + average01: 0,
  44 + average02: 1,
  45 + checkboxList: [],
  46 + checkNum: this.$options.propsData.check
  47 + }
  48 + },
  49 + name: 'crontab-second',
  50 + props: ['check', 'radioParent'],
  51 + methods: {
  52 + // 单选按钮值变化时
  53 + radioChange() {
  54 + switch (this.radioValue) {
  55 + case 1:
  56 + this.$emit('update', 'second', '*', 'second');
  57 + this.$emit('update', 'min', '*', 'second');
  58 + break;
  59 + case 2:
  60 + this.$emit('update', 'second', this.cycle01 + '-' + this.cycle02);
  61 + break;
  62 + case 3:
  63 + this.$emit('update', 'second', this.average01 + '/' + this.average02);
  64 + break;
  65 + case 4:
  66 + this.$emit('update', 'second', this.checkboxString);
  67 + break;
  68 + }
  69 + },
  70 + // 周期两个值变化时
  71 + cycleChange() {
  72 + if (this.radioValue == '2') {
  73 + this.$emit('update', 'second', this.cycleTotal);
  74 + }
  75 + },
  76 + // 平均两个值变化时
  77 + averageChange() {
  78 + if (this.radioValue == '3') {
  79 + this.$emit('update', 'second', this.averageTotal);
  80 + }
  81 + },
  82 + // checkbox值变化时
  83 + checkboxChange() {
  84 + if (this.radioValue == '4') {
  85 + this.$emit('update', 'second', this.checkboxString);
  86 + }
  87 + },
  88 + othChange() {
  89 + //反解析
  90 + let ins = this.cron.second
  91 + ('反解析 second', ins);
  92 + if (ins === '*') {
  93 + this.radioValue = 1;
  94 + } else if (ins.indexOf('-') > -1) {
  95 + this.radioValue = 2
  96 + } else if (ins.indexOf('/') > -1) {
  97 + this.radioValue = 3
  98 + } else {
  99 + this.radioValue = 4
  100 + this.checkboxList = ins.split(',')
  101 + }
  102 + }
  103 + },
  104 + watch: {
  105 + "radioValue": "radioChange",
  106 + 'cycleTotal': 'cycleChange',
  107 + 'averageTotal': 'averageChange',
  108 + 'checkboxString': 'checkboxChange',
  109 + radioParent() {
  110 + this.radioValue = this.radioParent
  111 + }
  112 + },
  113 + computed: {
  114 + // 计算两个周期值
  115 + cycleTotal: function () {
  116 + this.cycle01 = this.checkNum(this.cycle01, 0, 59)
  117 + this.cycle02 = this.checkNum(this.cycle02, 0, 59)
  118 + return this.cycle01 + '-' + this.cycle02;
  119 + },
  120 + // 计算平均用到的值
  121 + averageTotal: function () {
  122 + this.average01 = this.checkNum(this.average01, 0, 59)
  123 + this.average02 = this.checkNum(this.average02, 1, 59)
  124 + return this.average01 + '/' + this.average02;
  125 + },
  126 + // 计算勾选的checkbox值合集
  127 + checkboxString: function () {
  128 + let str = this.checkboxList.join();
  129 + return str == '' ? '*' : str;
  130 + }
  131 + }
  132 +}
  133 +</script>
  1 +<template>
  2 + <el-form size='small'>
  3 + <el-form-item>
  4 + <el-radio v-model='radioValue' :label="1">
  5 + 周,允许的通配符[, - * / L #]
  6 + </el-radio>
  7 + </el-form-item>
  8 +
  9 + <el-form-item>
  10 + <el-radio v-model='radioValue' :label="2">
  11 + 不指定
  12 + </el-radio>
  13 + </el-form-item>
  14 +
  15 + <el-form-item>
  16 + <el-radio v-model='radioValue' :label="3">
  17 + 周期从星期
  18 + <el-input-number v-model='cycle01' :min="1" :max="7" /> -
  19 + <el-input-number v-model='cycle02' :min="1" :max="7" />
  20 + </el-radio>
  21 + </el-form-item>
  22 +
  23 + <el-form-item>
  24 + <el-radio v-model='radioValue' :label="4">
  25 +
  26 + <el-input-number v-model='average01' :min="1" :max="4" /> 周的星期
  27 + <el-input-number v-model='average02' :min="1" :max="7" />
  28 + </el-radio>
  29 + </el-form-item>
  30 +
  31 + <el-form-item>
  32 + <el-radio v-model='radioValue' :label="5">
  33 + 本月最后一个星期
  34 + <el-input-number v-model='weekday' :min="1" :max="7" />
  35 + </el-radio>
  36 + </el-form-item>
  37 +
  38 + <el-form-item>
  39 + <el-radio v-model='radioValue' :label="6">
  40 + 指定
  41 + <el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
  42 + <el-option v-for="(item,index) of weekList" :key="index" :value="index+1">{{item}}</el-option>
  43 + </el-select>
  44 + </el-radio>
  45 + </el-form-item>
  46 +
  47 + </el-form>
  48 +</template>
  49 +
  50 +<script>
  51 +export default {
  52 + data() {
  53 + return {
  54 + radioValue: 2,
  55 + weekday: 1,
  56 + cycle01: 1,
  57 + cycle02: 2,
  58 + average01: 1,
  59 + average02: 1,
  60 + checkboxList: [],
  61 + weekList: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
  62 + checkNum: this.$options.propsData.check
  63 + }
  64 + },
  65 + name: 'crontab-week',
  66 + props: ['check', 'cron'],
  67 + methods: {
  68 + // 单选按钮值变化时
  69 + radioChange() {
  70 + if (this.radioValue === 1) {
  71 + this.$emit('update', 'week', '*');
  72 + this.$emit('update', 'year', '*');
  73 + } else {
  74 + if (this.cron.mouth === '*') {
  75 + this.$emit('update', 'mouth', '0', 'week');
  76 + }
  77 + if (this.cron.day === '*') {
  78 + this.$emit('update', 'day', '0', 'week');
  79 + }
  80 + if (this.cron.hour === '*') {
  81 + this.$emit('update', 'hour', '0', 'week');
  82 + }
  83 + if (this.cron.min === '*') {
  84 + this.$emit('update', 'min', '0', 'week');
  85 + }
  86 + if (this.cron.second === '*') {
  87 + this.$emit('update', 'second', '0', 'week');
  88 + }
  89 + }
  90 + switch (this.radioValue) {
  91 + case 2:
  92 + this.$emit('update', 'week', '?');
  93 + break;
  94 + case 3:
  95 + this.$emit('update', 'week', this.cycle01 + '-' + this.cycle02);
  96 + break;
  97 + case 4:
  98 + this.$emit('update', 'week', this.average01 + '#' + this.average02);
  99 + break;
  100 + case 5:
  101 + this.$emit('update', 'week', this.weekday + 'L');
  102 + break;
  103 + case 6:
  104 + this.$emit('update', 'week', this.checkboxString);
  105 + break;
  106 + }
  107 + },
  108 + // 根据互斥事件,更改radio的值
  109 +
  110 + // 周期两个值变化时
  111 + cycleChange() {
  112 + if (this.radioValue == '3') {
  113 + this.$emit('update', 'week', this.cycleTotal);
  114 + }
  115 + },
  116 + // 平均两个值变化时
  117 + averageChange() {
  118 + if (this.radioValue == '4') {
  119 + this.$emit('update', 'week', this.averageTotal);
  120 + }
  121 + },
  122 + // 最近工作日值变化时
  123 + weekdayChange() {
  124 + if (this.radioValue == '5') {
  125 + this.$emit('update', 'week', this.weekday + 'L');
  126 + }
  127 + },
  128 + // checkbox值变化时
  129 + checkboxChange() {
  130 + if (this.radioValue == '6') {
  131 + this.$emit('update', 'week', this.checkboxString);
  132 + }
  133 + },
  134 + },
  135 + watch: {
  136 + "radioValue": "radioChange",
  137 + 'cycleTotal': 'cycleChange',
  138 + 'averageTotal': 'averageChange',
  139 + 'weekdayCheck': 'weekdayChange',
  140 + 'checkboxString': 'checkboxChange',
  141 + },
  142 + computed: {
  143 + // 计算两个周期值
  144 + cycleTotal: function () {
  145 + this.cycle01 = this.checkNum(this.cycle01, 1, 7)
  146 + this.cycle02 = this.checkNum(this.cycle02, 1, 7)
  147 + return this.cycle01 + '-' + this.cycle02;
  148 + },
  149 + // 计算平均用到的值
  150 + averageTotal: function () {
  151 + this.average01 = this.checkNum(this.average01, 1, 4)
  152 + this.average02 = this.checkNum(this.average02, 1, 7)
  153 + return this.average01 + '#' + this.average02;
  154 + },
  155 + // 最近的工作日(格式)
  156 + weekdayCheck: function () {
  157 + this.weekday = this.checkNum(this.weekday, 1, 7)
  158 + return this.weekday;
  159 + },
  160 + // 计算勾选的checkbox值合集
  161 + checkboxString: function () {
  162 + let str = this.checkboxList.join();
  163 + return str == '' ? '*' : str;
  164 + }
  165 + }
  166 +}
  167 +</script>
  1 +<template>
  2 + <el-form size="small">
  3 + <el-form-item>
  4 + <el-radio :label="1" v-model='radioValue'>
  5 + 不填,允许的通配符[, - * /]
  6 + </el-radio>
  7 + </el-form-item>
  8 +
  9 + <el-form-item>
  10 + <el-radio :label="2" v-model='radioValue'>
  11 + 每年
  12 + </el-radio>
  13 + </el-form-item>
  14 +
  15 + <el-form-item>
  16 + <el-radio :label="3" v-model='radioValue'>
  17 + 周期从
  18 + <el-input-number v-model='cycle01' :min='fullYear' /> -
  19 + <el-input-number v-model='cycle02' :min='fullYear' />
  20 + </el-radio>
  21 + </el-form-item>
  22 +
  23 + <el-form-item>
  24 + <el-radio :label="4" v-model='radioValue'>
  25 +
  26 + <el-input-number v-model='average01' :min='fullYear' /> 年开始,每
  27 + <el-input-number v-model='average02' :min='fullYear' /> 年执行一次
  28 + </el-radio>
  29 +
  30 + </el-form-item>
  31 +
  32 + <el-form-item>
  33 + <el-radio :label="5" v-model='radioValue'>
  34 + 指定
  35 + <el-select clearable v-model="checkboxList" placeholder="可多选" multiple>
  36 + <el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear" :label="item -1 + fullYear" />
  37 + </el-select>
  38 + </el-radio>
  39 + </el-form-item>
  40 + </el-form>
  41 +</template>
  42 +
  43 +<script>
  44 +export default {
  45 + data() {
  46 + return {
  47 + fullYear: 0,
  48 + radioValue: 1,
  49 + cycle01: 0,
  50 + cycle02: 0,
  51 + average01: 0,
  52 + average02: 1,
  53 + checkboxList: [],
  54 + checkNum: this.$options.propsData.check
  55 + }
  56 + },
  57 + name: 'crontab-year',
  58 + props: ['check', 'mouth', 'cron'],
  59 + methods: {
  60 + // 单选按钮值变化时
  61 + radioChange() {
  62 + if (this.cron.mouth === '*') {
  63 + this.$emit('update', 'mouth', '0', 'year');
  64 + }
  65 + if (this.cron.day === '*') {
  66 + this.$emit('update', 'day', '0', 'year');
  67 + }
  68 + if (this.cron.hour === '*') {
  69 + this.$emit('update', 'hour', '0', 'year');
  70 + }
  71 + if (this.cron.min === '*') {
  72 + this.$emit('update', 'min', '0', 'year');
  73 + }
  74 + if (this.cron.second === '*') {
  75 + this.$emit('update', 'second', '0', 'year');
  76 + }
  77 + switch (this.radioValue) {
  78 + case 1:
  79 + this.$emit('update', 'year', '');
  80 + break;
  81 + case 2:
  82 + this.$emit('update', 'year', '*');
  83 + break;
  84 + case 3:
  85 + this.$emit('update', 'year', this.cycle01 + '-' + this.cycle02);
  86 + break;
  87 + case 4:
  88 + this.$emit('update', 'year', this.average01 + '/' + this.average02);
  89 + break;
  90 + case 5:
  91 + this.$emit('update', 'year', this.checkboxString);
  92 + break;
  93 + }
  94 + },
  95 + // 周期两个值变化时
  96 + cycleChange() {
  97 + if (this.radioValue == '3') {
  98 + this.$emit('update', 'year', this.cycleTotal);
  99 + }
  100 + },
  101 + // 平均两个值变化时
  102 + averageChange() {
  103 + if (this.radioValue == '4') {
  104 + this.$emit('update', 'year', this.averageTotal);
  105 + }
  106 + },
  107 + // checkbox值变化时
  108 + checkboxChange() {
  109 + if (this.radioValue == '5') {
  110 + this.$emit('update', 'year', this.checkboxString);
  111 + }
  112 + }
  113 + },
  114 + watch: {
  115 + "radioValue": "radioChange",
  116 + 'cycleTotal': 'cycleChange',
  117 + 'averageTotal': 'averageChange',
  118 + 'checkboxString': 'checkboxChange'
  119 + },
  120 + computed: {
  121 + // 计算两个周期值
  122 + cycleTotal: function () {
  123 + this.cycle01 = this.checkNum(this.cycle01, this.fullYear, this.fullYear + 100)
  124 + this.cycle02 = this.checkNum(this.cycle02, this.fullYear + 1, this.fullYear + 101)
  125 + return this.cycle01 + '-' + this.cycle02;
  126 + },
  127 + // 计算平均用到的值
  128 + averageTotal: function () {
  129 + this.average01 = this.checkNum(this.average01, this.fullYear, this.fullYear + 100)
  130 + this.average02 = this.checkNum(this.average02, 1, 10)
  131 + return this.average01 + '/' + this.average02;
  132 + },
  133 + // 计算勾选的checkbox值合集
  134 + checkboxString: function () {
  135 + let str = this.checkboxList.join();
  136 + return str;
  137 + }
  138 + },
  139 + mounted: function () {
  140 + // 仅获取当前年份
  141 + this.fullYear = Number(new Date().getFullYear());
  142 + }
  143 +}
  144 +</script>
@@ -156,7 +156,7 @@ @@ -156,7 +156,7 @@
156 /> 156 />
157 157
158 <!-- 添加或修改定时任务对话框 --> 158 <!-- 添加或修改定时任务对话框 -->
159 - <el-dialog :title="title" :visible.sync="open" width="700px" append-to-body> 159 + <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
160 <el-form ref="form" :model="form" :rules="rules" label-width="120px"> 160 <el-form ref="form" :model="form" :rules="rules" label-width="120px">
161 <el-row> 161 <el-row>
162 <el-col :span="12"> 162 <el-col :span="12">
@@ -192,17 +192,16 @@ @@ -192,17 +192,16 @@
192 <el-input v-model="form.invokeTarget" placeholder="请输入调用目标字符串" /> 192 <el-input v-model="form.invokeTarget" placeholder="请输入调用目标字符串" />
193 </el-form-item> 193 </el-form-item>
194 </el-col> 194 </el-col>
195 - <el-col :span="12"> 195 + <el-col :span="24">
196 <el-form-item label="cron表达式" prop="cronExpression"> 196 <el-form-item label="cron表达式" prop="cronExpression">
197 - <el-input v-model="form.cronExpression" placeholder="请输入cron执行表达式" />  
198 - </el-form-item>  
199 - </el-col>  
200 - <el-col :span="12">  
201 - <el-form-item label="是否并发" prop="concurrent">  
202 - <el-radio-group v-model="form.concurrent" size="small">  
203 - <el-radio-button label="0">允许</el-radio-button>  
204 - <el-radio-button label="1">禁止</el-radio-button>  
205 - </el-radio-group> 197 + <el-input v-model="form.cronExpression" placeholder="请输入cron执行表达式">
  198 + <template slot="append">
  199 + <el-button type="primary" @click="handleShowCron">
  200 + 生成表达式
  201 + <i class="el-icon-time el-icon--right"></i>
  202 + </el-button>
  203 + </template>
  204 + </el-input>
206 </el-form-item> 205 </el-form-item>
207 </el-col> 206 </el-col>
208 <el-col :span="24"> 207 <el-col :span="24">
@@ -214,7 +213,15 @@ @@ -214,7 +213,15 @@
214 </el-radio-group> 213 </el-radio-group>
215 </el-form-item> 214 </el-form-item>
216 </el-col> 215 </el-col>
217 - <el-col :span="24"> 216 + <el-col :span="12">
  217 + <el-form-item label="是否并发" prop="concurrent">
  218 + <el-radio-group v-model="form.concurrent" size="small">
  219 + <el-radio-button label="0">允许</el-radio-button>
  220 + <el-radio-button label="1">禁止</el-radio-button>
  221 + </el-radio-group>
  222 + </el-form-item>
  223 + </el-col>
  224 + <el-col :span="12">
218 <el-form-item label="状态"> 225 <el-form-item label="状态">
219 <el-radio-group v-model="form.status"> 226 <el-radio-group v-model="form.status">
220 <el-radio 227 <el-radio
@@ -233,6 +240,10 @@ @@ -233,6 +240,10 @@
233 </div> 240 </div>
234 </el-dialog> 241 </el-dialog>
235 242
  243 + <el-dialog title="Cron表达式生成器" :visible.sync="openCron">
  244 + <crontab @hide="openCron=false" @fill="crontabFill" :expression="expression"></crontab>
  245 + </el-dialog>
  246 +
236 <!-- 任务日志详细 --> 247 <!-- 任务日志详细 -->
237 <el-dialog title="任务详细" :visible.sync="openView" width="700px" append-to-body> 248 <el-dialog title="任务详细" :visible.sync="openView" width="700px" append-to-body>
238 <el-form ref="form" :model="form" label-width="120px" size="mini"> 249 <el-form ref="form" :model="form" label-width="120px" size="mini">
@@ -285,8 +296,10 @@ @@ -285,8 +296,10 @@
285 296
286 <script> 297 <script>
287 import { listJob, getJob, delJob, addJob, updateJob, exportJob, runJob, changeJobStatus } from "@/api/monitor/job"; 298 import { listJob, getJob, delJob, addJob, updateJob, exportJob, runJob, changeJobStatus } from "@/api/monitor/job";
  299 +import Crontab from '@/components/Crontab'
288 300
289 export default { 301 export default {
  302 + components: { Crontab },
290 name: "Job", 303 name: "Job",
291 data() { 304 data() {
292 return { 305 return {
@@ -312,6 +325,10 @@ export default { @@ -312,6 +325,10 @@ export default {
312 open: false, 325 open: false,
313 // 是否显示详细弹出层 326 // 是否显示详细弹出层
314 openView: false, 327 openView: false,
  328 + // 是否显示Cron表达式弹出层
  329 + openCron: false,
  330 + // 传入的表达式
  331 + expression: "",
315 // 任务组名字典 332 // 任务组名字典
316 jobGroupOptions: [], 333 jobGroupOptions: [],
317 // 状态字典 334 // 状态字典
@@ -448,6 +465,15 @@ export default { @@ -448,6 +465,15 @@ export default {
448 this.openView = true; 465 this.openView = true;
449 }); 466 });
450 }, 467 },
  468 + /** cron表达式按钮操作 */
  469 + handleShowCron() {
  470 + this.expression = this.form.cronExpression;
  471 + this.openCron = true;
  472 + },
  473 + /** 确定后回传值 */
  474 + crontabFill(value) {
  475 + this.form.cronExpression = value;
  476 + },
451 /** 任务日志列表查询 */ 477 /** 任务日志列表查询 */
452 handleJobLog(row) { 478 handleJobLog(row) {
453 const jobId = row.jobId || 0; 479 const jobId = row.jobId || 0;