懒羊羊
2024-01-31 e57a8990ae56f657a59c435a0613c5f7a8728003
提交 | 用户 | 时间
e57a89 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 nMonth = 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.getMonthArr(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, nMonth);
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 resetMonth = function () {
88                 MIdx = 0;
89                 nMonth = MDate[MIdx]
90                 resetDay();
91             }
92             // 如果当前年份不为数组中当前值
93             if (nYear !== YDate[YIdx]) {
94                 resetMonth();
95             }
96             // 如果当前月份不为数组中当前值
97             if (nMonth !== 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 (nMonth > MDate[MDate.length - 1]) {
118                     resetMonth();
119                     continue;
120                 }
121                 // 循环月份数组
122                 goMonth: 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                             resetMonth();
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                                     resetMonth();
148                                     continue goYear;
149                                 }
150                                 continue goMonth;
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 goMonth;
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 == 1) {
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 == 7) {
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 (this.dayRuleSup.indexOf(thisWeek) < 0) {
204                                 // 如果到达最大值时
205                                 if (Di == DDate.length - 1) {
206                                     resetDay();
207                                     if (Mi == MDate.length - 1) {
208                                         resetMonth();
209                                         continue goYear;
210                                     }
211                                     continue goMonth;
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                                             resetMonth();
258                                             continue goYear;
259                                         }
260                                         continue goMonth;
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                                                     resetMonth();
281                                                     continue goYear;
282                                                 }
283                                                 continue goMonth;
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                                                         resetMonth();
312                                                         continue goYear;
313                                                     }
314                                                     continue goMonth;
315                                                 }
316                                                 continue goDay;
317                                             }
318                                             continue goHour;
319                                         }
320                                         continue goMin;
321                                     }
322                                 } //goSecond
323                             } //goMin
324                         }//goHour
325                     }//goDay
326                 }//goMonth
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         getMonthArr(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[1]), Number(matchRule[0])];
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             }
405         },
406         // 获取"日"数组-少量为日期规则
407         getDayArr(rule) {
408             this.dateArr[3] = this.getOrderArr(1, 31);
409             this.dayRule = '';
410             this.dayRuleSup = '';
411             if (rule.indexOf('-') >= 0) {
412                 this.dateArr[3] = this.getCycleArr(rule, 31, false)
413                 this.dayRuleSup = 'null';
414             } else if (rule.indexOf('/') >= 0) {
415                 this.dateArr[3] = this.getAverageArr(rule, 31)
416                 this.dayRuleSup = 'null';
417             } else if (rule.indexOf('W') >= 0) {
418                 this.dayRule = 'workDay';
419                 this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]);
420                 this.dateArr[3] = [this.dayRuleSup];
421             } else if (rule.indexOf('L') >= 0) {
422                 this.dayRule = 'lastDay';
423                 this.dayRuleSup = 'null';
424                 this.dateArr[3] = [31];
425             } else if (rule !== '*' && rule !== '?') {
426                 this.dateArr[3] = this.getAssignArr(rule)
427                 this.dayRuleSup = 'null';
428             } else if (rule == '*') {
429                 this.dayRuleSup = 'null';
430             }
431         },
432         // 获取"时"数组
433         getHourArr(rule) {
434             this.dateArr[2] = this.getOrderArr(0, 23);
435             if (rule.indexOf('-') >= 0) {
436                 this.dateArr[2] = this.getCycleArr(rule, 24, true)
437             } else if (rule.indexOf('/') >= 0) {
438                 this.dateArr[2] = this.getAverageArr(rule, 23)
439             } else if (rule !== '*') {
440                 this.dateArr[2] = this.getAssignArr(rule)
441             }
442         },
443         // 获取"分"数组
444         getMinArr(rule) {
445             this.dateArr[1] = this.getOrderArr(0, 59);
446             if (rule.indexOf('-') >= 0) {
447                 this.dateArr[1] = this.getCycleArr(rule, 60, true)
448             } else if (rule.indexOf('/') >= 0) {
449                 this.dateArr[1] = this.getAverageArr(rule, 59)
450             } else if (rule !== '*') {
451                 this.dateArr[1] = this.getAssignArr(rule)
452             }
453         },
454         // 获取"秒"数组
455         getSecondArr(rule) {
456             this.dateArr[0] = this.getOrderArr(0, 59);
457             if (rule.indexOf('-') >= 0) {
458                 this.dateArr[0] = this.getCycleArr(rule, 60, true)
459             } else if (rule.indexOf('/') >= 0) {
460                 this.dateArr[0] = this.getAverageArr(rule, 59)
461             } else if (rule !== '*') {
462                 this.dateArr[0] = this.getAssignArr(rule)
463             }
464         },
465         // 根据传进来的min-max返回一个顺序的数组
466         getOrderArr(min, max) {
467             let arr = [];
468             for (let i = min; i <= max; i++) {
469                 arr.push(i);
470             }
471             return arr;
472         },
473         // 根据规则中指定的零散值返回一个数组
474         getAssignArr(rule) {
475             let arr = [];
476             let assiginArr = rule.split(',');
477             for (let i = 0; i < assiginArr.length; i++) {
478                 arr[i] = Number(assiginArr[i])
479             }
480             arr.sort(this.compare)
481             return arr;
482         },
483         // 根据一定算术规则计算返回一个数组
484         getAverageArr(rule, limit) {
485             let arr = [];
486             let agArr = rule.split('/');
487             let min = Number(agArr[0]);
488             let step = Number(agArr[1]);
489             while (min <= limit) {
490                 arr.push(min);
491                 min += step;
492             }
493             return arr;
494         },
495         // 根据规则返回一个具有周期性的数组
496         getCycleArr(rule, limit, status) {
497             // status--表示是否从0开始(则从1开始)
498             let arr = [];
499             let cycleArr = rule.split('-');
500             let min = Number(cycleArr[0]);
501             let max = Number(cycleArr[1]);
502             if (min > max) {
503                 max += limit;
504             }
505             for (let i = min; i <= max; i++) {
506                 let add = 0;
507                 if (status == false && i % limit == 0) {
508                     add = limit;
509                 }
510                 arr.push(Math.round(i % limit + add))
511             }
512             arr.sort(this.compare)
513             return arr;
514         },
515         // 比较数字大小(用于Array.sort)
516         compare(value1, value2) {
517             if (value2 - value1 > 0) {
518                 return -1;
519             } else {
520                 return 1;
521             }
522         },
523         // 格式化日期格式如:2017-9-19 18:04:33
524         formatDate(value, type) {
525             // 计算日期相关值
526             let time = typeof value == 'number' ? new Date(value) : value;
527             let Y = time.getFullYear();
528             let M = time.getMonth() + 1;
529             let D = time.getDate();
530             let h = time.getHours();
531             let m = time.getMinutes();
532             let s = time.getSeconds();
533             let week = time.getDay();
534             // 如果传递了type的话
535             if (type == undefined) {
536                 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);
537             } else if (type == 'week') {
538                 // 在quartz中 1为星期日
539                 return week + 1;
540             }
541         },
542         // 检查日期是否存在
543         checkDate(value) {
544             let time = new Date(value);
545             let format = this.formatDate(time)
546             return value === format;
547         }
548     },
549     watch: {
550         'ex': 'expressionChange'
551     },
552     props: ['ex'],
553     mounted: function () {
554         // 初始化 获取一次结果
555         this.expressionChange();
556     }
557 }
558
559 </script>