<template> 
 | 
  <div> 
 | 
    <el-tabs type="border-card"> 
 | 
      <el-tab-pane label="秒" v-if="shouldHide('second')"> 
 | 
        <CrontabSecond @update="updateCrontabValue" :check="checkNumber" ref="cronsecond" /> 
 | 
      </el-tab-pane> 
 | 
  
 | 
      <el-tab-pane label="分钟" v-if="shouldHide('min')"> 
 | 
        <CrontabMin 
 | 
          @update="updateCrontabValue" 
 | 
          :check="checkNumber" 
 | 
          :cron="crontabValueObj" 
 | 
          ref="cronmin" 
 | 
        /> 
 | 
      </el-tab-pane> 
 | 
  
 | 
      <el-tab-pane label="小时" v-if="shouldHide('hour')"> 
 | 
        <CrontabHour 
 | 
          @update="updateCrontabValue" 
 | 
          :check="checkNumber" 
 | 
          :cron="crontabValueObj" 
 | 
          ref="cronhour" 
 | 
        /> 
 | 
      </el-tab-pane> 
 | 
  
 | 
      <el-tab-pane label="日" v-if="shouldHide('day')"> 
 | 
        <CrontabDay 
 | 
          @update="updateCrontabValue" 
 | 
          :check="checkNumber" 
 | 
          :cron="crontabValueObj" 
 | 
          ref="cronday" 
 | 
        /> 
 | 
      </el-tab-pane> 
 | 
  
 | 
      <el-tab-pane label="月" v-if="shouldHide('month')"> 
 | 
        <CrontabMonth 
 | 
          @update="updateCrontabValue" 
 | 
          :check="checkNumber" 
 | 
          :cron="crontabValueObj" 
 | 
          ref="cronmonth" 
 | 
        /> 
 | 
      </el-tab-pane> 
 | 
  
 | 
      <el-tab-pane label="周" v-if="shouldHide('week')"> 
 | 
        <CrontabWeek 
 | 
          @update="updateCrontabValue" 
 | 
          :check="checkNumber" 
 | 
          :cron="crontabValueObj" 
 | 
          ref="cronweek" 
 | 
        /> 
 | 
      </el-tab-pane> 
 | 
  
 | 
      <el-tab-pane label="年" v-if="shouldHide('year')"> 
 | 
        <CrontabYear 
 | 
          @update="updateCrontabValue" 
 | 
          :check="checkNumber" 
 | 
          :cron="crontabValueObj" 
 | 
          ref="cronyear" 
 | 
        /> 
 | 
      </el-tab-pane> 
 | 
    </el-tabs> 
 | 
  
 | 
    <div class="popup-main"> 
 | 
      <div class="popup-result"> 
 | 
        <p class="title">时间表达式</p> 
 | 
        <table> 
 | 
          <thead> 
 | 
            <th v-for="item of tabTitles" width="40" :key="item">{{item}}</th> 
 | 
            <th>Cron 表达式</th> 
 | 
          </thead> 
 | 
          <tbody> 
 | 
            <td> 
 | 
              <span>{{crontabValueObj.second}}</span> 
 | 
            </td> 
 | 
            <td> 
 | 
              <span>{{crontabValueObj.min}}</span> 
 | 
            </td> 
 | 
            <td> 
 | 
              <span>{{crontabValueObj.hour}}</span> 
 | 
            </td> 
 | 
            <td> 
 | 
              <span>{{crontabValueObj.day}}</span> 
 | 
            </td> 
 | 
            <td> 
 | 
              <span>{{crontabValueObj.month}}</span> 
 | 
            </td> 
 | 
            <td> 
 | 
              <span>{{crontabValueObj.week}}</span> 
 | 
            </td> 
 | 
            <td> 
 | 
              <span>{{crontabValueObj.year}}</span> 
 | 
            </td> 
 | 
            <td> 
 | 
              <span>{{crontabValueString}}</span> 
 | 
            </td> 
 | 
          </tbody> 
 | 
        </table> 
 | 
      </div> 
 | 
      <CrontabResult :ex="crontabValueString"></CrontabResult> 
 | 
  
 | 
      <div class="pop_btn"> 
 | 
        <el-button size="small" type="primary" @click="submitFill">确定</el-button> 
 | 
        <el-button size="small" type="warning" @click="clearCron">重置</el-button> 
 | 
        <el-button size="small" @click="hidePopup">取消</el-button> 
 | 
      </div> 
 | 
    </div> 
 | 
  </div> 
 | 
