index.vue 3.14 KB
<template>
  <view class="waiting-page">
    <view class="waiting-content">
      <view>
        <IconFont name="clock" size="80rpx" color="#A67939" />
      </view>
      <view style="margin: 32rpx 0">支付中</view>
      <view>{{ current.seconds }} s</view>
      <view
        style="
          margin: 48rpx 0;
          font-size: 27rpx;
          color: #a67939;
          text-align: center;
          line-height: 2;
        "
      >
        温馨提示:{{ pay_msg }}<br />
      </view>
    </view>
    <view class="go-back-wrapper">
      <nut-button @click="goBackBtn" color="#A67939" block>返回首页</nut-button>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import Taro, { useRouter } from '@tarojs/taro'
import { IconFont } from '@nutui/icons-vue-taro'
import { billPayStatusAPI } from '@/api/index'
import { useGo } from '@/hooks/useGo'

const router = useRouter()
const go = useGo()

const remaining = ref(10)
const current = ref({ seconds: 10 })

// Ensure params are available. Taro.useRouter() might need time or be called in setup.
// router.params is reactive in some Taro versions, or just an object.
const pay_id = router.params.pay_id
const pay_msg = ref('支付可能需要10s左右,请耐心等待')

const PAY_STATUS = {
  PAY: '1',
  PAYING: '2',
  FAIL: '7',
  SUCCESS: '3'
}

let timer = null
let countdownTimer = null

const startCountdown = () => {
  countdownTimer = setInterval(() => {
    if (remaining.value > 0) {
      remaining.value--
      current.value.seconds = remaining.value
    } else {
      clearInterval(countdownTimer)
    }
  }, 1000)
}

const checkStatus = async () => {
  if (!pay_id) {
    return
  }
  try {
    const { code, data } = await billPayStatusAPI({ pay_id })
    // TAG:轮询支付回调
    if (data) {
      switch (data.status) {
        case PAY_STATUS.PAY:
          pay_msg.value = '订单待支付'
          break
        case PAY_STATUS.PAYING:
          pay_msg.value = '订单支付中'
          break
        case PAY_STATUS.SUCCESS:
          // 预约成功页面
          // Replace to avoid back button loop
          go(`/pages/success/index?pay_id=${pay_id}`, 'replace')
          break
        case PAY_STATUS.FAIL:
          pay_msg.value = '订单支付失败'
          break
      }
    }
  } catch (error) {
    console.error('Check status error:', error)
  }
}

onMounted(() => {
  startCountdown()
  // Immediate check
  checkStatus()
  timer = setInterval(async () => {
    if (remaining.value <= 0) {
      clearInterval(timer)
    }
    await checkStatus()
  }, 1000)
})

onUnmounted(() => {
  if (timer) {
    clearInterval(timer)
  }
  if (countdownTimer) {
    clearInterval(countdownTimer)
  }
})

const goBackBtn = () => {
  go('/pages/index/index')
}
</script>

<style lang="less">
.waiting-page {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #fff;
  align-items: center;
  padding-top: 96rpx;

  .waiting-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    font-size: 32rpx;
    color: #333;
  }

  .go-back-wrapper {
    width: 80%;
    margin-top: 64rpx;
  }
}
</style>