懒羊羊
2024-01-31 e57a8990ae56f657a59c435a0613c5f7a8728003
提交 | 用户 | 时间
e57a89 1 <template>
2   <div>
3     <el-tabs type="border-card">
4       <el-tab-pane label="秒" v-if="shouldHide('second')">
5         <CrontabSecond
6           @update="updateCrontabValue"
7           :check="checkNumber"
8           :cron="crontabValueObj"
9           ref="cronsecond"
10         />
11       </el-tab-pane>
12
13       <el-tab-pane label="分钟" v-if="shouldHide('min')">
14         <CrontabMin
15           @update="updateCrontabValue"
16           :check="checkNumber"
17           :cron="crontabValueObj"
18           ref="cronmin"
19         />
20       </el-tab-pane>
21
22       <el-tab-pane label="小时" v-if="shouldHide('hour')">
23         <CrontabHour
24           @update="updateCrontabValue"
25           :check="checkNumber"
26           :cron="crontabValueObj"
27           ref="cronhour"
28         />
29       </el-tab-pane>
30
31       <el-tab-pane label="日" v-if="shouldHide('day')">
32         <CrontabDay
33           @update="updateCrontabValue"
34           :check="checkNumber"
35           :cron="crontabValueObj"
36           ref="cronday"
37         />
38       </el-tab-pane>
39
40       <el-tab-pane label="月" v-if="shouldHide('month')">
41         <CrontabMonth
42           @update="updateCrontabValue"
43           :check="checkNumber"
44           :cron="crontabValueObj"
45           ref="cronmonth"
46         />
47       </el-tab-pane>
48
49       <el-tab-pane label="周" v-if="shouldHide('week')">
50         <CrontabWeek
51           @update="updateCrontabValue"
52           :check="checkNumber"
53           :cron="crontabValueObj"
54           ref="cronweek"
55         />
56       </el-tab-pane>
57
58       <el-tab-pane label="年" v-if="shouldHide('year')">
59         <CrontabYear
60           @update="updateCrontabValue"
61           :check="checkNumber"
62           :cron="crontabValueObj"
63           ref="cronyear"
64         />
65       </el-tab-pane>
66     </el-tabs>
67
68     <div class="popup-main">
69       <div class="popup-result">
70         <p class="title">时间表达式</p>
71         <table>
72           <thead>
73             <th v-for="item of tabTitles" width="40" :key="item">{{item}}</th>
74             <th>Cron 表达式</th>
75           </thead>
76           <tbody>
77             <td>
78               <span>{{crontabValueObj.second}}</span>
79             </td>
80             <td>
81               <span>{{crontabValueObj.min}}</span>
82             </td>
83             <td>
84               <span>{{crontabValueObj.hour}}</span>
85             </td>
86             <td>
87               <span>{{crontabValueObj.day}}</span>
88             </td>
89             <td>
90               <span>{{crontabValueObj.month}}</span>
91             </td>
92             <td>
93               <span>{{crontabValueObj.week}}</span>
94             </td>
95             <td>
96               <span>{{crontabValueObj.year}}</span>
97             </td>
98             <td>
99               <span>{{crontabValueString}}</span>
100             </td>
101           </tbody>
102         </table>
103       </div>
104       <CrontabResult :ex="crontabValueString"></CrontabResult>
105
106       <div class="pop_btn">
107         <el-button size="small" type="primary" @click="submitFill">确定</el-button>
108         <el-button size="small" type="warning" @click="clearCron">重置</el-button>
109         <el-button size="small" @click="hidePopup">取消</el-button>
110       </div>
111     </div>
112   </div>
113 </template>
114
115 <script>
116 import CrontabSecond from "./second.vue";
117 import CrontabMin from "./min.vue";
118 import CrontabHour from "./hour.vue";
119 import CrontabDay from "./day.vue";
120 import CrontabMonth from "./month.vue";
121 import CrontabWeek from "./week.vue";
122 import CrontabYear from "./year.vue";
123 import CrontabResult from "./result.vue";
124
125 export default {
126   data() {
127     return {
128       tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"],
129       tabActive: 0,
130       myindex: 0,
131       crontabValueObj: {
132         second: "*",
133         min: "*",
134         hour: "*",
135         day: "*",
136         month: "*",
137         week: "?",
138         year: "",
139       },
140     };
141   },
142   name: "vcrontab",
143   props: ["expression", "hideComponent"],
144   methods: {
145     shouldHide(key) {
146       if (this.hideComponent && this.hideComponent.includes(key)) return false;
147       return true;
148     },
149     resolveExp() {
150       // 反解析 表达式
151       if (this.expression) {
152         let arr = this.expression.split(" ");
153         if (arr.length >= 6) {
154           //6 位以上是合法表达式
155           let obj = {
156             second: arr[0],
157             min: arr[1],
158             hour: arr[2],
159             day: arr[3],
160             month: arr[4],
161             week: arr[5],
162             year: arr[6] ? arr[6] : "",
163           };
164           this.crontabValueObj = {
165             ...obj,
166           };
167           for (let i in obj) {
168             if (obj[i]) this.changeRadio(i, obj[i]);
169           }
170         }
171       } else {
172         // 没有传入的表达式 则还原
173         this.clearCron();
174       }
175     },
176     // tab切换值
177     tabCheck(index) {
178       this.tabActive = index;
179     },
180     // 由子组件触发,更改表达式组成的字段值
181     updateCrontabValue(name, value, from) {
182       "updateCrontabValue", name, value, from;
183       this.crontabValueObj[name] = value;
184       if (from && from !== name) {
185         console.log(`来自组件 ${from} 改变了 ${name} ${value}`);
186         this.changeRadio(name, value);
187       }
188     },
189     // 赋值到组件
190     changeRadio(name, value) {
191       let arr = ["second", "min", "hour", "month"],
192         refName = "cron" + name,
193         insValue;
194
195       if (!this.$refs[refName]) return;
196
197       if (arr.includes(name)) {
198         if (value === "*") {
199           insValue = 1;
200         } else if (value.indexOf("-") > -1) {
201           let indexArr = value.split("-");
202           isNaN(indexArr[0])
203             ? (this.$refs[refName].cycle01 = 0)
204             : (this.$refs[refName].cycle01 = indexArr[0]);
205           this.$refs[refName].cycle02 = indexArr[1];
206           insValue = 2;
207         } else if (value.indexOf("/") > -1) {
208           let indexArr = value.split("/");
209           isNaN(indexArr[0])
210             ? (this.$refs[refName].average01 = 0)
211             : (this.$refs[refName].average01 = indexArr[0]);
212           this.$refs[refName].average02 = indexArr[1];
213           insValue = 3;
214         } else {
215           insValue = 4;
216           this.$refs[refName].checkboxList = value.split(",");
217         }
218       } else if (name == "day") {
219         if (value === "*") {
220           insValue = 1;
221         } else if (value == "?") {
222           insValue = 2;
223         } else if (value.indexOf("-") > -1) {
224           let indexArr = value.split("-");
225           isNaN(indexArr[0])
226             ? (this.$refs[refName].cycle01 = 0)
227             : (this.$refs[refName].cycle01 = indexArr[0]);
228           this.$refs[refName].cycle02 = indexArr[1];
229           insValue = 3;
230         } else if (value.indexOf("/") > -1) {
231           let indexArr = value.split("/");
232           isNaN(indexArr[0])
233             ? (this.$refs[refName].average01 = 0)
234             : (this.$refs[refName].average01 = indexArr[0]);
235           this.$refs[refName].average02 = indexArr[1];
236           insValue = 4;
237         } else if (value.indexOf("W") > -1) {
238           let indexArr = value.split("W");
239           isNaN(indexArr[0])
240             ? (this.$refs[refName].workday = 0)
241             : (this.$refs[refName].workday = indexArr[0]);
242           insValue = 5;
243         } else if (value === "L") {
244           insValue = 6;
245         } else {
246           this.$refs[refName].checkboxList = value.split(",");
247           insValue = 7;
248         }
249       } else if (name == "week") {
250         if (value === "*") {
251           insValue = 1;
252         } else if (value == "?") {
253           insValue = 2;
254         } else if (value.indexOf("-") > -1) {
255           let indexArr = value.split("-");
256           isNaN(indexArr[0])
257             ? (this.$refs[refName].cycle01 = 0)
258             : (this.$refs[refName].cycle01 = indexArr[0]);
259           this.$refs[refName].cycle02 = indexArr[1];
260           insValue = 3;
261         } else if (value.indexOf("#") > -1) {
262           let indexArr = value.split("#");
263           isNaN(indexArr[0])
264             ? (this.$refs[refName].average01 = 1)
265             : (this.$refs[refName].average01 = indexArr[0]);
266           this.$refs[refName].average02 = indexArr[1];
267           insValue = 4;
268         } else if (value.indexOf("L") > -1) {
269           let indexArr = value.split("L");
270           isNaN(indexArr[0])
271             ? (this.$refs[refName].weekday = 1)
272             : (this.$refs[refName].weekday = indexArr[0]);
273           insValue = 5;
274         } else {
275           this.$refs[refName].checkboxList = value.split(",");
276           insValue = 6;
277         }
278       } else if (name == "year") {
279         if (value == "") {
280           insValue = 1;
281         } else if (value == "*") {
282           insValue = 2;
283         } else if (value.indexOf("-") > -1) {
284           insValue = 3;
285         } else if (value.indexOf("/") > -1) {
286           insValue = 4;
287         } else {
288           this.$refs[refName].checkboxList = value.split(",");
289           insValue = 5;
290         }
291       }
292       this.$refs[refName].radioValue = insValue;
293     },
294     // 表单选项的子组件校验数字格式(通过-props传递)
295     checkNumber(value, minLimit, maxLimit) {
296       // 检查必须为整数
297       value = Math.floor(value);
298       if (value < minLimit) {
299         value = minLimit;
300       } else if (value > maxLimit) {
301         value = maxLimit;
302       }
303       return value;
304     },
305     // 隐藏弹窗
306     hidePopup() {
307       this.$emit("hide");
308     },
309     // 填充表达式
310     submitFill() {
311       this.$emit("fill", this.crontabValueString);
312       this.hidePopup();
313     },
314     clearCron() {
315       // 还原选择项
316       ("准备还原");
317       this.crontabValueObj = {
318         second: "*",
319         min: "*",
320         hour: "*",
321         day: "*",
322         month: "*",
323         week: "?",
324         year: "",
325       };
326       for (let j in this.crontabValueObj) {
327         this.changeRadio(j, this.crontabValueObj[j]);
328       }
329     },
330   },
331   computed: {
332     crontabValueString: function() {
333       let obj = this.crontabValueObj;
334       let str =
335         obj.second +
336         " " +
337         obj.min +
338         " " +
339         obj.hour +
340         " " +
341         obj.day +
342         " " +
343         obj.month +
344         " " +
345         obj.week +
346         (obj.year == "" ? "" : " " + obj.year);
347       return str;
348     },
349   },
350   components: {
351     CrontabSecond,
352     CrontabMin,
353     CrontabHour,
354     CrontabDay,
355     CrontabMonth,
356     CrontabWeek,
357     CrontabYear,
358     CrontabResult,
359   },
360   watch: {
361     expression: "resolveExp",
362     hideComponent(value) {
363       // 隐藏部分组件
364     },
365   },
366   mounted: function() {
367     this.resolveExp();
368   },
369 };
370 </script>
371 <style scoped>
372 .pop_btn {
373   text-align: center;
374   margin-top: 20px;
375 }
376 .popup-main {
377   position: relative;
378   margin: 10px auto;
379   background: #fff;
380   border-radius: 5px;
381   font-size: 12px;
382   overflow: hidden;
383 }
384 .popup-title {
385   overflow: hidden;
386   line-height: 34px;
387   padding-top: 6px;
388   background: #f2f2f2;
389 }
390 .popup-result {
391   box-sizing: border-box;
392   line-height: 24px;
393   margin: 25px auto;
394   padding: 15px 10px 10px;
395   border: 1px solid #ccc;
396   position: relative;
397 }
398 .popup-result .title {
399   position: absolute;
400   top: -28px;
401   left: 50%;
402   width: 140px;
403   font-size: 14px;
404   margin-left: -70px;
405   text-align: center;
406   line-height: 30px;
407   background: #fff;
408 }
409 .popup-result table {
410   text-align: center;
411   width: 100%;
412   margin: 0 auto;
413 }
414 .popup-result table span {
415   display: block;
416   width: 100%;
417   font-family: arial;
418   line-height: 30px;
419   height: 30px;
420   white-space: nowrap;
421   overflow: hidden;
422   border: 1px solid #e8e8e8;
423 }
424 .popup-result-scroll {
425   font-size: 12px;
426   line-height: 24px;
427   height: 10em;
428   overflow-y: auto;
429 }
430 </style>