</template> 
 | 
  
 | 
<script> 
 | 
import CrontabSecond from "./second.vue"; 
 | 
import CrontabMin from "./min.vue"; 
 | 
import CrontabHour from "./hour.vue"; 
 | 
import CrontabDay from "./day.vue"; 
 | 
import CrontabMonth from "./month.vue"; 
 | 
import CrontabWeek from "./week.vue"; 
 | 
import CrontabYear from "./year.vue"; 
 | 
import CrontabResult from "./result.vue"; 
 | 
  
 | 
export default { 
 | 
  data() { 
 | 
    return { 
 | 
      tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"], 
 | 
      tabActive: 0, 
 | 
      myindex: 0, 
 | 
      crontabValueObj: { 
 | 
        second: "*", 
 | 
        min: "*", 
 | 
        hour: "*", 
 | 
        day: "*", 
 | 
        month: "*", 
 | 
        week: "?", 
 | 
        year: "", 
 | 
      }, 
 | 
    }; 
 | 
  }, 
 | 
  name: "vcrontab", 
 | 
  props: ["expression", "hideComponent"], 
 | 
  methods: { 
 | 
    shouldHide(key) { 
 | 
      if (this.hideComponent && this.hideComponent.includes(key)) return false; 
 | 
      return true; 
 | 
    }, 
 | 
    resolveExp() { 
 | 
      // 反解析 表达式 
 | 
      if (this.expression) { 
 | 
        let arr = this.expression.split(" "); 
 | 
        if (arr.length >= 6) { 
 | 
          //6 位以上是合法表达式 
 | 
          let obj = { 
 | 
            second: arr[0], 
 | 
            min: arr[1], 
 | 
            hour: arr[2], 
 | 
            day: arr[3], 
 | 
            month: arr[4], 
 | 
            week: arr[5], 
 | 
            year: arr[6] ? arr[6] : "", 
 | 
          }; 
 | 
          this.crontabValueObj = { 
 | 
            ...obj, 
 | 
          }; 
 | 
          for (let i in obj) { 
 | 
            if (obj[i]) this.changeRadio(i, obj[i]); 
 | 
          } 
 | 
        } 
 | 
      } else { 
 | 
        // 没有传入的表达式 则还原 
 | 
        this.clearCron(); 
 | 
      } 
 | 
    }, 
 | 
    // tab切换值 
 | 
    tabCheck(index) { 
 | 
      this.tabActive = index; 
 | 
    }, 
 | 
    // 由子组件触发,更改表达式组成的字段值 
 | 
    updateCrontabValue(name, value, from) { 
 | 
      "updateCrontabValue", name, value, from; 
 | 
      this.crontabValueObj[name] = value; 
 | 
      if (from && from !== name) { 
 | 
        console.log(`来自组件 ${from} 改变了 ${name} ${value}`); 
 | 
        this.changeRadio(name, value); 
 | 
      } 
 | 
    }, 
 | 
    // 赋值到组件 
 | 
    changeRadio(name, value) { 
 | 
      let arr = ["second", "min", "hour", "month"], 
 | 
        refName = "cron" + name, 
 | 
        insValue; 
 | 
  
 | 
      if (!this.$refs[refName]) return; 
 | 
  
 | 
      if (arr.includes(name)) { 
 | 
        if (value === "*") { 
 | 
          insValue = 1; 
 | 
        } else if (value.indexOf("-") > -1) { 
 | 
          let indexArr = value.split("-"); 
 | 
          isNaN(indexArr[0]) 
 | 
            ? (this.$refs[refName].cycle01 = 0) 
 | 
            : (this.$refs[refName].cycle01 = indexArr[0]); 
 | 
          this.$refs[refName].cycle02 = indexArr[1]; 
 | 
          insValue = 2; 
 | 
        } else if (value.indexOf("/") > -1) { 
 | 
          let indexArr = value.split("/"); 
 | 
          isNaN(indexArr[0]) 
 | 
            ? (this.$refs[refName].average01 = 0) 
 | 
            : (this.$refs[refName].average01 = indexArr[0]); 
 | 
          this.$refs[refName].average02 = indexArr[1]; 
 | 
          insValue = 3; 
 | 
        } else { 
 | 
          insValue = 4; 
 | 
          this.$refs[refName].checkboxList = value.split(","); 
 | 
        } 
 | 
      } else if (name == "day") { 
 | 
        if (value === "*") { 
 | 
          insValue = 1; 
 | 
        } else if (value == "?") { 
 | 
          insValue = 2; 
 | 
        } else if (value.indexOf("-") > -1) { 
 | 
          let indexArr = value.split("-"); 
 | 
          isNaN(indexArr[0]) 
 | 
            ? (this.$refs[refName].cycle01 = 0) 
 | 
            : (this.$refs[refName].cycle01 = indexArr[0]); 
 | 
          this.$refs[refName].cycle02 = indexArr[1]; 
 | 
          insValue = 3; 
 | 
        } else if (value.indexOf("/") > -1) { 
 | 
          let indexArr = value.split("/"); 
 | 
          isNaN(indexArr[0]) 
 | 
            ? (this.$refs[refName].average01 = 0) 
 | 
            : (this.$refs[refName].average01 = indexArr[0]); 
 | 
          this.$refs[refName].average02 = indexArr[1]; 
 | 
          insValue = 4; 
 | 
        } else if (value.indexOf("W") > -1) { 
 | 
          let indexArr = value.split("W"); 
 | 
          isNaN(indexArr[0]) 
 | 
            ? (this.$refs[refName].workday = 0) 
 | 
            : (this.$refs[refName].workday = indexArr[0]); 
 | 
          insValue = 5; 
 | 
        } else if (value === "L") { 
 | 
          insValue = 6; 
 | 
        } else { 
 | 
          this.$refs[refName].checkboxList = value.split(","); 
 | 
          insValue = 7; 
 | 
        } 
 | 
      } else if (name == "week") { 
 | 
        if (value === "*") { 
 | 
          insValue = 1; 
 | 
        } else if (value == "?") { 
 | 
          insValue = 2; 
 | 
        } else if (value.indexOf("-") > -1) { 
 | 
          let indexArr = value.split("-"); 
 | 
          isNaN(indexArr[0]) 
 | 
            ? (this.$refs[refName].cycle01 = 0) 
 | 
            : (this.$refs[refName].cycle01 = indexArr[0]); 
 | 
          this.$refs[refName].cycle02 = indexArr[1]; 
 | 
          insValue = 3; 
 | 
        } else if (value.indexOf("#") > -1) { 
 | 
          let indexArr = value.split("#"); 
 | 
          isNaN(indexArr[0]) 
 | 
            ? (this.$refs[refName].average01 = 1) 
 | 
            : (this.$refs[refName].average01 = indexArr[0]); 
 | 
          this.$refs[refName].average02 = indexArr[1]; 
 | 
          insValue = 4; 
 | 
        } else if (value.indexOf("L") > -1) { 
 | 
          let indexArr = value.split("L"); 
 | 
          isNaN(indexArr[0]) 
 | 
            ? (this.$refs[refName].weekday = 1) 
 | 
            : (this.$refs[refName].weekday = indexArr[0]); 
 | 
          insValue = 5; 
 | 
        } else { 
 | 
          this.$refs[refName].checkboxList = value.split(","); 
 | 
          insValue = 7; 
 | 
        } 
 | 
      } else if (name == "year") { 
 | 
        if (value == "") { 
 | 
          insValue = 1; 
 | 
        } else if (value == "*") { 
 | 
          insValue = 2; 
 | 
        } else if (value.indexOf("-") > -1) { 
 | 
          insValue = 3; 
 | 
        } else if (value.indexOf("/") > -1) { 
 | 
          insValue = 4; 
 | 
        } else { 
 | 
          this.$refs[refName].checkboxList = value.split(","); 
 | 
          insValue = 5; 
 | 
        } 
 | 
      } 
 | 
      this.$refs[refName].radioValue = insValue; 
 | 
    }, 
 | 
    // 表单选项的子组件校验数字格式(通过-props传递) 
 | 
    checkNumber(value, minLimit, maxLimit) { 
 | 
      // 检查必须为整数 
 | 
      value = Math.floor(value); 
 | 
      if (value < minLimit) { 
 | 
        value = minLimit; 
 | 
      } else if (value > maxLimit) { 
 | 
        value = maxLimit; 
 | 
      } 
 | 
      return value; 
 | 
    }, 
 | 
    // 隐藏弹窗 
 | 
    hidePopup() { 
 | 
      this.$emit("hide"); 
 | 
    }, 
 | 
    // 填充表达式 
 | 
    submitFill() { 
 | 
      this.$emit("fill", this.crontabValueString); 
 | 
      this.hidePopup(); 
 | 
    }, 
 | 
    clearCron() { 
 | 
      // 还原选择项 
 | 
      ("准备还原"); 
 | 
      this.crontabValueObj = { 
 | 
        second: "*", 
 | 
        min: "*", 
 | 
        hour: "*", 
 | 
        day: "*", 
 | 
        month: "*", 
 | 
        week: "?", 
 | 
        year: "", 
 | 
      }; 
 | 
      for (let j in this.crontabValueObj) { 
 | 
        this.changeRadio(j, this.crontabValueObj[j]); 
 | 
      } 
 | 
    }, 
 | 
  }, 
 | 
  computed: { 
 | 
    crontabValueString: function() { 
 | 
      let obj = this.crontabValueObj; 
 | 
      let str = 
 | 
        obj.second + 
 | 
        " " + 
 | 
        obj.min + 
 | 
        " " + 
 | 
        obj.hour + 
 | 
        " " + 
 | 
        obj.day + 
 | 
        " " + 
 | 
        obj.month + 
 | 
        " " + 
 | 
        obj.week + 
 | 
        (obj.year == "" ? "" : " " + obj.year); 
 | 
      return str; 
 | 
    }, 
 | 
  }, 
 | 
  components: { 
 | 
    CrontabSecond, 
 | 
    CrontabMin, 
 | 
    CrontabHour, 
 | 
    CrontabDay, 
 | 
    CrontabMonth, 
 | 
    CrontabWeek, 
 | 
    CrontabYear, 
 | 
    CrontabResult, 
 | 
  }, 
 | 
  watch: { 
 | 
    expression: "resolveExp", 
 | 
    hideComponent(value) { 
 | 
      // 隐藏部分组件 
 | 
    }, 
 | 
  }, 
 | 
  mounted: function() { 
 | 
    this.resolveExp(); 
 | 
  }, 
 | 
}; 
 | 
