diff --git a/src/pages/finance/Wallet.vue b/src/pages/finance/Wallet.vue
index 9aeb3f6..1ae67fd 100644
--- a/src/pages/finance/Wallet.vue
+++ b/src/pages/finance/Wallet.vue
@@ -429,6 +429,7 @@
:close-on-click-modal="false"
:close-on-press-escape="false"
class="qr-code-dialog"
+ @close="handleQrCodeDialogClose"
>
@@ -437,6 +438,7 @@
请使用微信扫描上方二维码完成支付
支付金额:¥{{ formatPrice(wechatForm.amount) }}
正在确认支付状态,请稍候...
+
关闭窗口后将继续确认支付结果,请勿重复支付
关闭
@@ -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
- // 不显示错误,继续轮询
}
}
diff --git a/src/pages/finance/WalletProcessing.vue b/src/pages/finance/WalletProcessing.vue
index 1e255f2..1392f83 100644
--- a/src/pages/finance/WalletProcessing.vue
+++ b/src/pages/finance/WalletProcessing.vue
@@ -119,7 +119,7 @@
{{ orderInfo.out_trade_no }}
+
+
+
+ 若您已完成支付,余额通常会在几分钟内到账,请稍后刷新钱包查看。
+
+
+
+
+
+ 订单号:
+ {{ orderInfo.out_trade_no }}
+
+
+ 金额:
+ ¥{{ orderInfo.amount }}
+
+
+
+
+
+
+
+
+
+
@@ -291,12 +342,16 @@ export default {
const orderStatus = ref('processing')
const isProcessing = ref(true)
const pollCount = ref(0)
- const maxPollCount = ref(30) // 最多轮询30次
+ const maxPollCount = ref(36) // 最多轮询36次(约3分钟)
+ const pollIntervalMs = 5000 // 每5秒查询一次,避免过于频繁
const pollInterval = ref(null)
// 获取URL参数
const outTradeNo = route.query.out_trade_no
const amount = route.query.amount
+ const paymentType = route.query.payment_type === 'wechat' ? 'wechat' : 'alipay'
+ const isWechatPay = computed(() => paymentType === 'wechat')
+ const tradeNoLabel = computed(() => (isWechatPay.value ? '微信交易号' : '支付宝交易号'))
// 初始化订单信息
orderInfo.value = {
@@ -304,6 +359,15 @@ export default {
amount: amount,
}
+ const normalizeOrderData = (data) => {
+ if (!data) return data
+ return {
+ ...data,
+ amount: data.amount ?? amount,
+ trade_no: data.trade_no || data.transaction_id || null,
+ }
+ }
+
// 格式化时间
const formatTime = (timeStr) => {
if (!timeStr) return '暂无'
@@ -313,41 +377,45 @@ export default {
// 查询订单状态
const queryOrderStatus = async () => {
try {
- const response = await financeApi.getAlipayOrderStatus({ out_trade_no: outTradeNo })
- orderInfo.value = response.data
- // 根据状态更新页面
+ const response = isWechatPay.value
+ ? await financeApi.getWechatOrderStatus({ out_trade_no: outTradeNo })
+ : await financeApi.getAlipayOrderStatus({ out_trade_no: outTradeNo })
+
+ if (!response?.data) return
+
+ orderInfo.value = normalizeOrderData(response.data)
+
if (response.data.status === 'success') {
orderStatus.value = 'success'
isProcessing.value = false
stopPolling()
- } else if (response.data.status === 'failed') {
+ } else if (response.data.status === 'failed' || response.data.status === 'closed') {
orderStatus.value = 'failed'
isProcessing.value = false
stopPolling()
- } else if (response.data.status === 'pending') {
- // 继续轮询,轮询次数在setInterval中已经增加
- if (pollCount.value >= maxPollCount.value) {
- // 超过最大轮询次数,停止轮询
- stopPolling()
- // 可以显示超时提示
- }
+ } else if (pollCount.value >= maxPollCount.value) {
+ orderStatus.value = 'timeout'
+ isProcessing.value = false
+ stopPolling()
}
} catch (error) {
console.error('查询订单状态失败:', error)
- // 查询失败时继续轮询,不要停止
+ if (pollCount.value >= maxPollCount.value) {
+ orderStatus.value = 'timeout'
+ isProcessing.value = false
+ stopPolling()
+ }
}
}
// 开始轮询
const startPolling = () => {
- // 立即查询一次
queryOrderStatus()
- // 每3秒查询一次
pollInterval.value = setInterval(() => {
- pollCount.value++ // 增加轮询次数
+ pollCount.value++
queryOrderStatus()
- }, 3000)
+ }, pollIntervalMs)
}
// 停止轮询
@@ -368,10 +436,13 @@ export default {
}
const retryPayment = () => {
- // 重新创建支付订单
router.push({
path: '/finance/wallet',
- query: { retry: 'true', amount: amount },
+ query: {
+ retry: 'true',
+ amount: amount,
+ method: isWechatPay.value ? 'wechat' : 'alipay',
+ },
})
}
@@ -404,6 +475,7 @@ export default {
isProcessing,
pollCount,
maxPollCount,
+ tradeNoLabel,
formatTime,
goToWallet,
goToRechargeRecords,