成功充值-2

This commit is contained in:
yml
2026-06-03 16:29:52 +08:00
parent ae8928f458
commit eb7c0045cd
3 changed files with 481 additions and 29 deletions
+162 -29
View File
@@ -1,6 +1,7 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ElMessage } from 'element-plus'
import QRCode from 'qrcode'
import {
fetchWalletBalance,
@@ -22,6 +23,10 @@ const currentPageSize = ref(20)
const total = ref(0)
const rechargeAmount = ref(100)
const recharging = ref(false)
const rechargeDialogVisible = ref(false)
const activeRechargePayment = ref<PaymentOrder | null>(null)
const rechargeQRCodeURL = ref('')
const qrGenerating = ref(false)
onMounted(loadWallet)
@@ -53,7 +58,7 @@ async function handleRecharge() {
if (payment.paid) {
ElMessage.success('充值成功')
} else {
await showRechargePaymentDialog(payment)
showRechargePaymentDialog(payment)
}
await loadWallet()
} catch (error) {
@@ -63,39 +68,37 @@ async function handleRecharge() {
}
}
async function showRechargePaymentDialog(payment: PaymentOrder) {
const payURL = payment.jspay_url || payment.td_code || payment.jspay_info || ''
const message = payURL
? `充值支付单已创建,金额 ¥${(payment.amount_cent / 100).toFixed(2)}\n\n${payURL}`
: '充值支付单已创建,请完成付款后刷新状态。'
await ElMessageBox.confirm(message, '支付充值', {
confirmButtonText: payURL ? '打开/复制' : '刷新状态',
cancelButtonText: '刷新状态',
distinguishCancelAndClose: true,
})
.then(async () => {
if (payURL) {
await openOrCopyPayURL(payURL)
}
await refreshRechargePayment(payment.id)
})
.catch(async (action) => {
if (action === 'cancel') {
await refreshRechargePayment(payment.id)
}
})
function showRechargePaymentDialog(payment: PaymentOrder) {
activeRechargePayment.value = payment
rechargeDialogVisible.value = true
renderRechargeQRCode(payment)
}
async function openOrCopyPayURL(payURL: string) {
if (/^https?:\/\//.test(payURL)) {
window.open(payURL, '_blank')
function rechargePayURL(payment = activeRechargePayment.value) {
return payment?.jspay_url || payment?.td_code || payment?.jspay_info || ''
}
async function renderRechargeQRCode(payment = activeRechargePayment.value) {
const payURL = rechargePayURL(payment)
rechargeQRCodeURL.value = ''
if (!payURL) {
return
}
qrGenerating.value = true
try {
await navigator.clipboard?.writeText(payURL)
ElMessage.success('支付链接已复制')
rechargeQRCodeURL.value = await QRCode.toDataURL(payURL, {
width: 240,
margin: 1,
errorCorrectionLevel: 'M',
color: {
dark: '#111827',
light: '#ffffff',
},
})
} catch {
ElMessage.warning('请手动复制支付链接')
ElMessage.error('二维码生成失败,请复制链接后扫码支付')
} finally {
qrGenerating.value = false
}
}
@@ -103,11 +106,22 @@ async function refreshRechargePayment(paymentID: number) {
const payment = await queryWalletRechargePayment(paymentID)
if (payment.paid) {
ElMessage.success('充值成功')
rechargeDialogVisible.value = false
await loadWallet()
} else {
activeRechargePayment.value = payment
await renderRechargeQRCode(payment)
ElMessage.info('支付未完成')
}
}
async function handleRefreshRechargePayment() {
if (!activeRechargePayment.value) {
return
}
await refreshRechargePayment(activeRechargePayment.value.id)
}
function readError(error: unknown, fallback: string) {
if (typeof error === 'object' && error && 'response' in error) {
const response = (error as { response?: { data?: { message?: string } } }).response
@@ -174,6 +188,38 @@ function readError(error: unknown, fallback: string) {
@size-change="handleSizeChange"
/>
</div>
<el-dialog
v-model="rechargeDialogVisible"
title="支付充值"
width="520px"
append-to-body
:z-index="4000"
class="wallet-pay-dialog"
>
<div v-if="activeRechargePayment" class="pay-dialog-body">
<div class="pay-summary">
<span>充值金额</span>
<strong>¥{{ (activeRechargePayment.amount_cent / 100).toFixed(2) }}</strong>
</div>
<div v-if="rechargePayURL()" class="pay-qr-panel">
<div class="pay-qr-box">
<el-icon v-if="qrGenerating" class="is-loading" :size="32"><Loading /></el-icon>
<img v-else-if="rechargeQRCodeURL" :src="rechargeQRCodeURL" alt="充值支付二维码" />
</div>
<div class="pay-scan-copy">
<strong>请使用微信或支付宝扫码支付</strong>
<span>不要在电脑浏览器直接打开该链接扫码完成后点击我已支付刷新充值状态</span>
</div>
</div>
<p v-else class="pay-hint">充值支付单已创建请完成付款后刷新状态</p>
</div>
<template #footer>
<div class="pay-dialog-footer">
<el-button type="primary" @click="handleRefreshRechargePayment">我已支付刷新状态</el-button>
</div>
</template>
</el-dialog>
</section>
</template>
@@ -190,4 +236,91 @@ function readError(error: unknown, fallback: string) {
margin: 0;
font-size: 16px;
}
.pay-dialog-body {
display: grid;
gap: 14px;
}
.pay-summary {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
padding: 12px 14px;
border-radius: 8px;
background: #f7f9fc;
color: #64748b;
}
.pay-summary strong {
color: #111a44;
font-size: 22px;
}
.pay-qr-panel {
display: grid;
grid-template-columns: 240px minmax(0, 1fr);
align-items: center;
gap: 20px;
padding: 18px;
border-radius: 8px;
background: #f8fafc;
}
.pay-qr-box {
width: 240px;
height: 240px;
display: grid;
place-items: center;
border: 1px solid #e2e8f0;
border-radius: 8px;
background: #ffffff;
}
.pay-qr-box img {
width: 220px;
height: 220px;
display: block;
}
.pay-scan-copy {
display: grid;
gap: 8px;
color: #334155;
}
.pay-scan-copy strong {
color: #111a44;
font-size: 18px;
}
.pay-scan-copy span {
color: #64748b;
line-height: 1.7;
}
.pay-hint {
margin: 0;
color: #64748b;
}
.pay-dialog-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
}
:global(.wallet-pay-dialog) {
position: relative;
z-index: 4001;
}
@media (max-width: 720px) {
.pay-qr-panel {
grid-template-columns: 1fr;
justify-items: center;
text-align: center;
}
}
</style>