前端学习笔记 7:小兔鲜-支付

时间:2024-01-23 08:59:01

渲染数据

封装接口apis/pay.js

import http from '@/utils/http'

export const getOrderInfoService = (id) => {
    return http.get(`/member/order/${id}`)
}

渲染数据到支付页:

<script setup>
import { getOrderInfoService } from '@/apis/pay'
import { ref } from "vue";
import { useRoute } from 'vue-router'
const payInfo = ref({})
const route = useRoute()
const loadPayInfo = async () => {
    const res = await getOrderInfoService(route.query.id)
    payInfo.value = res.result
}
loadPayInfo()
</script>

支付

拼接支付地址:

// 支付地址
const baseURL = 'http://pcapi-xiaotuxian-front-devtest.itheima.net/'
const backURL = 'http://127.0.0.1:5173/paycallback'
const redirectUrl = encodeURIComponent(backURL)
const payUrl = `${baseURL}pay/aliPay?orderId=${route.query.id}&redirect=${redirectUrl}

让支付链接使用该地址:

<a class="btn alipay" :href="payUrl"></a>

点击链接即可跳转到支付宝沙箱环境支付。

黑马程序员提供的沙箱账号已经没有余额,无法进行后续步骤。

支付结果展示

新建支付结果页views/pay/PayBack.vue,基本代码见这里

获取订单数据:

<script setup>
import { ref } from 'vue';
import { getOrderInfoService } from '@/apis/pay'
import { useRoute } from 'vue-router'
const route = useRoute()
const payInfo = ref({})
const loadPayInfo = async () => {
    const res = await getOrderInfoService(route.query.orderId)
    payInfo.value = res.result
}
loadPayInfo()
</script>

渲染数据:

<span class="iconfont icon-queren2 green" v-if="$route.query.payResult === 'true'"></span>
<span class="iconfont icon-shanchu red" v-else></span>
<p class="tit">支付{{ $route.query.payResult === 'true' ? '成功' : '失败' }}</p>
<p class="tip">我们将尽快为您发货,收货期间请保持手机畅通</p>
<p>支付方式:<span>支付宝</span></p>
<p>支付金额:<span>¥{{ payInfo.payMoney?.toFixed(2) }}</span></p>

倒计时

待支付页面有个倒计时,编写一个第三方倒计时组件composables/timer.js

import { ref, onUnmounted, computed } from 'vue'
import { dayjs } from 'element-plus'

// 计时器
export const useTimer = () => {
    const leftSeconds = ref(0)
    const formatTime = computed(() => {
        return dayjs.unix(leftSeconds.value).format('mm分ss秒')
    })
    const start = (totalSeconds) => {
        if(totalSeconds<=0){
            return
        }
        leftSeconds.value = totalSeconds
        let interval = setInterval(() => {
            leftSeconds.value--
            if (leftSeconds.value <= 0) {
                clearInterval(interval)
            }
        }, 1000)
        // 如果控件销毁时还存在定时任务,结束
        onUnmounted(() => {
            if (interval) {
                clearInterval(interval)
            }
        })
    }
    return { formatTime, start }
}

修改待支付页面pay/index.vue,启动计时器:

const timer = useTimer()
const loadPayInfo = async () => {
    const res = await getOrderInfoService(route.query.id)
    payInfo.value = res.result
    timer.start(payInfo.value.countdown)
}

渲染计时器:

<p>支付还剩 <span>{{ timer.formatTime }}</span>, 超时后将取消订单</p>