This commit is contained in:
Mrx
2026-06-08 15:28:53 +08:00
parent 47981086a5
commit 958139d149
2 changed files with 173 additions and 40 deletions

View File

@@ -429,6 +429,7 @@
:close-on-click-modal="false"
:close-on-press-escape="false"
class="qr-code-dialog"
@close="handleQrCodeDialogClose"
>
<div class="qr-code-container">
<div class="qr-code-wrapper">
@@ -437,6 +438,7 @@
<p class="qr-code-tip">请使用微信扫描上方二维码完成支付</p>
<p class="qr-code-amount">支付金额¥{{ formatPrice(wechatForm.amount) }}</p>
<p v-if="isCheckingPayment" class="qr-code-checking">正在确认支付状态请稍候...</p>
<p class="qr-code-tip">关闭窗口后将继续确认支付结果请勿重复支付</p>
<el-button type="primary" @click="closeQrCodeDialog" class="close-qr-btn">关闭</el-button>
</div>
</el-dialog>
@@ -476,6 +478,11 @@ const showQrCodeDialog = ref(false)
const qrCodeCanvas = ref(null)
const currentWechatOrderNo = ref(null)
const isCheckingPayment = ref(false)
const wechatPaymentResolved = ref(false)
const skipQrCloseRedirect = ref(false)
const wechatDialogPollCount = ref(0)
const WECHAT_POLL_INTERVAL_MS = 5000
const WECHAT_DIALOG_MAX_POLL_COUNT = 12 // 弹窗内最多轮询12次约1分钟之后跳转处理页
let wechatOrderPollTimer = null
// 钱包信息
@@ -993,26 +1000,78 @@ const showQrCode = async (codeUrl) => {
}
}
// 关闭二维码弹窗
// 关闭二维码弹窗(用户主动关闭,跳转处理页继续轮询)
const closeQrCodeDialog = () => {
stopWechatOrderPolling()
showQrCodeDialog.value = false
}
const handleQrCodeDialogClose = () => {
if (wechatPaymentResolved.value) {
wechatPaymentResolved.value = false
stopWechatOrderPolling()
currentWechatOrderNo.value = null
isCheckingPayment.value = false
wechatDialogPollCount.value = 0
return
}
if (skipQrCloseRedirect.value) {
skipQrCloseRedirect.value = false
isCheckingPayment.value = false
wechatDialogPollCount.value = 0
return
}
const orderNo = currentWechatOrderNo.value
const orderAmount = wechatForm.amount
stopWechatOrderPolling()
currentWechatOrderNo.value = null
isCheckingPayment.value = false
wechatDialogPollCount.value = 0
if (orderNo) {
router.push({
path: '/finance/wallet/processing',
query: {
out_trade_no: orderNo,
amount: orderAmount,
payment_type: 'wechat',
},
})
}
}
const redirectToWechatProcessingPage = () => {
const orderNo = currentWechatOrderNo.value
const orderAmount = wechatForm.amount
if (!orderNo) return
stopWechatOrderPolling()
skipQrCloseRedirect.value = true
currentWechatOrderNo.value = null
wechatDialogPollCount.value = 0
showQrCodeDialog.value = false
isCheckingPayment.value = false
router.push({
path: '/finance/wallet/processing',
query: {
out_trade_no: orderNo,
amount: orderAmount,
payment_type: 'wechat',
},
})
}
// 开始轮询微信订单状态
const startWechatOrderPolling = () => {
// 清除之前的定时器
stopWechatOrderPolling()
// 立即检查一次
wechatDialogPollCount.value = 0
checkWechatOrderStatus()
// 每3秒轮询一次
wechatOrderPollTimer = setInterval(() => {
wechatDialogPollCount.value++
checkWechatOrderStatus()
}, 3000)
}, WECHAT_POLL_INTERVAL_MS)
}
// 停止轮询
@@ -1029,47 +1088,49 @@ const checkWechatOrderStatus = async () => {
return
}
if (wechatDialogPollCount.value >= WECHAT_DIALOG_MAX_POLL_COUNT) {
redirectToWechatProcessingPage()
return
}
try {
isCheckingPayment.value = true
const response = await callProtectedAPI(financeApi.getWechatOrderStatus, {
const response = await financeApi.getWechatOrderStatus({
out_trade_no: currentWechatOrderNo.value
})
if (!response || !response.data) {
if (!response?.data) {
isCheckingPayment.value = false
return
}
const orderStatus = response.data.status
// 订单状态pending, success, failed, closed
if (orderStatus === 'success') {
// 支付成功
wechatPaymentResolved.value = true
stopWechatOrderPolling()
isCheckingPayment.value = false
closeQrCodeDialog()
showQrCodeDialog.value = false
ElMessage.success('充值成功!')
// 刷新钱包余额
await loadWalletInfo()
// 重置表单
wechatForm.amount = ''
selectedPresetAmount.value = null
currentWechatOrderNo.value = null
wechatDialogPollCount.value = 0
} else if (orderStatus === 'failed' || orderStatus === 'closed') {
// 支付失败或关闭
wechatPaymentResolved.value = true
stopWechatOrderPolling()
isCheckingPayment.value = false
showQrCodeDialog.value = false
ElMessage.error('支付失败,请重新支付')
closeQrCodeDialog()
currentWechatOrderNo.value = null
wechatDialogPollCount.value = 0
} else {
// pending 状态继续轮询
isCheckingPayment.value = false
}
} catch (error) {
console.error('查询微信订单状态失败:', error)
isCheckingPayment.value = false
// 不显示错误,继续轮询
}
}