change-bid-price-dialog.vue 6.13 KB
<template>
  <!--求购用调价对话框-->
  <div class="dialog-wrapper" :class="[visible ? 'show' : '']">
    <div :class="['change-bid-price-wrapper', visible ? 'anim' : '']">
      <div class="change-bid-price-container">
        <p class="price-item">
          <span>我的求购价:</span>
          <span>¥{{ goodsInfo.goodPrice }}</span>
        </p>
        <p v-if="goodsInfo.bidHighestPrice" class="price-item">
          <span>现货最高求购价:</span>
          <span>¥{{ goodsInfo.bidHighestPrice.toFixed(2) }}</span>
        </p>
        <p v-if="goodsInfo.leastPrice" class="price-item">
          <span>现货最低售价:</span>
          <span>¥{{ goodsInfo.leastPrice.toFixed(2) }}</span>
        </p>
        <InputUfo
          type="number"
          placeholder="定价需以9结尾 例如1999"
          :maxlength="8"
          :class="[
            errorTip ? 'ipt-number show-error' : 'ipt-number',
            'ufo-font'
          ]"
          v-model="chgPrice"
        >
          <span class="prepend" slot="prepend">¥</span>
        </InputUfo>
        <p class="error-tip">{{ errorTip }}</p>
        <p
          :class="
            i === computePriceList.length - 1
              ? 'promotion-list-item last'
              : 'promotion-list-item'
          "
          v-for="(priceInfo, i) in computePriceList"
          :key="i"
        >
          <span>{{ priceInfo.promotion }}:</span>
          <span>{{ priceInfo.promotionAmount }}</span>
        </p>
        <p class="tip">Tip: 调整求购价成功后,当前的求购将被关闭</p>
      </div>

      <div class="buttons-container">
        <button class="btn-cancel" @click="closeAction">取消</button>
        <button class="btn-confirm" @click="confirmAction">调整求购价</button>
      </div>
    </div>
  </div>
</template>

<script>
import { createNamespacedHelpers } from "vuex";
import InputUfo from "./input-ufo";
import { debounce } from "lodash";

const { mapActions } = createNamespacedHelpers("order/orderList");

export default {
  name: "change-bid-price-dialog",
  components: { InputUfo },
  props: {
    computePriceInfo: {
      type: Object,
      default: () => ({})
    },
    goodsInfo: {
      type: Object,
      default: () => ({})
    },
    orderCode: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      visible: false,
      chgPrice: "",
      errorTip: "",
      computePrice: null,
      calced: false
    };
  },

  computed: {
    computePriceList() {
      const priceInfo = this.computePrice || this.computePriceInfo;

      return priceInfo.promotionFormulaList.filter(
        ({ promotion }) => promotion === "运费" || promotion === "实付金额"
      );
    }
  },
  mounted() {
    // debounce防抖动,输入数字后延迟500毫秒提交
    this.inputChange = debounce(this.onChange.bind(this), 500);
  },
  methods: {
    ...mapActions(["computeChangePrice"]),
    async onChange(price) {
      // 预先算费
      if (this.checkPrice(price)) {
        const res = await this.computeChangePrice({
          price,
          orderCode: this.orderCode
        });

        if (typeof res === "string") {
          this.errorTip = res;
          this.calced = false;
        } else {
          this.computePrice = res;
          this.calced = true;
        }
      }
    },
    show() {
      this.clearData();
      this.visible = true;
    },

    hide() {
      this.visible = false;
    },
    checkPrice(price) {
      let valid = false;

      if (!price) {
        this.errorTip = "没有价格";
        return false;
      } else if (!/^\d+$/.test(price)) {
        this.errorTip = "价格只能为正整数";
      } else if (!/9$/.test(price)) {
        this.errorTip = "出售价格必须以9结尾";
      } else if (+price === +this.goodsInfo.goodPrice) {
        this.errorTip = "前后价格没有变化";
      } else {
        this.errorTip = "";
        valid = true;
      }
      return valid;
    },
    closeAction() {
      this.hide();
      this.clearData();
      this.$emit("closeAction");
    },
    confirmAction() {
      if (this.calced) {
        let price = this.chgPrice;

        this.hide();
        this.clearData();
        this.$emit("confirmAction", price);
      }
    },
    clearData() {
      this.chgPrice = "";
      (this.errorTip = ""), (this.computePrice = null);
      this.calced = false;
    }
  },
  watch: {
    chgPrice(newVal) {
      this.calced = false;
      this.inputChange(newVal);
    }
  }
};
</script>

<style lang="scss" scoped>
.dialog-wrapper {
  position: fixed;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 99;
  display: none;
  align-items: center;
  justify-content: center;

  &.show {
    display: flex;
  }
}

.change-bid-price-wrapper {
  position: absolute;
  width: 600px;
  background-color: #fff;
  transform: scale(0.9);

  &.anim {
    animation: animateDialog 0.5s cubic-bezier(0.03, 1.58, 0.79, 0.96) forwards;
  }
}

.change-bid-price-container {
  background-color: #fff;
  font-size: 24px;
  color: #000;
  padding: 60px 38px 0 38px;
  letter-spacing: 0;

  .price-item {
    font-size: 24px;
    line-height: 34px;
    margin-bottom: 10px;
  }

  .ipt-number {
    margin: 30px 0;

    /deep/ .prepend {
      width: 40px;
      margin-left: 20px;
      text-align: left;
    }

    &.show-error {
      margin-bottom: 0;
    }
  }

  .error-tip {
    color: #d0021b;
    margin-bottom: 10px;
  }

  .promotion-list-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: #999;
    margin-bottom: 10px;
    font-size: 24px;

    &.last {
      color: #000;
    }
  }

  .tip {
    color: #999;
    margin: 40px auto;
    font-size: 24px;
  }
}

.buttons-container {
  width: 100%;
  height: 100px;
  display: flex;
  border-top: 1px solid #f0f0f0;

  button {
    width: 100%;
    height: 100%;
    text-align: center;
    line-height: 100px;
    font-size: 32px;
    border: none;
    background-color: #fff;
  }

  button + button {
    border-left: 1px solid #f0f0f0;
  }
}

@keyframes animateDialog {
  0% {
    transform: scale(0.9);
  }

  100% {
    transform: scale(1);
  }
}
</style>