seller-confirm.vue 10.2 KB
<template>
  <LayoutApp :show-back="true" title="出售" :back-action="backAction">
    <div class="body">
      <ProductInfo :data="productDetail" class="product-info"></ProductInfo>
      <InputPrice @input="changePrice" class="input-price"
                  :num="num" :value="price"
                  @on-blur="compute" :super-sell="superSell"
                  @on-num-change="onNumChange"
      >
      </InputPrice>
      <OrderMargin class="order-item order-margin" :data="fee" :super-sell="superSell"></OrderMargin>
      <OrderFee class="order-item" :data="fee"></OrderFee>
      <AddressInfo :data="address" class="order-item"></AddressInfo>
    </div>
    <div class="footer">
      <OrderAgree :value="agree" @input="changeAgree" class="agree-wrapper" :desc="agreeDesc" :url="url"></OrderAgree>
      <div class="btn-wrapper">
        <YohoButton :txt="txt" class="submit-btn" @click="onClick" :disable="!agree"></YohoButton>
      </div>
    </div>
  </LayoutApp>
</template>

<script>

import ProductInfo from './components/confirm/product';
import InputPrice from './components/confirm/input-price';
import AddressInfo from './components/confirm/address';
import TitleComp from './components/confirm/title';
import OrderMargin from './components/confirm/order-margin';
import OrderFee from './components/confirm/order-fee';
import OrderAgree from './components/confirm/agree';
import { Types, UserType } from 'store/order/order-confirm';
import { get } from 'lodash';

import { createNamespacedHelpers, mapState } from 'vuex';

const { mapState: mapOrderState, mapActions: mapOrderAction, mapMutations: mapOrderMutations } = createNamespacedHelpers('order/orderConfirm');

