<!--
 * @Author: ch
 * @Date: 2022-05-04 17:25:41
 * @LastEditors: ch
 * @LastEditTime: 2022-05-04 17:26:08
 * @Description: file content
-->
<template>
  <div class="seckill">
    <div v-show="isSticky" class="seckill-header-sticky">
      <TabBar
        v-model="query.activityTimeId"
        :list="tabList"
        @tab-click="getGoodsList"
      />
    </div>
    <!-- 秒杀时间段 -->
    <div
      class="seckill-header"
      :style="{ backgroundImage: `url(${bkgSckill})` }"
    >
      <div class="seckill-header-tabbar">
        <TabBar
          v-model="query.activityTimeId"
          :list="tabList"
          @tab-click="getGoodsList"
        />
      </div>
    </div>
    <!-- 倒计时展示 -->
    <div
      v-if="tabList.length > 0"
      class="seckill-bar flex flex-middle flex-center"
    >
      <p>{{ seckillTip }}</p>
      <div class="seckill-bar-countdown flex flex-middle">
        <div class="seckill-bar-countdown__time">{{ countdown.hour }}</div>
        <span class="seckill-bar-countdown--mark">:</span>
        <div class="seckill-bar-countdown__time">{{ countdown.minute }}</div>
        <span class="seckill-bar-countdown--mark">:</span>
        <div class="seckill-bar-countdown__time">{{ countdown.second }}</div>
      </div>
    </div>
    <!-- 秒杀商品列表 -->
    <div v-loading="loading" class="seckill-products flex flex-wrap">
      <div
        v-for="item in goodsList"
        :key="item.productId"
        @click="onJumpGoodsDetail(item.productId)"
        class="seckill-products-wrap"
      >
        <img
          :src="item.productMainPicture"
          class="seckill-products-wrap__cover"
        />
        <div class="seckill-products-wrap__content">
          <p class="products-wrap-content__title">{{ item.productName }}</p>
          <div class="products-wrap-content__price">
            <strong>￥{{ item.activityPrice }}</strong>
            <del>￥{{ item.originalPrice }}</del>
          </div>
          <div
            class="products-wrap-content__footer flex flex-middle flex-between"
          >
            <div class="wrap-content-footer__stock">
              <el-progress :percentage="40" :show-text="false"></el-progress>
              <p>仅剩{{ item.stock }}件</p>
            </div>
            <div class="wrap-content-footer__btn">立即抢购</div>
          </div>
        </div>
      </div>
    </div>
    <!-- 分页 -->
    <div class="seckill-pagination flex flex-right">
      <el-pagination
        background
        :current-page="currentPage"
        :page-size="query.length"
        layout="prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      >
      </el-pagination>
      <el-button class="btn-confirm">确定</el-button>
    </div>
  </div>
</template>
<script>
import {
  ApiGetSeckillTimes,
  ApiGetSeckillGoods,
  ApiGetCurrentTime,
} from "@/plugins/api/seckill";
import TabBar from "./module/TabBar.vue";

