Vue項目實戰:訂單結算功能實現

目錄

在這裏插入圖片描述

(1)訂單詳情數據加載

在orderPay.vue中:

<p>
    訂單詳情
    <em class="icon-down up" :class="{'up': showDetail}" @click="showDetail=!showDetail"></em>  <!--控制訂單詳情是否展示-->
</p>
<script>
export default {
  data() {
    return {
      orderId: this.$route.query.orderNo,
      addressInfo: "", //收貨人地址
      orderDetail: [], //訂單詳情,包含商品列表
      showDetail: false, //是否顯示訂單詳情
      payment:0
    };
  },
  mounted() {
    this.getOrderDetail();
  },
  methods: {
    getOrderDetail() {
      this.axios.get(`/orders/${this.orderId}`).then(res => {
        let item = res.shippingVo;
        this.addressInfo = `${item.receiverName} ${item.receiverMobile} ${item.receiverProvince} ${item.receiverCity} ${item.recevierDistrict} ${item.receiverAddress}`;
        this.orderDetail = res.orderItemVoList;
        this.payment:0,//訂單總金額
      });
    }
  }
};
</script>

(2)支付寶支付對接

在orderPay頁面中點擊 支付寶支付 後,頁面跳轉到支付寶支付頁面alipay。

  • 在orderPay.vue中:
<!--省略了很多代碼-->
<div class="pay-way">
     <p>支付平臺</p>
<div class="pay pay-ali" :class="{'checked' : payType == 1}" @click="paySubmit(1)"></div>
     <div class="pay pay-wechat" :class="{'checked': payType == 2}" @click="paySubmit(2)"></div>
</div>
<script>
export default {
  data() {
    return {
      payType: '', //支付類型
    };
  },

  methods: {
    paySubmit(payType) {
      if (payType == 1) {
        window.open("/#/order/alipay?orderId =" + this.orderId, "_blank");
      }
    }
  }
};
</script>
  • 在alipay.vue中:
<template>
    <div class="ali-pay">
        <div class="form" v-html="coutent"></div>  
    </div>
</template>
<script>
import Loading from './../components/Loading';
export default {
    name: 'alipay',
    data() {
        return {
            orderId: this.$route.query.orderNo,
            content: '' //支付寶返回給前端的源碼
        }
    },
    components: {
        Loading
    },
    mounted() {
        this.paySubumit();
    },
    methods: {
        paySubumit() {
            this.axios.post('/pay', {
                orderId: this.orderId,
                orderName: 'Vue高仿小米商城',
                amount: 0.01, //單位元
                payType: 1 //1支付寶, 2微信
            }).then((res) => {
                this.content = res.coutent;
                setTimeout(() => {
                    document.form[0].submit();
                }, 100)
            })
        }
    }
}
</script>

(3)微信支付對接

點擊 微信支付 後,會出現微信支付圖片彈窗。其中的二維碼是通過qrcode插件將後端返回的字符串轉換來的 。

  • 在orderPay.vue中:
 <scan-pay-code v-if="showPay" @click="closePayModal" :img="payImg"></scan-pay-code>
<script>
import ScanPayCode from "./../components/ScanPayCode";
import QRCode from 'qrcode';
export default {
  data() {
    return {
      showPay: false, //是否顯示微信支付彈框
      payType: "" //支付類型
      payImg: '' //微信支付的二維碼地址 
    };
  },
  components: {
    ScanPayCode
  },
  methods: {
    // 關閉微信彈框
    closePayModal() {
      this.showPay = false;
    },
    paySubmit(payType) {
      if (payType == 1) {
        window.open("/#/order/alipay?orderId =" + this.orderId, "_blank");
      } else {
          this.axios.post('/pay', {
              orderId:this.orderId,
              orderName: 'Vue高仿小米商城',
              amount: 0.01,
              payType: 2
          }).then((res) => {
              QRCode.toDataURL(res.content).then(url => {
                  this.showPay = true;
                  this.payImg = url;
              }).catch( () => {
                  this.$message.error("微信二維碼生成失敗")
              })
          })
      }
    }
  }
};
</script>
  • 在ScanPayCode.vue中:
<template>
  <div class="scan">
    <div class="mask"></div>
    <div class="item-wrap">
      <div class="img-scan"></div>
      <div class="img-pay">
        <div class="title">微信支付<em @click="close"></em></div>
        <div class="qrcode"><img :src="img"></div>
        <div class="tip">
          <p>請使用<span class="theme-color">微信</span>掃一掃</p>
          <p>二維碼完成支付</p>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
  export default{
    name:'scan-pay-code',
    props:['img'],
    methods:{
      close(){
        this.$emit('close');
      }
    }
  }
</script>

(4)微信支付轉態輪詢

在支付彈窗出現後,可能出現兩種情況,一種是用戶沒有完成支付就關閉支付彈窗。另一種是用戶支付完成,自動跳轉到訂單列表。

爲了防止由於網絡延時導致用戶支付完成但未自動跳轉,而用戶又把支付彈窗關閉了,所以添加一個支付確認彈框,在支付彈窗關閉後會出現支付確認彈框,讓用戶手動選擇是否完成支付,如果選擇用戶支付確認彈框中 “查看訂單” (表示自己已經完成支付)後會查詢是否真的已支付,如果已支付就跳轉到訂單列表。

另外爲了用戶體驗,添加訂單輪詢,實時獲取當前用戶支付狀態,在用戶支付完成後跳轉到訂單列表,而無需手動關閉彈窗和再次確認。

  • 在orderPay.vue中:
    <modal
      title="支付確認"
      btnType="3"
      :showModal="showPayModal"
      sureText="查看訂單" 
      cancelText="未支付"
      @cancel="showPayModal=false"
      @submit="goOrderList"
    >
      <template v-slot:body>
        <p>您確認是否完成支付?</p>
      </template>
    </modal>

<script>
import Modal from './../components/Modal'
export default{
  name:'order-pay',
  data(){
    return {
      showPayModal:false,//是否顯示二次支付確認彈框
      payment:0,//訂單總金額
      T:''//定時器ID
    }
  },
  components:{
    Modal
  },
  methods:{
    paySubmit(payType){
      if(payType == 1){
        window.open('/#/order/alipay?orderId='+this.orderId,'_blank');
      }else{
        this.axios.post('/pay',{
          orderId:this.orderId,
          orderName:'Vue高仿小米商城',
          amount:0.01,//單位元
          payType:2 //1支付寶,2微信
        }).then((res)=>{
          QRCode.toDataURL(res.content)
          .then(url => {
            this.showPay = true;
            this.payImg = url;
            this.loopOrderState();
          })
          .catch(() => {
            this.$message.error('微信二維碼生成失敗,請稍後重試');
          })
        })
      }
    },
    // 關閉微信彈框
    closePayModal(){
      this.showPay = false;
      this.showPayModal = true;
      clearInterval(this.T);
    },
    // 輪詢當前訂單支付狀態
    loopOrderState(){
      this.T = setInterval(()=>{ 
        this.axios.get(`/orders/${this.orderId}`).then((res)=>{
          if(res.status == 20){
            clearInterval(this.T);
            this.goOrderList();
          }
        })
      },1000);
    },
    goOrderList(){
      this.$router.push('/order/list');
    }      
  }
}
</script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章