<template>
  <view class="lr-datetime-picker">
    <view
      @tap.stop="maskClick"
      @touchmove.stop.prevent
      :class="{ show: showPicker }"
      class="lr-datetime-mask"
      catchtouchmove="true"
    ></view>
    <view :class="{ show: showPicker }" class="lr-datetime-content">
      <view @touchmove.stop.prevent catchtouchmove="true" class="lr-datetime-hd">
        <view @tap.stop="pickerCancel" class="lr-datetime-btn">取消</view>
        <view @tap.stop="pickerConfirm" :style="{ color: color }" class="lr-datetime-btn">确定</view>
      </view>
      <view class="lr-datetime-view">
        <picker-view
          v-if="isAll"
          @change="bindChange"
          :indicator-style="itemHeight"
          :value="values"
          style="height: 100%;"
        >
          <picker-view-column>
            <view v-for="(item, index) in dateObj.years" :key="index" class="lr-datetime-item">{{ item }}年</view>
          </picker-view-column>
          <picker-view-column>
            <view v-for="(item, index) in dateObj.months" :key="index" class="lr-datetime-item">{{ item }}月</view>
          </picker-view-column>
          <picker-view-column>
            <view v-for="(item, index) in dateObj.days" :key="index" class="lr-datetime-item">{{ item }}日</view>
          </picker-view-column>
          <picker-view-column>
            <view v-for="(item, index) in dateObj.hours" :key="index" class="lr-datetime-item">{{ item }}时</view>
          </picker-view-column>
          <picker-view-column>
            <view v-for="(item, index) in dateObj.minutes" :key="index" class="lr-datetime-item">{{ item }}分</view>
          </picker-view-column>
          <picker-view-column>
            <view v-for="(item, index) in dateObj.seconds" :key="index" class="lr-datetime-item">{{ item }}秒</view>
          </picker-view-column>
        </picker-view>
        <picker-view
          v-else
          @change="bindDateChange"
          :indicator-style="itemHeight"
          :value="dateValues"
          style="height: 100%;"
        >
          <picker-view-column class="yu-picker-column">
            <view v-for="(item, index) in dateObj.dates" :key="index" class="lr-datetime-item">{{ item }}</view>
          </picker-view-column>
          <picker-view-column>
            <view v-for="(item, index) in dateObj.hours" :key="index" class="lr-datetime-item">{{ item }}时</view>
          </picker-view-column>
          <picker-view-column>
            <view v-for="(item, index) in dateObj.minutes" :key="index" class="lr-datetime-item">{{ item }}分</view>
          </picker-view-column>
          <picker-view-column>
            <view v-for="(item, index) in dateObj.seconds" :key="index" class="lr-datetime-item">{{ item }}秒</view>
          </picker-view-column>
        </picker-view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'l-datetime-panel',

  props: {
    //全部日期有效可选
    isAll: { default: true },
    //颜色
    color: { default: '#1aad19' },
    //开始年份
    startYear: { default: '1900' },
    //结束年份
    endYear: { default: '2100' },
    //设置默认日期时间
    val: { default: '' }
  },

  data() {
    let date = new Date()
    let year = date.getFullYear()
    let month = date.getMonth() + 1
    let day = date.getDate()
    let hour = date.getHours()
    let minute = date.getMinutes()
    let second = date.getSeconds()
    let dates = []
    let months = []
    let years = []
    let days = []
    let hours = []
    let minutes = []
    let seconds = []
    for (let i = month; i <= month + 2; i++) {
      //获取包括当前月份在内的3个月内的日期
      let localMonth = i
      let localYear = year
      if (i == 13) {
        localYear += 1
      }
      if (i >= 13) {
        localMonth -= 12
      }
      let total = new Date(localYear, localMonth, 0).getDate()
      if (i == month) {
        for (let j = day; j <= total; j++) {
          let m = localMonth
          let d = j
          if (localMonth < 10) {
            m = '0' + m
          }
          if (j < 10) {
            d = '0' + d
          }
          let str = year + '-' + m + '-' + d
          dates.push(str)
        }
      } else {
        for (let j = 1; j <= total; j++) {
          let m = localMonth
          let d = j
          if (localMonth < 10) {
            m = '0' + m
          }
          if (j < 10) {
            d = '0' + d
          }
          let str = year + '-' + m + '-' + d
          dates.push(str)
        }
      }
    }
    for (let i = parseInt(this.startYear); i <= this.endYear; i++) {
      years.push(i)
    }
    for (let i = 1; i <= 12; i++) {
      let str = i
      if (i < 10) {
        str = '0' + str
      } else {
        str = '' + str
      }
      months.push(str)
    }

    if (this.val) {
      let valueArr = this.val.split(' ')
      let valueDateArr = valueArr[0].split('-')
      let totalCurrent = new Date(valueDateArr[0], valueDateArr[1], 0).getDate()
      for (let i = 1; i <= totalCurrent; i++) {
        let str = i
        if (i < 10) {
          str = '0' + str
        } else {
          str = '' + str
        }
        days.push(str)
      }
    } else {
      let totalCurrent = new Date(year, month, 0).getDate()
      for (let i = 1; i <= totalCurrent; i++) {
        let str = i
        if (i < 10) {
          str = '0' + str
        } else {
          str = '' + str
        }
        days.push(str)
      }
    }
    for (let i = 0; i < 24; i++) {
      let str = i
      if (i < 10) {
        str = '0' + str
      } else {
        str = '' + str
      }
      hours.push(str)
    }
    for (let i = 0; i < 60; i++) {
      let str = i
      if (i < 10) {
        str = '0' + str
      } else {
        str = '' + str
      }
      minutes.push(str)
    }
    for (let i = 0; i < 60; i++) {
      let str = i
      if (i < 10) {
        str = '0' + str
      } else {
        str = '' + str
      }
      seconds.push(str)
    }
    let dateObj = {
      dates,
      years,
      months,
      days,
      hours,
      minutes,
      seconds
    }
    return {
      value: this.val,
      year,
      month,
      day,
      hour,
      minute,
      second,
      dateObj,
      itemHeight: `height: ${uni.upx2px(88)}px;`,
      values: [0, 0, 0, 0, 0, 0],
      selectArr: [],
      selectRes: '',
      showPicker: false,
      dateValues: [0, 0, 0, 0]
    }
  },

  mounted() {
    this.setDate()
  },

  methods: {
    setDate(dt) {
      if (dt) {
        this.value = dt
      }

      this.initDate()

      if (!this.value) {
        this.showCurrent()
      }
    },

    initDate() {
      let _this = this
      //解析默认显示的日期时间
      if (_this.value) {
        let values = [0, 0, 0, 0, 0, 0]
        let dateValues = [0, 0, 0, 0]
        let valueStr = _this.value
        let valueArr = valueStr.split(' ')
        let valueDateArr = valueArr[0].split('-')
        let valueTimeArr = valueArr[1].split(':')
        if (_this.isAll) {
          values[0] = valueDateArr[0] - _this.startYear > 0 ? valueDateArr[0] - _this.startYear : 0
          values[1] = parseInt(valueDateArr[1]) - 1
          values[2] = parseInt(valueDateArr[2]) - 1
          values[3] = parseInt(valueTimeArr[0])
          values[4] = parseInt(valueTimeArr[1])
          values[5] = parseInt(valueTimeArr[2])
          _this.$nextTick(() => {
            _this.values = values
          })
          if (valueDateArr[0] - _this.startYear >= 0) {
            _this.selectArr = [
              valueDateArr[0],
              valueDateArr[1],
              valueDateArr[2],
              valueTimeArr[0],
              valueTimeArr[1],
              valueTimeArr[2]
            ]
            _this.selectRes = _this.value
          } else {
            _this.selectArr = [
              _this.formatNum(_this.startYear),
              valueDateArr[1],
              valueDateArr[2],
              valueTimeArr[0],
              valueTimeArr[1],
              valueTimeArr[2]
            ]
            _this.selectRes = `${this.formatNum(_this.startYear) +
              '-' +
              valueDateArr[1] +
              '-' +
              valueDateArr[2] +
              ' ' +
              valueTimeArr[0] +
              ':' +
              valueTimeArr[1] +
              ':' +
              valueTimeArr[2]}`
          }
        } else {
          let str = valueDateArr.join('')
          let localStr = _this.formatNum(_this.year) + _this.formatNum(_this.month) + _this.formatNum(_this.day) + ''
          if (str < localStr) {
            dateValues[0] = 0
            _this.selectArr = [
              _this.formatNum(_this.year),
              _this.formatNum(_this.month),
              _this.formatNum(_this.day),
              valueTimeArr[0],
              valueTimeArr[1],
              valueTimeArr[2]
            ]
            _this.selectRes = `${_this.formatNum(_this.year) +
              '-' +
              _this.formatNum(_this.month) +
              '-' +
              _this.formatNum(_this.day) +
              ' ' +
              valueTimeArr[0] +
              ':' +
              valueTimeArr[1] +
              ':' +
              valueTimeArr[2]}`
          } else {
            let num = 0 //计算默认日期和当前日期相隔天数，计算下标
            let start =
              _this.formatNum(_this.year) + '-' + _this.formatNum(_this.month) + '-' + _this.formatNum(_this.day)
            let res = _this.getBetweenDateStr(start, valueArr[0])
            dateValues[0] = res.length - 1
            _this.selectArr = [
              valueDateArr[0],
              valueDateArr[1],
              valueDateArr[2],
              valueTimeArr[0],
              valueTimeArr[1],
              valueTimeArr[2]
            ]
            _this.selectRes = _this.value
          }
          dateValues[1] = parseInt(valueTimeArr[0])
          dateValues[2] = parseInt(valueTimeArr[1])
          dateValues[3] = parseInt(valueTimeArr[2])
          _this.$nextTick(() => {
            _this.dateValues = dateValues
          })
        }
        return
      }
      if (_this.isAll) {
        _this.selectArr = [_this.formatNum(_this.startYear), '01', '01', '00', '00', '00']
        _this.selectRes = `${_this.formatNum(_this.startYear) + '-01-01 00:00:00'}`
      } else {
        _this.selectArr = [_this.formatNum(_this.year), _this.formatNum(_this.month), '01', '00', '00', '00']
        _this.selectRes = `${_this.formatNum(_this.year) + '-' + _this.formatNum(_this.month) + '-01 00:00:00'}`
      }
    },
    showCurrent() {
      //显示当前的日期时间
      let arr = [0, 0, 0, 0, 0, 0]
      let dateArr = [0, 0, 0, 0]
      this.selectArr = [
        this.formatNum(this.year),
        this.formatNum(this.month),
        this.formatNum(this.day),
        this.formatNum(this.hour),
        this.formatNum(this.minute),
        this.formatNum(this.second)
      ]
      this.selectRes = `${this.formatNum(this.year) +
        '-' +
        this.formatNum(this.month) +
        '-' +
        this.formatNum(this.day) +
        ' ' +
        this.formatNum(this.hour) +
        ':' +
        this.formatNum(this.minute) +
        ':' +
        this.formatNum(this.second)}`
      if (this.isAll) {
        arr[0] = this.year - this.startYear
        arr[1] = this.month - 1
        arr[2] = this.day - 1
        arr[3] = this.hour
        arr[4] = this.minute
        arr[5] = this.second
        this.$nextTick(() => {
          this.values = arr
        })
      } else {
        dateArr[1] = this.hour
        dateArr[2] = this.minute
        dateArr[3] = this.second
        this.$nextTick(() => {
          this.dateValues = dateArr
        })
      }
    },
    initDayArr: (year, month) => {
      //初始化月份天数
      let totalDay = new Date(year, month, 0).getDate()
      let dayArr = []
      for (let i = 1; i <= totalDay; i++) {
        if (i < 10) {
          i = '0' + i
        } else {
          i = i + ''
        }
        dayArr.push(i)
      }
      return dayArr
    },
    formatNum(num) {
      //日期时间的初始化
      return num < 10 ? '0' + num : num + ''
    },
    maskClick() {
      //日期时间的遮罩
      this.showPicker = false
      this.$emit('cancel')
    },
    show() {
      //日期时间的显示
      this.showPicker = true
    },
    hide() {
      //日期时间的隐藏
      this.showPicker = false
      this.$emit('cancel')
    },
    pickerCancel() {
      //日期时间取消
      this.showPicker = false
      this.$emit('cancel', {
        selectArr: this.selectArr
      })
    },
    pickerConfirm(e) {
      //日期时间确定
      this.showPicker = false
      this.$emit('confirm', {
        selectArr: this.selectArr,
        selectRes: this.selectRes
      })
    },
    bindChange(e) {
      //默认滚动日期时间方法
      let valueArr = e.detail.value
      let year = '',
        month = '',
        day = '',
        hour = '',
        minute = '',
        second = ''
      let selectArr = this.selectArr
      let dayArr = []
      year = this.dateObj.years[valueArr[0]]
      month = this.dateObj.months[valueArr[1]]
      day = this.dateObj.days[valueArr[2]]
      hour = this.dateObj.hours[valueArr[3]]
      minute = this.dateObj.minutes[valueArr[4]]
      second = this.dateObj.seconds[valueArr[5]]
      if (year != selectArr[0]) {
        dayArr = this.initDayArr(year, month)
        this.dateObj.days = dayArr
      }
      if (month != selectArr[1]) {
        dayArr = this.initDayArr(year, month)
        this.dateObj.days = dayArr
      }
      this.selectArr = [year, month, day, hour, minute, second]
      this.selectRes = `${year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second}`
      this.$nextTick(() => {
        this.values = valueArr
      })
    },
    bindDateChange(e) {
      //有效日期的滚动日期时间方法
      let valueArr = e.detail.value
      let dateStr = '',
        dateArr = [],
        hour = '',
        minute = '',
        second = ''
      let selectArr = this.selectArr
      let dayArr = []
      dateStr = this.dateObj.dates[valueArr[0]]
      dateArr = dateStr.split('-')
      hour = this.dateObj.hours[valueArr[1]]
      minute = this.dateObj.minutes[valueArr[2]]
      second = this.dateObj.seconds[valueArr[3]]
      this.selectArr = [dateArr[0], dateArr[1], dateArr[2], hour, minute, second]
      this.selectRes = `${dateArr[0] + '-' + dateArr[1] + '-' + dateArr[2] + ' ' + hour + ':' + minute + ':' + second}`
      this.$nextTick(() => {
        this.dateValues = valueArr
      })
    },
    //遍历两个日期间的所有日期
    getBetweenDateStr(start, end) {
      let result = []
      let beginDay = start.split('-')
      let endDay = end.split('-')
      let diffDay = new Date()
      let dateList = new Array()
      let i = 0
      diffDay.setDate(beginDay[2])
      diffDay.setMonth(beginDay[1] - 1)
      diffDay.setFullYear(beginDay[0])
      result.push(start)
      while (i == 0) {
        let countDay = diffDay.getTime() + 24 * 60 * 60 * 1000
        diffDay.setTime(countDay)
        dateList[2] = diffDay.getDate()
        dateList[1] = diffDay.getMonth() + 1
        dateList[0] = diffDay.getFullYear()
        if (String(dateList[1]).length == 1) {
          dateList[1] = '0' + dateList[1]
        }
        if (String(dateList[2]).length == 1) {
          dateList[2] = '0' + dateList[2]
        }
        result.push(dateList[0] + '-' + dateList[1] + '-' + dateList[2])
        if (dateList[0] == endDay[0] && dateList[1] == endDay[1] && dateList[2] == endDay[2]) {
          i = 1
        }
      }
      return result
    }
  }
}
</script>

