<!--
  @description: 倒计时组件
  @Modifier: haoFx
  @routerPath:
  @date: 2020/3/18-22:44
-->
<template>
  <div>
    <div v-if="msTime.show" class="countdown">
      <p v-if="msTime.day>0">
        <span>{{ msTime.day }}</span>
        <i class="dateText">天</i>
      </p>
      <span>{{ msTime.hour[0] }}</span>
      <span>{{ msTime.hour[1] }}</span>
      <i class="dateText">时</i>
      <span>{{ msTime.minutes[0] }}</span>
      <span>{{ msTime.minutes[1] }}</span>
      <i class="dateText">分</i>
      <span>{{ msTime.seconds[0] }}</span>
      <span>{{ msTime.seconds[1] }}</span>
      <i class="dateText">秒</i>
    </div>
    <p v-if="!msTime.show">
      {{ endText }}
    </p>
  </div>
</template>

<script>
export default {
  name: 'Countdown',
  props: {
    // 当前时间
    sysCurrentTime: {
      type: String | Number,
      default: ''
    },
    // 活动结束时间
    endTime: {
      type: String,
      default: ''
    },
    // 倒计时结束显示文本
    endText: {
      type: String,
      default: '倒计时结束'
    },
    // 今日标段列表下标
    index: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      msTime: {			// 倒计时数值
        show: false,		// 倒计时状态
        day: '',			// 天
        hour: '',		// 小时
        minutes: '',		// 分钟
        seconds: ''		// 秒
      },
      startTime: '',
      count: 0 // 标记执行次数
    }
  },
  watch: {
    sysCurrentTime(val) {
      if (val) {
        this.setTimeToReStart()
      }
    }
  },
  created() {
    this.startTime = new Date().getTime()
    this.setTimeToReStart()
  },
  beforeDestroy() {
    clearTimeout(this.timer)
  },
  methods: {
    setTimeToReStart() {
      let endTime = '' // 活动结束时间
      let currentTime = '' // 系统当前时间
      // 活动结束时间-处理ie不兼容日期格式
      endTime = this.endTime.replace(/-/g, '/')
      // 活动结束时间-转换时间戳
      endTime = new Date(endTime).getTime()
      // 系统当前时间
      if (this.sysCurrentTime) {
        // 系统当前时间-处理ie不兼容日期格式
        currentTime = this.sysCurrentTime.replace(/-/g, '/')
        // 系统当前时间-转换时间戳
        currentTime = new Date(currentTime).getTime()
        // 启动倒计时
        const data = {
          endTime, // 活动结束时间
          currentTime, // 当前系统时间
          index: this.index, // 索引
          endCallBack: this.end_callBack // 倒计时结束回调
        }
        this.runTime(data)
        setTimeout(() => {
          this.runTime(data)
        }, 1000)
      }
    },
    runTime(data) {
      const { endTime, currentTime } = data
      const msTime = this.msTime
      const interval = 1000 // 设定倒计时标准间隔差
      this.count++
      let offset = new Date().getTime() - (this.startTime + this.count * interval) // 计算误差
      if (offset > interval) { // 若误差超过间隔时间，则立即校正(会出现跳秒的情况)
        data.currentTime += Math.floor(offset / interval) * interval
        this.count += Math.floor(offset / interval)
        offset = offset % interval
      }
      let nextTime = interval - offset // 标准时间间隔减去此次的误差，为下一次执行的时间
      if (nextTime < 0) {
        nextTime = 0
      }
      let timeDistance = endTime - currentTime
      if (timeDistance > 0) {
        this.msTime.show = true
        // 计算时间
        // 天
        msTime.day = Math.floor(timeDistance / 86400000)
        timeDistance -= msTime.day * 86400000
        // 时
        msTime.hour = Math.floor(timeDistance / 3600000)
        timeDistance -= msTime.hour * 3600000
        // 分
        msTime.minutes = Math.floor(timeDistance / 60000)
        timeDistance -= msTime.minutes * 60000
        // 秒
        msTime.seconds = Math.floor(timeDistance / 1000).toFixed(0)
        timeDistance -= msTime.seconds * 1000
        // 判断是否小于 10 如果小于0 则加 '0'
        if (msTime.hour < 10) msTime.hour = '0' + msTime.hour
        if (msTime.minutes < 10) msTime.minutes = '0' + msTime.minutes
        if (msTime.seconds < 10) msTime.seconds = '0' + msTime.seconds
        msTime.hour = msTime.hour + ''
        msTime.minutes = msTime.minutes + ''
        // 启动倒计时
        data.currentTime += interval
        this.timer = setTimeout(() => {
          this.runTime(data)
        }, nextTime)
      } else {
        data.endCallBack(data)
      }
    },
    end_callBack(data) {
      this.msTime.show = false
      this.$emit('end_callback', this.msTime.show, data.index)
      clearTimeout(this.timer)
      if (this.sysCurrentTime <= 0) {
        return
      }
    }
  }
}
</script>

<style scoped lang="less">
  // 时间倒计时样式
  .countdown{
    display: inline-block;
    p{
      display: inline-block;
    }
    span{
      background: linear-gradient(to bottom, #45484d 0%,#000000 100%);
      color: white;
      border-radius: 2px;
      font-size: 16px;
      padding: 0 5px;
    }
    span+span{
      margin-left: 2px;
    }
    .dateText{
      font-style: normal;
      margin: 0 5px;
    }
  }
</style>
