list.vue 8.69 KB
<template>
  <LayoutApp>
    <div class="tab">
      <div class="item right-line" :class="type ==='unused' ?  'item-selected' : 'item-default'"
           @click="onChangeList('unused')">未使用{{unused.total && '('+ unused.total + ')' || null}}
      </div>
      <div class="item right-line" :class="type ==='used' ?  'item-selected' : 'item-default'"
           @click="onChangeList('used')">已使用{{used.total && '('+ used.total + ')' || null}}
      </div>
      <div class="item" :class="type ==='overtime' ?  'item-selected' : 'item-default'"
           @click="onChangeList('overtime')">已失效{{overtime.total && '('+ overtime.total + ')' || null}}
      </div>
    </div>
    <Scroll class="coupon-list"
            :options="scrollOptions"
            :data="list"
            @pulling-up="onPullingUp" v-show="!showEmpty">
      <div class="item" v-for="(item,index) in list">
        <div :class="type === 'unused' ? 'item-bg' : 'item-gray-bg'">
          <div class="item-left">
            <div class="item-price" :class="type !== 'unused' && 'gray'">{{item.coupon_value}}</div>
            <div class="item-rule" v-if="item.use_rule" :class="type !== 'unused' && 'gray'">{{item.use_rule}}</div>
          </div>
          <div class="item-right">
            <div class="item-name" :class="type !== 'unused' && 'gray'">
              <span class="item-type" :class="type !== 'unused' && 'gray'">[{{item.coupon_type_name}}]</span>
              {{item.coupon_name}}
            </div>
            <div class="item-time" :class="type !== 'unused' && 'gray'">{{item.coupon_validity}}</div>
            <div class="item-desc-btn" :class="type !== 'unused' && 'gray'" @click="handleShowNotice(item,index)">
              使用说明
              <div class="down" :class="item.showNotice && 'up'"></div>
            </div>
            <div class="time-up" v-if="type ==='unused' && item.is_expired_soon === 'Y'"></div>
            <div class="item-used-flag" v-if="type === 'used'"></div>
            <div class="item-use" v-if="type === 'unused'" @click="goUseList(item.coupon_token)">
              立即使用
            </div>
            <div class="item-overtime-flag" v-if="type === 'overtime'"></div>
          </div>
        </div>
        <div class="notice" v-show="item.showNotice">
          <div class="shadow"></div>
          <div v-for="no in item.notes" class="row">
            <div class="mr10">•</div>
            <div class="no-text">{{no}}</div>
          </div>
        </div>
      </div>
    </Scroll>
    <div
      class="empty-wrapper"
      v-show="showEmpty"
    >
      <div class="couponErrorPageImage"></div>
      暂无优惠券
    </div>
  </LayoutApp>
</template>

<script>

import {Scroll} from 'cube-ui';
import {createNamespacedHelpers} from 'vuex';
import EmptyList from '../../../components/ufo-no-item';

const {mapState, mapActions} = createNamespacedHelpers('home/coupon');

export default {
  name: 'Coupon',
  components: {Scroll, EmptyList},
  activated: function() {
    this.type = 'unused';
    this.fetchCouponList({type: 'unused', isReset: true}).then(r=>{
      this.list = r;
      this.showEmpty = !(r && r.length);
    });
    this.fetchCouponList({type: 'used', isReset: true});
    this.fetchCouponList({type: 'overtime', isReset: true});
  },
  data() {
    return {
      scrollOptions: {
        bounce: {
          top: false
        },
        pullUpLoad: true
      },
      type: 'unused',
      list: [],
      showEmpty: false,
    };
  },
  methods: {
    ...mapActions(['fetchCouponList']),

    onChangeList(type) {
      // 切换tab
      this.type = type;

      // 切换list
      this.list = this[type].list;
      this.showEmpty = this[type].isEmpty;
    },

    handleShowNotice(item, index) {
      if (item.showNotice !== void(0)) {
        item.showNotice = !item.showNotice;
      } else {
        item.showNotice = true;
      }
      this.$set(this.list, index, item);
    },

    async onPullingUp() {
      this.list = await this.fetchCouponList({type: this.type});
      this.showEmpty = this[this.type].isEmpty;
    },

    goUseList(coupon_token) {
      return this.$router.push({
        name: 'List',
        query: {
          coupon_token
        }
      });
    }
  },
  computed: {
    ...mapState(['unused', 'used', 'overtime']),
  },
};
</script>