<style>
.lr-datetime-picker {
  position: relative;
  z-index: 888;
}

.lr-datetime-mask {
  position: fixed;
  z-index: 1000;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.4);
  visibility: hidden;
  opacity: 0;
  transition: all 0.3s ease;
}

.lr-datetime-mask.show {
  visibility: visible;
  opacity: 1;
}

.lr-datetime-content {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  transition: all 0.3s ease;
  transform: translateY(100%);
  z-index: 3000;
}

.lr-datetime-content.show {
  transform: translateY(0);
}

.lr-datetime-hd {
  display: flex;
  align-items: center;
  padding: 0 30upx;
  height: 44px;
  background-color: #fff;
  position: relative;
  text-align: center;
  font-size: 15px;
  justify-content: space-between;
}

.lr-datetime-btn {
  font-size: 14px;
}

.lr-datetime-hd:after {
  content: ' ';
  position: absolute;
  left: 0;
  bottom: 0;
  right: 0;
  height: 1px;
  border-bottom: 1px solid #e5e5e5;
  color: #e5e5e5;
  transform-origin: 0 100%;
  transform: scaleY(0.5);
}

.lr-datetime-view {
  width: 100%;
  height: 200px;
  overflow: hidden;
  background-color: rgba(255, 255, 255, 1);
  z-index: 666;
}

.yu-picker-column {
  -webkit-flex: 2;
  -webkit-box-flex: 2;
  flex: 2;
}

.lr-datetime-item {
  text-align: center;
  width: 100%;
  height: 88upx;
  line-height: 88upx;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 30upx;
}
</style>