export default {
  name: "Sckill",
  components: { TabBar },
  data() {
    return {
      bkgSckill: require("~/assets/img/sckill/bkg-large.png"),
      tabList: [], // 秒杀时间段
      goodsList: [], // 商品列表
      total: 0,
      currentPage: 0,
      loading: false,
      query: {
        pageIndex: 1,
        length: 16,
        activityTimeId: 0,
      },
      ticking: false,
      isSticky: false,
      currentTabItem: null, // 当前选中时间段
      timeInterval: null, // 倒计时定时器
      seckillTip: "", // 秒杀提示文案
      seckillTime: 0, // 秒杀时间
    };
  },
  computed: {
    countdown() {
      const data = parseInt(this.seckillTime / 1e3);
      const hour = Math.floor(data / 60 / 60);
      const minute = Math.floor((data / 60) % 60);
      const second = Math.floor(data % 60);
      return {
        hour: hour < 10 ? `0${hour}` : `${hour}`,
        minute: minute < 10 ? `0${minute}` : `${minute}`,
        second: second < 10 ? `0${second}` : `${second}`,
      };
    },
  },
  watch: {
    "query.activityTimeId": {
      immediate: true,
      handler(val) {
        if (val === 0) {
          return;
        }
        clearImmediate(this.timeInterval);
        const tabItem = this.tabList.find((item) => item.id === val);
        if (tabItem) {
          this.currentTabItem = tabItem;
          const { activityStartTime, activityEndTime } = tabItem;
          this.setTimerInterval({
            startTime: activityStartTime,
            endTime: activityEndTime,
          });
        }
      },
    },
  },

  created() {
    this.getSeckillTimes();
  },
  mounted() {
    // 监听滚动事件
    window.addEventListener("scroll", this.scrollEventMethod);
  },
  destroyed() {
    window.removeEventListener("scroll", this.scrollEventMethod);
    clearInterval(this.timeInterval);
  },
  methods: {
    scrollEventMethod() {
      const that = this;
      // 节流
      if (!that.ticking) {
        window.requestAnimationFrame(function () {
          that.ticking = false;
          that.isSticky = window.scrollY > 400;
        });
        that.ticking = true;
      }
    },
    async getSeckillTimes() {
      const { result } = await ApiGetSeckillTimes();
      if (result && result.length > 0) {
        this.tabList = result;
        const inProgressItem = result.find((item) => item.isInProgress);
        this.query.activityTimeId =
          (inProgressItem && inProgressItem.id) || result[0].id;
        this.getGoodsList();
      }
    },
    async getGoodsList() {
      this.loading = true;
      const { result } = await ApiGetSeckillGoods({ ...this.query });
      this.loading = false;
      if (result) {
        this.total = result.total;
        this.goodsList = result.records;
      }
    },

    // 设置定时器
    async setTimerInterval({ startTime, endTime }) {
      // 获取服务器当前时间
      const { result } = await ApiGetCurrentTime();
      const current = result || Date.now();

      startTime = new Date(startTime).getTime();
      endTime = new Date(endTime).getTime();
      if (current > endTime) {
        // 秒杀结束
        this.getSeckillTimes();
        return;
      }
      if (startTime < current && endTime > current) {
        // 秒杀进行中
        this.seckillTime = endTime - current;
        this.seckillTip = "本场正在秒杀中，好物转瞬即逝，不要错过哦~距结束仅剩";
      } else {
        // 秒杀未开始
        this.seckillTime = startTime - current;
        this.seckillTip = "本场秒杀即将开抢，距开始还剩";
      }

      this.timeInterval = setInterval(() => {
        if (this.seckillTime <= 0) {
          clearInterval(this.timeInterval);
          this.getSeckillTimes();
          return;
        }
        this.seckillTime -= 1e3;
      }, 1e3);
    },
    onJumpGoodsDetail(id) {
      this.$router.push(`/goods/detail/${id}`);
    },
    handleSizeChange(size) {
      this.query.length = size;
      this.getGoodsList();
    },
    handleCurrentChange(page) {
      this.query.pageIndex = page;
      this.getGoodsList();
    },
    handleTabSelect(id) {
      this.query.activityTimeId = id;
      Object.assign(this.query, {
        pageIndex: 1,
        length: 16,
      });
      this.getGoodsList();
    },
  },
};
</script>
<style lang="scss" scoped>
.seckill {
  background: #f8f8f8;
  padding-bottom: 42px;
  .seckill-header-sticky {
    position: fixed;
    left: 50%;
    transform: translate(-50%);
    top: 50px;
    z-index: 1;
    @include layout-box;
  }
  .seckill-header {
    position: relative;
    width: 100%;
    height: 156px;
    background-size: 100% 100%;
    .seckill-header-tabbar {
      @include layout-box;
      position: absolute;
      left: 50%;
      bottom: 0;
      transform: translate(-50%);
    }
  }
  .seckill-bar {
    height: 60px;
    line-height: 60px;
    text-align: center;
    font-size: 14px;
    color: #666666;
    .seckill-bar-countdown {
      margin-left: 25px;
      font-weight: bold;
      &__time {
        width: 22px;
        height: 22px;
        line-height: 22px;
        text-align: center;
        font-size: 14px;
        color: #ffffff;
        background: #2f3430;
      }
      &--mark {
        display: block;
        margin: 0 7px;
        color: #2f3430;
      }
    }
  }
  .seckill-products,
  .seckill-pagination {
    @include layout-box;
  }
  .seckill-products {
    .seckill-products-wrap {
      width: 24%;
      background: #ffffff;
      margin: 15px 0 60px 0;
      cursor: pointer;
      &:not(:nth-child(4n)) {
        margin-right: calc(4% / 3);
      }
      .seckill-products-wrap__cover {
        width: 100%;
        height: 288px;
      }
      .seckill-products-wrap__content {
        padding: 20px 16px;
        .products-wrap-content__title {
          @include ellipsis;
          color: #333333;
          font-size: 16px;
          margin-bottom: 10px;
        }
        .products-wrap-content__price {
          font-size: 12px;
          color: #999999;
          margin-bottom: 7px;
          strong {
            font-size: 18px;
            color: #ff512b;
            margin-right: 14px;
          }
        }
        .products-wrap-content__footer {
          .wrap-content-footer__stock {
            font-size: 12px;
            color: #666666;
            /deep/.el-progress {
              width: 100px;
              height: 6px;
              background: #dddddd;
              border-radius: 4px;
              margin-bottom: 8px;
            }
          }
          .wrap-content-footer__btn {
            width: 100px;
            height: 36px;
            line-height: 36px;
            text-align: center;
            background: #ff512b;
            font-size: 14px;
            color: #ffffff;
          }
        }
      }
    }
  }
  .seckill-pagination {
    margin-top: 60px;
    /deep/.el-pagination {
      .btn-prev,
      .btn-next {
        width: 32px;
        height: 32px;
        background: #ffffff;
        border-radius: 2px;
        border: 1px solid rgba(0, 0, 0, 0.2);
      }
      .el-pagination__jump {
        color: #333333;
      }
      .el-pager {
        .number {
          width: 32px;
          height: 32px;
          line-height: 32px;
          font-size: 14px;
          background: #ffffff;
          border: 1px solid rgba(0, 0, 0, 0.2);
          border-radius: 2px;
        }
        .active {
          color: #ffffff;
          background: #ff512b;
          border: none;
        }
      }
    }
    .btn-confirm {
      width: 81px;
      height: 32px;
      border-radius: 2px;
      margin-left: 14px;
    }
  }
}
</style>
