成功充值-2
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user