pay.vue 4.51 KB
<template>
  <LayoutApp :show-back="true" title="支付中" :back-action="backAction">
    <CountCircle :line-width="6" :time="count * 1000" style="width: 70px; height: 70px; display: block;"></CountCircle>

    <div class="tip">正在支付中…</div>
    <div class="tip2">支付成功跳转成功页面,支付失败返回上一层</div>

    <div class="btn-wrapper">
      <YohoButton class="btn2 ok" txt="继续支付" @click="openPay"></YohoButton>
      <YohoButton class="btn2" txt="支付完成" @click="goOk"></YohoButton>
    </div>
  </LayoutApp>
</template>

<script>

import config from 'config';
import { UserType } from 'store/order/order-confirm';
import { createNamespacedHelpers } from 'vuex';

const { mapActions: mapOrderAction } = createNamespacedHelpers('order/orderConfirm');

export default {
  name: 'PayPage',
  props: ['orderCode', 'payParams', 'extra'],
  data() {
    return {
      count: 60,
      page: null,
      timer: null,
    };
  },
  mounted() {
    if (this.payParams) {
      this.openPay();
    }

    this.setCount();

    if (this.extra) {
      this.page = JSON.parse(this.extra || '{}');
    }

    this.check().catch((result) => {
      if (result?.data?.statusDetail?.leftTime < 60) {
        this.count = result?.data?.statusDetail?.leftTime;
      }
    });
  },
  beforeRouteLeave(to, from, next) {
    if (this.timer) {
      clearTimeout(this.timer);
    }

    next();
  },
  methods: {
    ...mapOrderAction(['fetchOrderStatus']),
    openPay() {
      const url = config.alipayUrl + '?' + this.payParams;

      this.$xianyu.goXianyuNewPage({
        url
      });
    },
    backAction() {
      const page = JSON.parse(this.extra || '{}');

      if (page?.back) {
        this.$router.replace(page.back);
      } else {
        this.$router.go(-1);
      }
    },
    setCount() {
      if (this.count > 0) {
        this.timer = setTimeout(() => {
          this.count = this.count - 1;
          this.setCount();
        }, 1000);

        if (this.count % 5 === 0) {
          this.check().catch(() => {
          });
        }
      } else {
        this.goOk();
      }
    },
    check() {
      return this.fetchOrderStatus({
        orderCode: this.orderCode
      }).then((result) => {
        if ([1, 7].includes(result?.data?.statusDetail?.status)) {
          this.$router.replace(this.page?.forward);
        } else {
          return Promise.reject(result);
        }
      });
    },
    async goOk() {
      this.check().catch(() => {
        this.goDetail();
      });
    },
    goDetail() {
      switch (this.page.type) {
        case UserType.sell: {
          this.$router.replace({
            name: 'sellOrderDetail',
            params: {
              owner: UserType.sell,
              code: this.orderCode
            }
          });
          break;
        }
        case UserType.buy: {
          this.$router.replace({
            name: 'buyOrderDetail',
            params: {
              owner: UserType.buy,
              code: this.orderCode
            }
          });
          break;
        }
        default: {
          this.goList();
        }
      }
    },
    goList() {
      switch (this.page.type) {
        case UserType.sell: {
          this.$router.replace({
            name: 'InSaleOrderList',
          });
          break;
        }
        case UserType.buy: {
          this.$router.replace({
            name: 'OrderList',
            params: {
              owner: UserType.buy
            }
          });
          break;
        }
        default: {
          this.$router.replace({
            name: 'OrderList',
            params: {
              owner: UserType.buy
            }
          });
          break;
        }
      }
    }
  }
};
</script>

<style lang="scss" scoped>
.timer-wrapper {
  margin-top: 60px;
  text-align: center;
}

.timer {
  display: inline-block;
  width: 120px;
  height: 120px;
  border-radius: 60px;
  border: 5px solid black;
  font-size: 40px;
  text-align: center;
  line-height: 110px;
  font-weight: bolder;
}

.tip {
  font-size: 32px;
  font-weight: bold;
  text-align: center;
  margin-top: 20px;
}

.tip2 {
  font-size: 28px;
  color: #999;
  text-align: center;
  margin-top: 66px;
}

.btn-wrapper {
  margin-top: 100px;
  padding: 0 40px;
  display: flex;
  justify-content: space-between;
}

.btn2 {
  width: 320px;
  height: 88px;
  background: #fff;
  border: 1px solid #ccc;
  border-radius: 44px;
  font-size: 32px;
  text-align: center;
  line-height: 88px;
}

.ok {
  background: white !important;
  color: black !important;
}
</style>