Newer
Older
DH_Apicture / src / components / Crontab / result.vue
@zhangqy zhangqy on 29 Nov 20 KB first commit
  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 setup>
  14. const props = defineProps({
  15. ex: {
  16. type: String,
  17. default: ''
  18. }
  19. })
  20. const dayRule = ref('')
  21. const dayRuleSup = ref('')
  22. const dateArr = ref([])
  23. const resultList = ref([])
  24. const isShow = ref(false)
  25. watch(() => props.ex, () => expressionChange())
  26. // 表达式值变化时,开始去计算结果
  27. function expressionChange() {
  28. // 计算开始-隐藏结果
  29. isShow.value = false;
  30. // 获取规则数组[0秒、1分、2时、3日、4月、5星期、6年]
  31. let ruleArr = props.ex.split(' ');
  32. // 用于记录进入循环的次数
  33. let nums = 0;
  34. // 用于暂时存符号时间规则结果的数组
  35. let resultArr = [];
  36. // 获取当前时间精确至[年、月、日、时、分、秒]
  37. let nTime = new Date();
  38. let nYear = nTime.getFullYear();
  39. let nMonth = nTime.getMonth() + 1;
  40. let nDay = nTime.getDate();
  41. let nHour = nTime.getHours();
  42. let nMin = nTime.getMinutes();
  43. let nSecond = nTime.getSeconds();
  44. // 根据规则获取到近100年可能年数组、月数组等等
  45. getSecondArr(ruleArr[0]);
  46. getMinArr(ruleArr[1]);
  47. getHourArr(ruleArr[2]);
  48. getDayArr(ruleArr[3]);
  49. getMonthArr(ruleArr[4]);
  50. getWeekArr(ruleArr[5]);
  51. getYearArr(ruleArr[6], nYear);
  52. // 将获取到的数组赋值-方便使用
  53. let sDate = dateArr.value[0];
  54. let mDate = dateArr.value[1];
  55. let hDate = dateArr.value[2];
  56. let DDate = dateArr.value[3];
  57. let MDate = dateArr.value[4];
  58. let YDate = dateArr.value[5];
  59. // 获取当前时间在数组中的索引
  60. let sIdx = getIndex(sDate, nSecond);
  61. let mIdx = getIndex(mDate, nMin);
  62. let hIdx = getIndex(hDate, nHour);
  63. let DIdx = getIndex(DDate, nDay);
  64. let MIdx = getIndex(MDate, nMonth);
  65. let YIdx = getIndex(YDate, nYear);
  66. // 重置月日时分秒的函数(后面用的比较多)
  67. const resetSecond = function () {
  68. sIdx = 0;
  69. nSecond = sDate[sIdx]
  70. }
  71. const resetMin = function () {
  72. mIdx = 0;
  73. nMin = mDate[mIdx]
  74. resetSecond();
  75. }
  76. const resetHour = function () {
  77. hIdx = 0;
  78. nHour = hDate[hIdx]
  79. resetMin();
  80. }
  81. const resetDay = function () {
  82. DIdx = 0;
  83. nDay = DDate[DIdx]
  84. resetHour();
  85. }
  86. const resetMonth = function () {
  87. MIdx = 0;
  88. nMonth = MDate[MIdx]
  89. resetDay();
  90. }
  91. // 如果当前年份不为数组中当前值
  92. if (nYear !== YDate[YIdx]) {
  93. resetMonth();
  94. }
  95. // 如果当前月份不为数组中当前值
  96. if (nMonth !== MDate[MIdx]) {
  97. resetDay();
  98. }
  99. // 如果当前“日”不为数组中当前值
  100. if (nDay !== DDate[DIdx]) {
  101. resetHour();
  102. }
  103. // 如果当前“时”不为数组中当前值
  104. if (nHour !== hDate[hIdx]) {
  105. resetMin();
  106. }
  107. // 如果当前“分”不为数组中当前值
  108. if (nMin !== mDate[mIdx]) {
  109. resetSecond();
  110. }
  111. // 循环年份数组
  112. goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) {
  113. let YY = YDate[Yi];
  114. // 如果到达最大值时
  115. if (nMonth > MDate[MDate.length - 1]) {
  116. resetMonth();
  117. continue;
  118. }
  119. // 循环月份数组
  120. goMonth: for (let Mi = MIdx; Mi < MDate.length; Mi++) {
  121. // 赋值、方便后面运算
  122. let MM = MDate[Mi];
  123. MM = MM < 10 ? '0' + MM : MM;
  124. // 如果到达最大值时
  125. if (nDay > DDate[DDate.length - 1]) {
  126. resetDay();
  127. if (Mi === MDate.length - 1) {
  128. resetMonth();
  129. continue goYear;
  130. }
  131. continue;
  132. }
  133. // 循环日期数组
  134. goDay: for (let Di = DIdx; Di < DDate.length; Di++) {
  135. // 赋值、方便后面运算
  136. let DD = DDate[Di];
  137. let thisDD = DD < 10 ? '0' + DD : DD;
  138. // 如果到达最大值时
  139. if (nHour > hDate[hDate.length - 1]) {
  140. resetHour();
  141. if (Di === DDate.length - 1) {
  142. resetDay();
  143. if (Mi === MDate.length - 1) {
  144. resetMonth();
  145. continue goYear;
  146. }
  147. continue goMonth;
  148. }
  149. continue;
  150. }
  151. // 判断日期的合法性,不合法的话也是跳出当前循环
  152. if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true && dayRule.value !== 'workDay' && dayRule.value !== 'lastWeek' && dayRule.value !== 'lastDay') {
  153. resetDay();
  154. continue goMonth;
  155. }
  156. // 如果日期规则中有值时
  157. if (dayRule.value === 'lastDay') {
  158. // 如果不是合法日期则需要将前将日期调到合法日期即月末最后一天
  159. if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  160. while (DD > 0 && checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  161. DD--;
  162. thisDD = DD < 10 ? '0' + DD : DD;
  163. }
  164. }
  165. } else if (dayRule.value === 'workDay') {
  166. // 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
  167. if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  168. while (DD > 0 && checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  169. DD--;
  170. thisDD = DD < 10 ? '0' + DD : DD;
  171. }
  172. }
  173. // 获取达到条件的日期是星期X
  174. let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
  175. // 当星期日时
  176. if (thisWeek === 1) {
  177. // 先找下一个日,并判断是否为月底
  178. DD++;
  179. thisDD = DD < 10 ? '0' + DD : DD;
  180. // 判断下一日已经不是合法日期
  181. if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  182. DD -= 3;
  183. }
  184. } else if (thisWeek === 7) {
  185. // 当星期6时只需判断不是1号就可进行操作
  186. if (dayRuleSup.value !== 1) {
  187. DD--;
  188. } else {
  189. DD += 2;
  190. }
  191. }
  192. } else if (dayRule.value === 'weekDay') {
  193. // 如果指定了是星期几
  194. // 获取当前日期是属于星期几
  195. let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
  196. // 校验当前星期是否在星期池(dayRuleSup)中
  197. if (dayRuleSup.value.indexOf(thisWeek) < 0) {
  198. // 如果到达最大值时
  199. if (Di === DDate.length - 1) {
  200. resetDay();
  201. if (Mi === MDate.length - 1) {
  202. resetMonth();
  203. continue goYear;
  204. }
  205. continue goMonth;
  206. }
  207. continue;
  208. }
  209. } else if (dayRule.value === 'assWeek') {
  210. // 如果指定了是第几周的星期几
  211. // 获取每月1号是属于星期几
  212. let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
  213. if (dayRuleSup.value[1] >= thisWeek) {
  214. DD = (dayRuleSup.value[0] - 1) * 7 + dayRuleSup.value[1] - thisWeek + 1;
  215. } else {
  216. DD = dayRuleSup.value[0] * 7 + dayRuleSup.value[1] - thisWeek + 1;
  217. }
  218. } else if (dayRule.value === 'lastWeek') {
  219. // 如果指定了每月最后一个星期几
  220. // 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
  221. if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  222. while (DD > 0 && checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
  223. DD--;
  224. thisDD = DD < 10 ? '0' + DD : DD;
  225. }
  226. }
  227. // 获取月末最后一天是星期几
  228. let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
  229. // 找到要求中最近的那个星期几
  230. if (dayRuleSup.value < thisWeek) {
  231. DD -= thisWeek - dayRuleSup.value;
  232. } else if (dayRuleSup.value > thisWeek) {
  233. DD -= 7 - (dayRuleSup.value - thisWeek)
  234. }
  235. }
  236. // 判断时间值是否小于10置换成“05”这种格式
  237. DD = DD < 10 ? '0' + DD : DD;
  238. // 循环“时”数组
  239. goHour: for (let hi = hIdx; hi < hDate.length; hi++) {
  240. let hh = hDate[hi] < 10 ? '0' + hDate[hi] : hDate[hi]
  241. // 如果到达最大值时
  242. if (nMin > mDate[mDate.length - 1]) {
  243. resetMin();
  244. if (hi === hDate.length - 1) {
  245. resetHour();
  246. if (Di === DDate.length - 1) {
  247. resetDay();
  248. if (Mi === MDate.length - 1) {
  249. resetMonth();
  250. continue goYear;
  251. }
  252. continue goMonth;
  253. }
  254. continue goDay;
  255. }
  256. continue;
  257. }
  258. // 循环"分"数组
  259. goMin: for (let mi = mIdx; mi < mDate.length; mi++) {
  260. let mm = mDate[mi] < 10 ? '0' + mDate[mi] : mDate[mi];
  261. // 如果到达最大值时
  262. if (nSecond > sDate[sDate.length - 1]) {
  263. resetSecond();
  264. if (mi === mDate.length - 1) {
  265. resetMin();
  266. if (hi === hDate.length - 1) {
  267. resetHour();
  268. if (Di === DDate.length - 1) {
  269. resetDay();
  270. if (Mi === MDate.length - 1) {
  271. resetMonth();
  272. continue goYear;
  273. }
  274. continue goMonth;
  275. }
  276. continue goDay;
  277. }
  278. continue goHour;
  279. }
  280. continue;
  281. }
  282. // 循环"秒"数组
  283. goSecond: for (let si = sIdx; si <= sDate.length - 1; si++) {
  284. let ss = sDate[si] < 10 ? '0' + sDate[si] : sDate[si];
  285. // 添加当前时间(时间合法性在日期循环时已经判断)
  286. if (MM !== '00' && DD !== '00') {
  287. resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss)
  288. nums++;
  289. }
  290. // 如果条数满了就退出循环
  291. if (nums === 5) break goYear;
  292. // 如果到达最大值时
  293. if (si === sDate.length - 1) {
  294. resetSecond();
  295. if (mi === mDate.length - 1) {
  296. resetMin();
  297. if (hi === hDate.length - 1) {
  298. resetHour();
  299. if (Di === DDate.length - 1) {
  300. resetDay();
  301. if (Mi === MDate.length - 1) {
  302. resetMonth();
  303. continue goYear;
  304. }
  305. continue goMonth;
  306. }
  307. continue goDay;
  308. }
  309. continue goHour;
  310. }
  311. continue goMin;
  312. }
  313. } //goSecond
  314. } //goMin
  315. }//goHour
  316. }//goDay
  317. }//goMonth
  318. }
  319. // 判断100年内的结果条数
  320. if (resultArr.length === 0) {
  321. resultList.value = ['没有达到条件的结果!'];
  322. } else {
  323. resultList.value = resultArr;
  324. if (resultArr.length !== 5) {
  325. resultList.value.push('最近100年内只有上面' + resultArr.length + '条结果!')
  326. }
  327. }
  328. // 计算完成-显示结果
  329. isShow.value = true;
  330. }
  331. // 用于计算某位数字在数组中的索引
  332. function getIndex(arr, value) {
  333. if (value <= arr[0] || value > arr[arr.length - 1]) {
  334. return 0;
  335. } else {
  336. for (let i = 0; i < arr.length - 1; i++) {
  337. if (value > arr[i] && value <= arr[i + 1]) {
  338. return i + 1;
  339. }
  340. }
  341. }
  342. }
  343. // 获取"年"数组
  344. function getYearArr(rule, year) {
  345. dateArr.value[5] = getOrderArr(year, year + 100);
  346. if (rule !== undefined) {
  347. if (rule.indexOf('-') >= 0) {
  348. dateArr.value[5] = getCycleArr(rule, year + 100, false)
  349. } else if (rule.indexOf('/') >= 0) {
  350. dateArr.value[5] = getAverageArr(rule, year + 100)
  351. } else if (rule !== '*') {
  352. dateArr.value[5] = getAssignArr(rule)
  353. }
  354. }
  355. }
  356. // 获取"月"数组
  357. function getMonthArr(rule) {
  358. dateArr.value[4] = getOrderArr(1, 12);
  359. if (rule.indexOf('-') >= 0) {
  360. dateArr.value[4] = getCycleArr(rule, 12, false)
  361. } else if (rule.indexOf('/') >= 0) {
  362. dateArr.value[4] = getAverageArr(rule, 12)
  363. } else if (rule !== '*') {
  364. dateArr.value[4] = getAssignArr(rule)
  365. }
  366. }
  367. // 获取"日"数组-主要为日期规则
  368. function getWeekArr(rule) {
  369. // 只有当日期规则的两个值均为“”时则表达日期是有选项的
  370. if (dayRule.value === '' && dayRuleSup.value === '') {
  371. if (rule.indexOf('-') >= 0) {
  372. dayRule.value = 'weekDay';
  373. dayRuleSup.value = getCycleArr(rule, 7, false)
  374. } else if (rule.indexOf('#') >= 0) {
  375. dayRule.value = 'assWeek';
  376. let matchRule = rule.match(/[0-9]{1}/g);
  377. dayRuleSup.value = [Number(matchRule[1]), Number(matchRule[0])];
  378. dateArr.value[3] = [1];
  379. if (dayRuleSup.value[1] === 7) {
  380. dayRuleSup.value[1] = 0;
  381. }
  382. } else if (rule.indexOf('L') >= 0) {
  383. dayRule.value = 'lastWeek';
  384. dayRuleSup.value = Number(rule.match(/[0-9]{1,2}/g)[0]);
  385. dateArr.value[3] = [31];
  386. if (dayRuleSup.value === 7) {
  387. dayRuleSup.value = 0;
  388. }
  389. } else if (rule !== '*' && rule !== '?') {
  390. dayRule.value = 'weekDay';
  391. dayRuleSup.value = getAssignArr(rule)
  392. }
  393. }
  394. }
  395. // 获取"日"数组-少量为日期规则
  396. function getDayArr(rule) {
  397. dateArr.value[3] = getOrderArr(1, 31);
  398. dayRule.value = '';
  399. dayRuleSup.value = '';
  400. if (rule.indexOf('-') >= 0) {
  401. dateArr.value[3] = getCycleArr(rule, 31, false)
  402. dayRuleSup.value = 'null';
  403. } else if (rule.indexOf('/') >= 0) {
  404. dateArr.value[3] = getAverageArr(rule, 31)
  405. dayRuleSup.value = 'null';
  406. } else if (rule.indexOf('W') >= 0) {
  407. dayRule.value = 'workDay';
  408. dayRuleSup.value = Number(rule.match(/[0-9]{1,2}/g)[0]);
  409. dateArr.value[3] = [dayRuleSup.value];
  410. } else if (rule.indexOf('L') >= 0) {
  411. dayRule.value = 'lastDay';
  412. dayRuleSup.value = 'null';
  413. dateArr.value[3] = [31];
  414. } else if (rule !== '*' && rule !== '?') {
  415. dateArr.value[3] = getAssignArr(rule)
  416. dayRuleSup.value = 'null';
  417. } else if (rule === '*') {
  418. dayRuleSup.value = 'null';
  419. }
  420. }
  421. // 获取"时"数组
  422. function getHourArr(rule) {
  423. dateArr.value[2] = getOrderArr(0, 23);
  424. if (rule.indexOf('-') >= 0) {
  425. dateArr.value[2] = getCycleArr(rule, 24, true)
  426. } else if (rule.indexOf('/') >= 0) {
  427. dateArr.value[2] = getAverageArr(rule, 23)
  428. } else if (rule !== '*') {
  429. dateArr.value[2] = getAssignArr(rule)
  430. }
  431. }
  432. // 获取"分"数组
  433. function getMinArr(rule) {
  434. dateArr.value[1] = getOrderArr(0, 59);
  435. if (rule.indexOf('-') >= 0) {
  436. dateArr.value[1] = getCycleArr(rule, 60, true)
  437. } else if (rule.indexOf('/') >= 0) {
  438. dateArr.value[1] = getAverageArr(rule, 59)
  439. } else if (rule !== '*') {
  440. dateArr.value[1] = getAssignArr(rule)
  441. }
  442. }
  443. // 获取"秒"数组
  444. function getSecondArr(rule) {
  445. dateArr.value[0] = getOrderArr(0, 59);
  446. if (rule.indexOf('-') >= 0) {
  447. dateArr.value[0] = getCycleArr(rule, 60, true)
  448. } else if (rule.indexOf('/') >= 0) {
  449. dateArr.value[0] = getAverageArr(rule, 59)
  450. } else if (rule !== '*') {
  451. dateArr.value[0] = getAssignArr(rule)
  452. }
  453. }
  454. // 根据传进来的min-max返回一个顺序的数组
  455. function getOrderArr(min, max) {
  456. let arr = [];
  457. for (let i = min; i <= max; i++) {
  458. arr.push(i);
  459. }
  460. return arr;
  461. }
  462. // 根据规则中指定的零散值返回一个数组
  463. function getAssignArr(rule) {
  464. let arr = [];
  465. let assiginArr = rule.split(',');
  466. for (let i = 0; i < assiginArr.length; i++) {
  467. arr[i] = Number(assiginArr[i])
  468. }
  469. arr.sort(compare)
  470. return arr;
  471. }
  472. // 根据一定算术规则计算返回一个数组
  473. function getAverageArr(rule, limit) {
  474. let arr = [];
  475. let agArr = rule.split('/');
  476. let min = Number(agArr[0]);
  477. let step = Number(agArr[1]);
  478. while (min <= limit) {
  479. arr.push(min);
  480. min += step;
  481. }
  482. return arr;
  483. }
  484. // 根据规则返回一个具有周期性的数组
  485. function getCycleArr(rule, limit, status) {
  486. // status--表示是否从0开始(则从1开始)
  487. let arr = [];
  488. let cycleArr = rule.split('-');
  489. let min = Number(cycleArr[0]);
  490. let max = Number(cycleArr[1]);
  491. if (min > max) {
  492. max += limit;
  493. }
  494. for (let i = min; i <= max; i++) {
  495. let add = 0;
  496. if (status === false && i % limit === 0) {
  497. add = limit;
  498. }
  499. arr.push(Math.round(i % limit + add))
  500. }
  501. arr.sort(compare)
  502. return arr;
  503. }
  504. // 比较数字大小(用于Array.sort)
  505. function compare(value1, value2) {
  506. if (value2 - value1 > 0) {
  507. return -1;
  508. } else {
  509. return 1;
  510. }
  511. }
  512. // 格式化日期格式如:2017-9-19 18:04:33
  513. function formatDate(value, type) {
  514. // 计算日期相关值
  515. let time = typeof value == 'number' ? new Date(value) : value;
  516. let Y = time.getFullYear();
  517. let M = time.getMonth() + 1;
  518. let D = time.getDate();
  519. let h = time.getHours();
  520. let m = time.getMinutes();
  521. let s = time.getSeconds();
  522. let week = time.getDay();
  523. // 如果传递了type的话
  524. if (type === undefined) {
  525. 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);
  526. } else if (type === 'week') {
  527. // 在quartz中 1为星期日
  528. return week + 1;
  529. }
  530. }
  531. // 检查日期是否存在
  532. function checkDate(value) {
  533. let time = new Date(value);
  534. let format = formatDate(time)
  535. return value === format;
  536. }
  537. onMounted(() => {
  538. expressionChange()
  539. })
  540. </script>