<template>
  <view class="tn-code-class tn-code">
    
  </view>
</template>

<script>
  export default {
    name: 'tn-verification-code',
    props: {
      // 倒计时总秒数
      seconds: {
        type: Number,
        default: 60
      },
      // 开始时提示文字
      startText: {
        type: String,
        default: '获取验证码'
      },
      // 倒计时提示文字
      countDownText: {
        type: String,
        default: 's秒后重新获取'
      },
      // 结束时提示文字
      endText: {
        type: String,
        default: '重新获取'
      },
      // 是否在H5刷新或各端返回再进入时继续倒计时
      keepRunning: {
      	type: Boolean,
      	default: false
      },
      // 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了
      uniqueKey: {
      	type: String,
      	default: ''
      }
    },
    data() {
      return {
        timer: null,
        secNum: this.seconds,
        // 是否可以执行验证码操作
        canGetCode: true
      }
    },
    watch: {
      seconds: {
        handler(n) {
          this.secNum = n
        },
        immediate: true
      }
    },
    mounted() {
      this.checkKeepRunning()
    },
    beforeDestroy() {
      this.setTimeToStorage()
      if (this.timer) {
        clearInterval(this.timer)
        this.timer = null
      }
    },
    methods: {
      // 检查是否继续运行
      checkKeepRunning() {
        // 获取上一次退出页面时的时间戳,如果没有上次保存,该值为空
        let lastTimestamp = Number(uni.getStorageSync(this.uniqueKey + '_$tCountDownTimestamp'))
        if (!lastTimestamp) return this.changeEvent(this.startText)
        // 当前秒的时间戳
        // + new Date() 相当于 new Date().getTime()
        let nowTimestamp = Math.floor((+ new Date()) / 1000)
        // 判断当前的时间戳,是否小于上一次的设定结束的时间,提前于结束的时间戳
        if (this.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) {
          // 剩余尚未执行完倒计时秒数
          this.secNum = lastTimestamp - nowTimestamp
          // 清除本地保存的变量
          uni.removeStorageSync(this.uniqueKey + '_$tCountDownTimestamp')
          // 开始倒计时
          this.start()
        } else {
          // 如果不存在需要继续上一次的倒计时,执行正常的逻辑
          this.changeEvent(this.startText);
        }
      },
      // 开始倒计时
      start() {
        // 防止快速点击获取验证码按钮导致产生多个定时器导致混乱
        if (this.timer) {
          clearInterval(this.timer)
          this.timer = null
        }
        this.$emit('start')
        this.canGetCode = false
        
        this.changeEvent(this.countDownText.replace(/s|S/, this.secNum))
        this.setTimeToStorage()
        this.timer = setInterval(() => {
          if (--this.secNum) {
            this.changeEvent(this.countDownText.replace(/s|S/, this.secNum))
          } else {
            // 倒计时结束,清空定时器、重置提示信息
            this.reset()
            this.$emit('end')
          }
        }, 1000)
      },
      // 重置倒计时
      reset() {
        this.canGetCode = true
        if (this.timer) {
          clearInterval(this.timer)
          this.timer = null
        }
        this.secNum = this.seconds
        this.changeEvent(this.endText)
      },
      // 倒计时改变事件
      changeEvent(text) {
        this.$emit('change', text)
      },
      // 保存当前时间戳
      // 防止倒计时尚未结束,H5刷新或者各端的右上角返回上一页再进来
      setTimeToStorage() {
        if (!this.keepRunning ||!this.timer) return
        // 记录当前的时间戳,为了下次进入页面,如果还在倒计时内的话,继续倒计时
        // 倒计时尚未结束,结果大于0;倒计时已经开始,就会小于初始值,如果等于初始值,说明没有开始倒计时,无需处理
        if (this.secNum > 0 && this.secNum <= this.seconds) {
          let nowTimestamp = Math.floor((+ new Date()) / 1000)
          // 保存本次倒计时结束时候的时间戳
          uni.setStorageSync(this.uniqueKey + '_$tCountDownTimestamp', nowTimestamp + this.secNum)
        }
      }
    }
  }
</script>

<style lang="scss" scoped>
  .tn-code {
    width: 0;
    height: 0;
    position: fixed;
    z-index: -1;
  }
</style>