<style lang="scss" scoped>
  .tab {
    position: relative;
    display: flex;
    width: 100%;
    height: 88px;
    padding: 14px 0;
    align-items: center;
    z-index: 9999;
    background: #fff;

    .item {
      font-size: 28px;
      flex: 1;
      height: 60px;
      text-align: center;
      line-height: 60px;
    }

    .right-line {
      border-right: 1px solid #E0E0E0;
    }

    .item-default {
      color: #B0B0B0;
    }

    .item-selected {
      color: #444444;
    }
  }

  .coupon-list {
    background: #f5f5f5;

    .item {
      width: 100%;
      margin-top: 20px;
    }

    .item-bg {
      background: url(~statics/image/coupon/bg@3x.png) no-repeat;
      width: 710px;
      height: 200px;
      background-size: cover;
      margin: 0 auto;
      display: flex;
      position: relative;
      z-index: 10;
    }

    .down {
      transform: rotate(0deg);
      background: url(~statics/image/coupon/down@3x.png) no-repeat;
      background-size: contain;
      width: 20px;
      height: 20px;
      margin-left: 10px;
      margin-top: 4px;
    }

    .up {
      margin-top: -8px !important;
      transform: rotate(180deg);
    }

    .shadow {
      opacity: 0.7;
      background: #fff;
      position: absolute;
      top: 0;
      left: 0;
      height: 2px;
      width: 702px;
      box-shadow: #ddd 0 1px 10px 10px;
    }

    .item-left {
      width: 230px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;

      .item-price {
        font-size: 72px;
        color: #002B47;
      }

      .item-rule {
        font-size: 24px;
        margin-top: 4px;
        color: #002B47;
      }
    }

    .item-right {
      margin-left: 6px;

      .item-name {
        font-size: 24px;
        color: #222;
        margin-top: 22px;
        width: 320px;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
        text-overflow: ellipsis;
        height: 60px;
      }

      .item-type {
        color: #002B47;
      }

      .item-time {
        margin-top: 10px;
        font-size: 22px;
        color: #999;
      }

      .item-desc-btn {
        margin-top: 26px;
        font-size: 22px;
        color: #999;
        display: flex;
        align-items: center;
      }

      .time-up {
        background: url(~statics/image/coupon/time-up@3x.png) no-repeat;
        background-size: cover;
        position: absolute;
        top: 0;
        right: 0;
        width: 80px;
        height: 80px;
      }

      .item-used-flag {
        background: url(~statics/image/coupon/used@3x.png) no-repeat;
        background-size: cover;
        position: absolute;
        right: 30px;
        width: 130px;
        height: 130px;
        top: 30px;
      }

      .item-overtime-flag {
        background: url(~statics/image/coupon/overtime@3x.png) no-repeat;
        background-size: cover;
        position: absolute;
        right: 30px;
        width: 130px;
        height: 130px;
        top: 30px;
      }
    }

    .gray {
      color: #ccc !important;
    }

    .item-gray-bg {
      background: url(~statics/image/coupon/bg-gray@3x.png) no-repeat;
      width: 710px;
      height: 200px;
      background-size: cover;
      margin: 0 auto;
      display: flex;
      position: relative;
      z-index: 10;
    }

    .notice {
      opacity: 0.7;
      background: #fff;
      margin: -10px 20px 0 20px;
      padding: 36px 26px 26px 26px;
      position: relative;

      .mr10 {
        margin-right: 10px;
      }

      .row {
        display: flex;
        margin-bottom: 8px;
      }

      .no-text {
        font-size: 22px;
        color: #444;
      }
    }
  }

  .empty-wrapper {
    width: 100%;
    margin: auto 0;
    position: absolute;
    top: 0;
    bottom: 0;
    background: #f5f5f5;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    font-size: 28px;
    color: #b0b0b0;
  }

  .couponErrorPageImage {
    background: url(~statics/image/coupon/no_coupon.png) no-repeat;
    background-size: cover;
    width: 208px;
    height: 130px;
    margin-bottom: 30px;
  }

  .item-use {
    position: absolute;
    right: 20px;
    bottom: 20px;
    width: 130px;
    height: 50px;
    border: 1px solid #444;
    border-radius: 25px;
    justify-content: center;
    align-items: center;
    font-size: 20px;
    color: #444;
    display: flex;
  }
</style>