黑马程序员前端 Vue3 小兔鲜电商项目——(十一)支付页


image.png

支付页有俩个关键数据,一个是要支付的钱数,一个是倒计时数据(超时不支付商品释放)。

基础数据渲染

封装接口

在 src\apis\pay.js 文件中添加获取订单信息的接口,参数为订单 id:

import request from '@/utils/http'

export const getOrderAPI = (id) => {
    
    
  return request({
    
    
    url: `/member/order/${
      
      id}`
  })
}

数据渲染

在 src\views\Pay\index.vue 中调用封装好的接口,获取订单信息,并进行渲染:

<script setup>
import { ref, onMounted } from 'vue'
import { getOrderAPI } from '@/apis/pay'
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>

支付功能实现

支付携带参数

src\views\Pay\index.vue 中添加支付参数,拼接成为支付链接地址:

// 支付地址
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>

支付宝沙箱账号信息

支付宝沙箱支付要求升级了,原有的账号不能继续使用,沙箱新账号如下:

账号 [email protected]
登录密码 111111
支付密码 111111

使用支付宝沙箱进行支付测试,付款时登录支付宝账号。

支付结果页展示

模版代码

新建 src\views\Pay\PayBack.vue 文件,粘贴一下代码,显示支付结果信息:

<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>

绑定路由

src\router\index.js 中添加支付结果页面得路由,必须是 ‘/paycallback’,此处需要和支付回调得地址相同:

{
    
    
  path: 'paycallback', // 注意路径,必须是paycallback
  component: PayBack
}

渲染数据

在 src\views\Pay\PayBack.vue 中调用订单接口通过订单id参数获取订单信息,渲染数据到页面:

<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>

倒计时逻辑函数封装

安装时间格式化插件:

npm i dayjs

新建 src\composables\useCountDown.js 文件并编写一个函数 useCountDown 可以把秒数格式化为倒计时的显示状态:

// 封装倒计时逻辑函数
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
  }
}

在 src\views\Pay\index.vue 中调用倒计时函数:

import {
    
     useCountDown } from '@/composables/useCountDown'

const {
    
     formatTime, start } = useCountDown
//获取订单数据
const route = useRoute()
const payInfo = ref({
    
    })
const getPayInfo = async () => {
    
    
    const res = await getOrderAPI(route.query.id)
    payInfo.value = res.result
    //初始化倒计时秒数
    start(res.result.countdown)
}

并在模板代码中进行渲染:

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

猜你喜欢

转载自blog.csdn.net/qq_20185737/article/details/131400026
今日推荐