export default {
  name: 'SellOrderConfirm',
  props: ['productId', 'storageId'],
  components: {
    ProductInfo,
    AddressInfo,
    InputPrice,
    TitleComp,
    OrderMargin,
    OrderFee,
    OrderAgree
  },
  data() {
    return {
      txt: '提交',
      error: false,
      agreeDesc: '有货卖家协议',
      url: 'https://activity.yoho.cn/feature/6773.html?share_id=9479&title=%E9%97%B2%E9%B1%BC%E6%BD%AE%E5%8D%96%E5%AE%B6%E5%8D%8F%E8%AE%AE',
      superSell: false,
      addNumError: false
    };
  },
  activated() {
    this.fetchUserStatus().then(result => {
      this.superSell = get(result, 'data.entrySellerType', 0) !== 0;
    });
    this.fetchOrderAddress({ tabType: UserType.sell });
    this.$store.dispatch('product/getSelectedTradeProduct', {
      productId: this.productId,
      storageId: this.storageId
    });
  },
  beforeRouteLeave(to, from, next) {
    if (to.name !== 'address') {
      this[Types.CLEAR_SELL_STATUS]();
    }
    next();
  },
  computed: {
    ...mapOrderState(['address', 'fee', 'price', 'agree', 'num']),
    ...mapState({
      productDetail: state => {
        const leastPrice = get(state.product.selectedProductInfo, 'size.least_price', 0);
        const storageNum = get(state.product.selectedProductInfo, 'size.storage_num', 0);
        const suggestHighPrice = get(state.product.selectedProductInfo, 'size.suggest_high_price', 0);
        const suggestLowPrice = get(state.product.selectedProductInfo, 'size.suggest_low_price', 0);
        const bidPrice = get(state.product.selectedProductInfo, 'size.bid_moster_price', 0);

        let priceType = '最低现货价:';
        let goodPrice = '';
        let priceBidType = '最高求购价:';
        let goodBidPrice = '¥-';

        if (!storageNum) {
          if (suggestHighPrice && suggestLowPrice) {
            priceType = '建议售价:';
            goodPrice = `¥${suggestLowPrice}-¥${suggestHighPrice}`;
          } else {
            goodPrice = '¥-';
          }
        } else {
          goodPrice = `¥${leastPrice}`;
        }

        if (leastPrice > 0) {
          if (bidPrice) {
            goodBidPrice = `¥${bidPrice}`;
          }
        }

        return {
          goodImg: get(state.product.selectedProductInfo, 'product.goods_list[0].image_list[0].image_url', ''),
          productName: get(state.product.selectedProductInfo, 'product.product_name', ''),
          colorName: get(state.product.selectedProductInfo, 'product.goods_list[0].color_name', ''),
          sizeName: get(state.product.selectedProductInfo, 'size.size_name', ''),
          skup: get(state.product.selectedProductInfo, 'size.skup', ''),
          goodPrice,
          priceType,
          goodBidPrice,
          priceBidType,
          isSuggest: suggestHighPrice && suggestLowPrice,
          suggestHighPrice,
          suggestLowPrice,
          bidPrice
        };
      }
    })
  },
  methods: {
    ...mapOrderAction(['fetchOrderAddress', 'fetchUserStatus', 'fetchOrderPrice', 'submitOrder', 'fetchPayList']),
    ...mapOrderMutations([Types.CHANGE_PRICE, Types.CHANGE_AGREE, Types.CLEAR_SELL_STATUS, Types.CHANGE_SELL_NUM]),

    onClick() {
      this.submit();
    },
    compute() {
      if (this.productDetail.bidPrice && (Number(this.price) >= this.productDetail.bidPrice)) {
        this.$createDialog({
          type: 'confirm',
          title: `最高求购价${this.productDetail.bidPrice}`,
          content: '已有求购高于您的出价,可直接变现',
          confirmBtn: {
            text: '我再想想',
            active: true,
            disabled: false,
          },
          cancelBtn: {
            text: '确定变现',
            active: false,
            disabled: false
          },
          onCancel: () => {
            this.$router.replace({
              name: 'sellAskOrder',
              query: {
                skup: this.productDetail.skup,
                price: this.productDetail.bidPrice
              }
            });
          }
        }).show();
        return;
      }

      return this.fetchOrderPrice({
        address_id: this.address?.address_id,
        num: this.num,
        price: this.price,
        storage_id: this.storageId,
      }).then(result => {
        if (result.error) {
          this.error = result.error;

          this.$createToast({
            time: 1500,
            txt: result.error,
            type: 'txt'
          }).show();

          if (result.code === 438) {
            this.addNumError = true;
          }

          return;
        }
        this.error = false;
        this.addNumError = false;
      });
    },
    changePrice(val) {
      this[Types.CHANGE_PRICE](val);
    },
    checkAddress() {
      if (!this.address) {
        this.$createToast({
          time: 1500,
          txt: '请选择地址',
          type: 'txt'
        }).show();
        return false;
      }

      return true;
    },
    changeAgree(val) {
      this[Types.CHANGE_AGREE](val);
    },
    submit() {
      if (this.productDetail.isSuggest) {
        if (Number(this.price) > this.productDetail.suggestHighPrice) {
          this.$createDialog({
            type: 'confirm',
            content: '超出建议售价将被限制展示,建议下调至合理价格区间',
            confirmBtn: {
              text: '修改价格',
              active: true,
              disabled: false,
            },
            cancelBtn: {
              text: '仍要上架',
              active: false,
              disabled: false
            },
            onCancel: () => {
              this.submitHandler();
            }

          }).show();
        } else {
          this.submitHandler();
        }
      } else {
        this.submitHandler();
      }
    },
    async submitHandler() {
      const vm = this;

      if (!this.checkAddress()) {
        return;
      }

      await this.compute();

      if (this.error) {
        return;
      }

      const orderResult = await this.submitOrder({
        address_id: this.address?.address_id,
        num: this.num,
        price: this.price,
        storage_id: this.storageId,
      });

      if (orderResult.code !== 200) {
        this.$createToast({
          time: 1500,
          txt: orderResult.message,
          type: 'txt'
        }).show();
        return;
      }

      // 从定金中走了钱,不用支付宝
      if (orderResult.data.orderCode === 0) {
        this.$createToast({
          time: 1500,
          txt: orderResult.message,
          mask: true,
          type: 'txt'
        }).show();

        await this.delay(1500);

        this.$router.replace({
          name: 'ProductDetail',
          params: {
            productId: this.productId
          }
        });
        return;
      }

      this.$createOrderPayType({
        price: this.fee.earnestMoneyStr,
        desc: '保证金',
        orderCode: orderResult.data.orderCode,
        extra: JSON.stringify({
          type: UserType.sell,
          back: {
            name: 'ProductDetail',
            params: {
              productId: this.productId
            }
          },
          forward: {
            name: 'SellPayOk',
            query: {
              orderCode: orderResult.data.orderCode
            }
          }
        }),
        onCloseAction() {
          vm.onClose(orderResult.data.orderCode);
        }
      }).show();
    },
    onClose(orderCode) {
      this.$router.replace({
        name: 'sellOrderDetail',
        params: {
          owner: UserType.sell,
          code: orderCode
        }
      });
    },
    onNumChange({ count, type }) {
      console.log(count, type, this.addNumError);
      if (type === 'add' && this.addNumError) {
        return;
      }

      this[Types.CHANGE_SELL_NUM](count);
      this.compute();
    },
    delay(ns) {
      return new Promise(resolve => {
        setTimeout(resolve, ns);
      });
    },
    backAction() {
      this.$router.replace({
        name: 'ProductDetail',
        params: {
          productId: this.productId
        }
      });
    }
  }
};
</script>

<style lang="scss" scoped>
.body {
  height: 100%;
  margin: 0 40px;
  padding-bottom: 200px;
  overflow-y: auto;
}

.order-item {
  padding-top: 40px;
  padding-bottom: 40px;
}

.order-item + .order-item {
  border-top: 1px solid #eee;
}

.footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  border-top: 1px solid #eee;
  z-index: 1;
}

.btn-wrapper {
  margin-bottom: 40px;
  padding: 0 40px;
  background-color: white;
}

.agree-wrapper {
  padding: 0 50px;
}

.submit-btn {
  height: 80px;
  line-height: 80px;
  font-size: 28px;
}

</style>