支付
渲染基础数据
支付页有俩个关键数据,一个是要支付的钱数
,一个是倒计时数据
(超时不支付商品释放)
- 准备接口
import request from '@/utils/http'
export const getOrderAPI = (id) => {
return request({
url: `/member/order/${id}`
})
}
- 获取数据渲染内容
<script setup>
import { getOrderAPI } from '@/apis/pay'
import { onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'
// 获取订单数据
const route = useRoute()
const payInfo = ref({})
const getPayInfo = async () => {
const res = await getOrderAPI(route.query.id)
payInfo.value = res.result
}
onMounted(() => getPayInfo())
</script>
<template>
<div class="xtx-pay-page">
<div class="container">
<!-- 付款信息 -->
<div class="pay-info">
<span class="icon iconfont icon-queren2"></span>
<div class="tip">
<p>订单提交成功!请尽快完成支付。</p>
<p>支付还剩 <span>{{ formatTime }}</span>, 超时后将取消订单</p>
</div>
<div class="amount">
<span>应付总额:</span>
<span>¥{{ payInfo.payMoney?.toFixed(2) }}</span>
</div>
</div>
<!-- 付款方式 -->
<div class="pay-type">
<p class="head">选择以下支付方式付款</p>
<div class="item">
<p>支付平台</p>
<a class="btn wx" href="javascript:;"></a>
<a class="btn alipay" :href="payUrl"></a>
</div>
<div class="item">
<p>支付方式</p>
<a class="btn" href="javascript:;">招商银行</a>
<a class="btn" href="javascript:;">工商银行</a>
<a class="btn" href="javascript:;">建设银行</a>
<a class="btn" href="javascript:;">农业银行</a>
<a class="btn" href="javascript:;">交通银行</a>
</div>
</div>
</div>
</div>
</template>
实现支付功能
支付业务流程
- 支付携带参数
// 支付地址
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}`
- 支付宝沙箱账号信息
支付结果展示
业务需求理解
- 准备模版
<script setup>
</script>
<template>
<div class="xtx-pay-page">
<div class="container">
<!-- 支付结果 -->
<div class="pay-result">
<span class="iconfont icon-queren2 green"></span>
<span class="iconfont icon-shanchu red"></span>
<p class="tit">支付成功</p>
<p class="tip">我们将尽快为您发货,收货期间请保持手机畅通</p>
<p>支付方式:<span>支付宝</span></p>
<p>支付金额:<span>¥200.00</span></p>
<div class="btn">
<el-button type="primary" style="margin-right:20px">查看订单</el-button>
<el-button>进入首页</el-button>
</div>
<p class="alert">
<span class="iconfont icon-tip"></span>
温馨提示:小兔鲜儿不会以订单异常、系统升级为由要求您点击任何网址链接进行退款操作,保护资产、谨慎操作。
</p>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.pay-result {
padding: 100px 0;
background: #fff;
text-align: center;
margin-top: 20px;
>.iconfont {
font-size: 100px;
}
.green {
color: #1dc779;
}
.red {
color: $priceColor;
}
.tit {
font-size: 24px;
}
.tip {
color: #999;
}
p {
line-height: 40px;
font-size: 16px;
}
.btn {
margin-top: 50px;
}
.alert {
font-size: 12px;
color: #999;
margin-top: 50px;
}
}
</style>
- 绑定路由
{
path: 'paycallback', // 注意路径,必须是paycallback
component: PayBack
},
- 渲染数据
<script setup>
import { getOrderAPI } from '@/apis/pay'
import { onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const orderInfo = ref({})
const getOrderInfo = async () => {
const res = await getOrderAPI(route.query.orderId)
orderInfo.value = res.result
}
onMounted(() => getOrderInfo())
</script>
<template>
<div class="xtx-pay-page">
<div class="container">
<!-- 支付结果 -->
<div class="pay-result">
<!-- 路由参数获取到的是字符串而不是布尔值 -->
<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>¥{{ orderInfo.payMoney?.toFixed(2) }}</span></p>
<div class="btn">
<el-button type="primary" style="margin-right:20px">查看订单</el-button>
<el-button>进入首页</el-button>
</div>
<p class="alert">
<span class="iconfont icon-tip"></span>
温馨提示:小兔鲜儿不会以订单异常、系统升级为由要求您点击任何网址链接进行退款操作,保护资产、谨慎操作。
</p>
</div>
</div>
</div>
</template>
封装倒计时函数
理解需求
编写一个函数useCountDown可以把秒数格式化为倒计时的显示状态
,函数使用样例如下:
- formatTime为显示的倒计时时间
- start是倒计时启动函数,调用时可以
设置初始值并且开始倒计时
实现思路分析
// 封装倒计时逻辑函数
import { computed, onUnmounted, ref } from 'vue'
import dayjs from 'dayjs'
export const useCountDown = () => {
// 1. 响应式的数据
let timer = null
const time = ref(0)
// 格式化时间 为 xx分xx秒
const formatTime = computed(() => dayjs.unix(time.value).format('mm分ss秒'))
// 2. 开启倒计时的函数
const start = (currentTime) => {
// 开始倒计时的逻辑
// 核心逻辑的编写:每隔1s就减一
time.value = currentTime
timer = setInterval(() => {
time.value--
}, 1000)
}
// 组件销毁时清除定时器
onUnmounted(() => {
timer && clearInterval(timer)
})
return {
formatTime,
start
}
}