</script> 
 | 
<style scoped> 
 | 
.pop_btn { 
 | 
  text-align: center; 
 | 
  margin-top: 20px; 
 | 
} 
 | 
.popup-main { 
 | 
  position: relative; 
 | 
  margin: 10px auto; 
 | 
  background: #fff; 
 | 
  border-radius: 5px; 
 | 
  font-size: 12px; 
 | 
  overflow: hidden; 
 | 
} 
 | 
.popup-title { 
 | 
  overflow: hidden; 
 | 
  line-height: 34px; 
 | 
  padding-top: 6px; 
 | 
  background: #f2f2f2; 
 | 
} 
 | 
.popup-result { 
 | 
  box-sizing: border-box; 
 | 
  line-height: 24px; 
 | 
  margin: 25px auto; 
 | 
  padding: 15px 10px 10px; 
 | 
  border: 1px solid #ccc; 
 | 
  position: relative; 
 | 
} 
 | 
.popup-result .title { 
 | 
  position: absolute; 
 | 
  top: -28px; 
 | 
  left: 50%; 
 | 
  width: 140px; 
 | 
  font-size: 14px; 
 | 
  margin-left: -70px; 
 | 
  text-align: center; 
 | 
  line-height: 30px; 
 | 
  background: #fff; 
 | 
} 
 | 
.popup-result table { 
 | 
  text-align: center; 
 | 
  width: 100%; 
 | 
  margin: 0 auto; 
 | 
} 
 | 
.popup-result table span { 
 | 
  display: block; 
 | 
  width: 100%; 
 | 
  font-family: arial; 
 | 
  line-height: 30px; 
 | 
  height: 30px; 
 | 
  white-space: nowrap; 
 | 
  overflow: hidden; 
 | 
  border: 1px solid #e8e8e8; 
 | 
} 
 | 
.popup-result-scroll { 
 | 
  font-size: 12px; 
 | 
  line-height: 24px; 
 | 
  height: 10em; 
 | 
  overflow-y: auto; 
 | 
} 
 | 
</style> 
 |