buy-sheet.vue 4.48 KB
<template>
  <action-sheet @hidden="onHidden" position="right" ref="popup">
      <div class="buy-sheet">
        <div class="header">
          <div class="back-wrapper flex" @touchend="onBack">
            <div class="back"></div>
          </div>
        </div>
        <div class="title">
          <img-size class="title-thumbnail" :src="imageUrl" :width="300" :height="300"/>
          <div>{{productDetail.product_name}} {{goodsName}}</div>
        </div>
        <div class="size-list">
          <cube-scroll>
            <ul>
              <li :class="['size-item', item.available ? '': 'disable']" v-for="(item, idx) in sizeViewList" :key="idx" @click="buy(item)">
                <div class="size"><span>{{item.name}}</span><span v-if="item.subName">{{item.subName}}</span></div>
                <div class="price">¥ {{item.price}} <i class="cubeic-arrow"></i></div>
              </li>
            </ul>
          </cube-scroll>
        </div>
    </div>
  </action-sheet>
</template>

<script>
import { Scroll } from 'cube-ui';
import { get } from 'lodash';
import { createNamespacedHelpers } from 'vuex';

import ImgSize from '../../../components/img-size';
import ActionSheet from './action-sheet';

const { mapActions, mapGetters } = createNamespacedHelpers('product');

export default {
  name: 'BuySheet',
  components: {
    ImgSize,
    ActionSheet,
    'cube-scroll': Scroll,
  },
  computed: {
    ...mapGetters(['productDetail']),
    sizeList() {
      return get(this.productDetail, 'goods_list_tabs.goods_list[0].size_list', []);
    },
    sizeViewList() {
      return this.sizeList.map(info => {
        let price;

        if (info.least_price > 0) {
          price = `${info.least_price}`;
        } else {
          price = '-';
        }

        const name = info.size_name.split(/\s+/);

        return {
          size_id: info.size_id,
          name: name[0],
          subName: name[1],
          price,
          storage_id: info.storage_id,
          available: info.storage_num > 0 && price !== '-',
        };
      });
    },
    imageUrl() {
      return get(this.productDetail, 'goods_list[0].image_list[0].image_url', '');
    },
    goodsName() {
      return get(this.productDetail, 'goods_list[0].goods_name', '');
    },
  },
  mounted() {
    this.$refs.popup.show();
  },
  methods: {
    ...mapActions(['updateTradeInfo']),
    onHidden() {
      this.$emit('hidden');
    },
    buy(product) {
      if (!product.available) {
        return;
      }
      this.onBack();
      this.updateTradeInfo({
        productId: this.productDetail.product_id,
        sizeInfo: product,
      }).then((data) => {
        this.$router.push({
          name: 'OrderBuyConfirm',
          query: data,
        });
      });
    },
    onBack() {
      this.$refs.popup.hide();
    },
  },
};
</script>

<style lang="scss" scoped>
  @import "../product-detail";

  .buy-sheet {
    height: 100vh;
    display: flex;
    flex-direction: column;
    position: relative;
    .size-list {
      flex: 1;
      padding: 10px 40px;
      overflow: scroll;
    }
  }
  .title-thumbnail {
    width: 140px;
    height: 140px;
    margin: 0 auto;
    display: block;
  }

  .header {
    width: 100%;
    height: 90px;
    padding-left: 40px;
    padding-right: 40px;
    display: flex;
    justify-content: flex-end;
    align-items: stretch;
    box-sizing: border-box;
    position: absolute;
    top: 0;

    .flex {
      display: flex;
      align-items: center;
    }

    .back-wrapper {
      height: 100%;
    }

    .back {
      width: 48px;
      height: 48px;
      background: url(~statics/image/address/close.png) no-repeat;
      background-size: cover;
    }
  }

  .title {
    padding: 20px 40px 80px;
    text-align: center;
    font-weight: bold;
    font-size: 0.9em;
    border-bottom: 1px solid #ddd;
  }

  .size-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: #000;
    font-size: 32px;
    padding: 40px;
    margin-bottom: 40px;
    border-bottom: 1px solid #ddd;

    .size {
      line-height: 1.8;
      display: flex;
      font-size: 1.3em;
      font-weight: bold;
      align-items: baseline;

      span:nth-child(2) {
        font-size: 0.8em;
        margin-left: 10px;
        display: inline-block;
      }
    }

    .price {
      display: flex;
      align-items: center;

      i {
        display: inline-block;
        margin-left: 5px;
        color: #999;
      }
    }
    &.disable {
      .size, .price {
        color: #999;
      }
    }
  }
</style>