2025-11-24 16:06:44 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div class="list-page-container">
|
|
|
|
|
|
<div class="list-page-card">
|
|
|
|
|
|
<!-- 页面头部 -->
|
|
|
|
|
|
<div class="list-page-header">
|
|
|
|
|
|
<div class="flex justify-between items-start">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<h1 class="list-page-title">钱包充值</h1>
|
|
|
|
|
|
<p class="list-page-subtitle">选择充值方式,为您的钱包添加余额</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="list-page-wrapper">
|
|
|
|
|
|
<!-- 钱包余额信息 -->
|
|
|
|
|
|
<div class="wallet-info-section">
|
|
|
|
|
|
<div class="wallet-balance-card" :class="getBalanceCardClass()">
|
|
|
|
|
|
<div class="balance-icon">
|
|
|
|
|
|
<i class="el-icon-wallet"></i>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="balance-content">
|
|
|
|
|
|
<div class="balance-label">当前余额</div>
|
|
|
|
|
|
<div class="balance-amount">¥{{ formatPrice(walletInfo.balance || 0) }}</div>
|
|
|
|
|
|
<div v-if="walletInfo.balance_status" class="balance-status">
|
|
|
|
|
|
{{ getBalanceStatusText() }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 充值优惠提示 -->
|
|
|
|
|
|
<div class="recharge-benefit-alert">
|
|
|
|
|
|
<el-alert
|
|
|
|
|
|
title="充值优惠"
|
|
|
|
|
|
description="充值满1000元即可享受商务洽谈优惠,获得专属服务支持"
|
|
|
|
|
|
type="success"
|
|
|
|
|
|
:closable="false"
|
|
|
|
|
|
show-icon
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #default>
|
|
|
|
|
|
<div class="benefit-content">
|
|
|
|
|
|
<span>充值满1000元即可享受商务洽谈优惠,获得专属服务支持</span>
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
size="small"
|
|
|
|
|
|
@click="showBusinessConsultation = true"
|
|
|
|
|
|
class="consultation-btn"
|
|
|
|
|
|
>
|
|
|
|
|
|
商务洽谈
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-alert>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 余额状态提示 -->
|
|
|
|
|
|
<div v-if="walletInfo.is_arrears" class="balance-alert arrears-alert">
|
|
|
|
|
|
<el-alert
|
|
|
|
|
|
title="账户已欠费"
|
|
|
|
|
|
description="您的账户已欠费,服务已停止。请立即充值以恢复服务。"
|
|
|
|
|
|
type="error"
|
|
|
|
|
|
:closable="false"
|
|
|
|
|
|
show-icon
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div v-else-if="walletInfo.is_low_balance" class="balance-alert low-balance-alert">
|
|
|
|
|
|
<el-alert
|
|
|
|
|
|
title="余额不足"
|
|
|
|
|
|
description="您的余额较低,建议及时充值以确保服务正常使用。"
|
|
|
|
|
|
type="warning"
|
|
|
|
|
|
:closable="false"
|
|
|
|
|
|
show-icon
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 充值方式选择 -->
|
|
|
|
|
|
<div class="recharge-methods-section">
|
|
|
|
|
|
<h3 class="section-title">选择充值方式</h3>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="recharge-methods-grid">
|
|
|
|
|
|
<!-- 支付宝充值 -->
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="recharge-method-card"
|
|
|
|
|
|
:class="{ active: selectedMethod === 'alipay' }"
|
|
|
|
|
|
@click="selectMethod('alipay')"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="method-icon alipay-icon">
|
|
|
|
|
|
<CurrencyYenIcon class="h-7 w-7" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="method-content">
|
|
|
|
|
|
<div class="method-title">支付宝充值</div>
|
|
|
|
|
|
<div class="method-description">在线支付,即时到账</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="method-check"
|
|
|
|
|
|
:class="{
|
|
|
|
|
|
checked: selectedMethod === 'alipay',
|
|
|
|
|
|
unchecked: selectedMethod !== 'alipay',
|
|
|
|
|
|
}"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-icon v-if="selectedMethod === 'alipay'"><Check /></el-icon>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2025-12-12 15:27:21 +08:00
|
|
|
|
<!-- 微信充值 -->
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="recharge-method-card"
|
|
|
|
|
|
:class="{ active: selectedMethod === 'wechat' }"
|
|
|
|
|
|
@click="selectMethod('wechat')"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="method-icon wechat-icon">
|
|
|
|
|
|
<svg class="h-7 w-7" viewBox="0 0 24 24" fill="currentColor">
|
|
|
|
|
|
<path d="M8.691 2.188C3.891 2.188 0 5.476 0 9.53c0 2.212 1.17 4.203 3.002 5.55a.59.59 0 0 1 .213.665l-.39 1.48c-.019.07-.048.141-.048.213 0 .163.13.295.29.295a.326.326 0 0 0 .167-.054l1.903-1.114a.864.864 0 0 1 .717-.098 10.16 10.16 0 0 0 2.837.403c.276 0 .543-.027.811-.05-.857-2.578.157-4.972 1.932-6.446 2.048-1.715 4.81-2.04 6.765-.632 0 0 .127-.08.289-.183a8.262 8.262 0 0 1-.79-3.228c0-4.054-3.89-7.342-8.691-7.342zM5.785 5.991c.642 0 1.162.529 1.162 1.18a1.17 1.17 0 0 1-1.162 1.178A1.17 1.17 0 0 1 4.623 7.17c0-.651.52-1.18 1.162-1.18zm5.813 0c.642 0 1.162.529 1.162 1.18a1.17 1.17 0 0 1-1.162 1.178 1.17 1.17 0 0 1-1.162-1.178c0-.651.52-1.18 1.162-1.18zm6.581 4.853c-1.894-.006-3.598.723-4.712 1.87-.792.813-1.235 1.865-1.235 3.004 0 .918.3 1.762.81 2.426.393.511.893.93 1.468 1.22.464.23.97.345 1.483.345.276 0 .543-.027.811-.05a.86.86 0 0 1 .717.098l1.903 1.114c.11.065.167.054.167.054.16 0 .29-.132.29-.295 0-.072-.03-.142-.048-.213l-.39-1.48a.59.59 0 0 1 .213-.665c1.832-1.347 3.002-3.338 3.002-5.55 0-2.24-1.35-4.237-3.405-5.314a8.21 8.21 0 0 0-1.484-.456zm-2.834 3.524c.518 0 .938.427.938.953a.946.946 0 0 1-.938.953.946.946 0 0 1-.938-.953c0-.526.42-.953.938-.953zm4.604 0c.518 0 .938.427.938.953a.946.946 0 0 1-.938.953.946.946 0 0 1-.938-.953c0-.526.42-.953.938-.953z"/>
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="method-content">
|
|
|
|
|
|
<div class="method-title">微信充值</div>
|
|
|
|
|
|
<div class="method-description">在线支付,即时到账</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="method-check"
|
|
|
|
|
|
:class="{
|
|
|
|
|
|
checked: selectedMethod === 'wechat',
|
|
|
|
|
|
unchecked: selectedMethod !== 'wechat',
|
|
|
|
|
|
}"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-icon v-if="selectedMethod === 'wechat'"><Check /></el-icon>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2025-11-24 16:06:44 +08:00
|
|
|
|
<!-- 对公转账 -->
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="recharge-method-card"
|
|
|
|
|
|
:class="{ active: selectedMethod === 'transfer' }"
|
|
|
|
|
|
@click="selectMethod('transfer')"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="method-icon transfer-icon">
|
|
|
|
|
|
<CreditCardIcon class="h-7 w-7" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="method-content">
|
|
|
|
|
|
<div class="method-title">对公转账</div>
|
|
|
|
|
|
<div class="method-description">银行转账,人工确认</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="method-check"
|
|
|
|
|
|
:class="{
|
|
|
|
|
|
checked: selectedMethod === 'transfer',
|
|
|
|
|
|
unchecked: selectedMethod !== 'transfer',
|
|
|
|
|
|
}"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-icon v-if="selectedMethod === 'transfer'"><Check /></el-icon>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2025-12-12 15:27:21 +08:00
|
|
|
|
<!-- 微信充值表单 -->
|
|
|
|
|
|
<div v-if="selectedMethod === 'wechat'" class="recharge-form-section">
|
|
|
|
|
|
<h3 class="section-title">微信充值</h3>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 预设充值金额选择 -->
|
|
|
|
|
|
<div class="preset-amounts-section">
|
|
|
|
|
|
<h4 class="preset-title">选择充值金额</h4>
|
|
|
|
|
|
<div class="preset-amounts-grid">
|
|
|
|
|
|
<div
|
|
|
|
|
|
v-for="bonus in rechargeConfig.alipay_recharge_bonus"
|
|
|
|
|
|
:key="bonus.recharge_amount"
|
|
|
|
|
|
class="preset-amount-card"
|
|
|
|
|
|
:class="{ active: selectedPresetAmount === bonus.recharge_amount }"
|
|
|
|
|
|
@click="selectPresetAmount(bonus.recharge_amount)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="preset-amount-main">
|
|
|
|
|
|
<div class="preset-amount-value">¥{{ formatPrice(bonus.recharge_amount) }}</div>
|
|
|
|
|
|
<div class="preset-bonus-info">
|
|
|
|
|
|
<span class="bonus-label">赠送</span>
|
|
|
|
|
|
<span class="bonus-amount">¥{{ formatPrice(bonus.bonus_amount) }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="preset-amount-total">
|
|
|
|
|
|
实到账:¥{{ formatPrice(bonus.recharge_amount + bonus.bonus_amount) }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 自定义金额选项 -->
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="preset-amount-card custom-amount-card"
|
|
|
|
|
|
:class="{ active: selectedPresetAmount === 'custom' }"
|
|
|
|
|
|
@click="selectCustomAmount"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="preset-amount-main">
|
|
|
|
|
|
<div class="preset-amount-value">自定义金额</div>
|
|
|
|
|
|
<div class="preset-bonus-info">
|
|
|
|
|
|
<span class="bonus-label">赠送</span>
|
|
|
|
|
|
<span class="bonus-amount">{{ getCustomBonusText() }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="preset-amount-total">
|
|
|
|
|
|
实到账:¥{{ getCustomTotalAmount() }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<el-form
|
|
|
|
|
|
ref="wechatFormRef"
|
|
|
|
|
|
:model="wechatForm"
|
|
|
|
|
|
:rules="wechatRules"
|
|
|
|
|
|
label-width="120px"
|
|
|
|
|
|
class="recharge-form"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-form-item label="充值金额" prop="amount">
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
v-model="wechatForm.amount"
|
|
|
|
|
|
placeholder="请输入充值金额"
|
|
|
|
|
|
@input="handleWechatAmountInput"
|
|
|
|
|
|
class="amount-input"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #prepend>¥</template>
|
|
|
|
|
|
</el-input>
|
|
|
|
|
|
<div class="form-tip">最低充值金额:¥{{ rechargeConfig.min_amount }},最多支持两位小数</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 显示赠送信息 -->
|
|
|
|
|
|
<div v-if="wechatForm.amount && getCurrentBonusAmount() > 0" class="bonus-info">
|
|
|
|
|
|
<el-alert
|
|
|
|
|
|
:title="`充值 ¥${wechatForm.amount} 可享受赠送 ¥${formatPrice(getCurrentBonusAmount())}`"
|
|
|
|
|
|
type="success"
|
|
|
|
|
|
:closable="false"
|
|
|
|
|
|
show-icon
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #default>
|
|
|
|
|
|
<div class="bonus-detail">
|
|
|
|
|
|
<span>实际到账:¥{{ formatPrice(parseFloat(wechatForm.amount || 0) + getCurrentBonusAmount()) }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-alert>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- PC/H5 场景不再必填 openid -->
|
|
|
|
|
|
|
|
|
|
|
|
<el-form-item>
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
size="large"
|
|
|
|
|
|
@click="handleWechatRecharge"
|
|
|
|
|
|
:loading="wechatLoading"
|
|
|
|
|
|
class="submit-btn"
|
|
|
|
|
|
>
|
|
|
|
|
|
立即充值
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
</el-form>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2025-11-24 16:06:44 +08:00
|
|
|
|
<!-- 支付宝充值表单 -->
|
|
|
|
|
|
<div v-if="selectedMethod === 'alipay'" class="recharge-form-section">
|
|
|
|
|
|
<h3 class="section-title">支付宝充值</h3>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 预设充值金额选择 -->
|
|
|
|
|
|
<div class="preset-amounts-section">
|
|
|
|
|
|
<h4 class="preset-title">选择充值金额</h4>
|
|
|
|
|
|
<div class="preset-amounts-grid">
|
|
|
|
|
|
<div
|
|
|
|
|
|
v-for="bonus in rechargeConfig.alipay_recharge_bonus"
|
|
|
|
|
|
:key="bonus.recharge_amount"
|
|
|
|
|
|
class="preset-amount-card"
|
|
|
|
|
|
:class="{ active: selectedPresetAmount === bonus.recharge_amount }"
|
|
|
|
|
|
@click="selectPresetAmount(bonus.recharge_amount)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="preset-amount-main">
|
|
|
|
|
|
<div class="preset-amount-value">¥{{ formatPrice(bonus.recharge_amount) }}</div>
|
|
|
|
|
|
<div class="preset-bonus-info">
|
|
|
|
|
|
<span class="bonus-label">赠送</span>
|
|
|
|
|
|
<span class="bonus-amount">¥{{ formatPrice(bonus.bonus_amount) }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="preset-amount-total">
|
|
|
|
|
|
实到账:¥{{ formatPrice(bonus.recharge_amount + bonus.bonus_amount) }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 自定义金额选项 -->
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="preset-amount-card custom-amount-card"
|
|
|
|
|
|
:class="{ active: selectedPresetAmount === 'custom' }"
|
|
|
|
|
|
@click="selectCustomAmount"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="preset-amount-main">
|
|
|
|
|
|
<div class="preset-amount-value">自定义金额</div>
|
|
|
|
|
|
<div class="preset-bonus-info">
|
|
|
|
|
|
<span class="bonus-label">赠送</span>
|
|
|
|
|
|
<span class="bonus-amount">{{ getCustomBonusText() }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="preset-amount-total">
|
|
|
|
|
|
实到账:¥{{ getCustomTotalAmount() }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<el-form
|
|
|
|
|
|
ref="alipayFormRef"
|
|
|
|
|
|
:model="alipayForm"
|
|
|
|
|
|
:rules="alipayRules"
|
|
|
|
|
|
label-width="120px"
|
|
|
|
|
|
class="recharge-form"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-form-item label="充值金额" prop="amount">
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
v-model="alipayForm.amount"
|
|
|
|
|
|
placeholder="请输入充值金额"
|
|
|
|
|
|
@input="handleAmountInput"
|
|
|
|
|
|
class="amount-input"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #prepend>¥</template>
|
|
|
|
|
|
</el-input>
|
|
|
|
|
|
<div class="form-tip">最低充值金额:¥{{ rechargeConfig.min_amount }},最多支持两位小数</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 显示赠送信息 -->
|
|
|
|
|
|
<div v-if="alipayForm.amount && getCurrentBonusAmount() > 0" class="bonus-info">
|
|
|
|
|
|
<el-alert
|
|
|
|
|
|
:title="`充值 ¥${alipayForm.amount} 可享受赠送 ¥${formatPrice(getCurrentBonusAmount())}`"
|
|
|
|
|
|
type="success"
|
|
|
|
|
|
:closable="false"
|
|
|
|
|
|
show-icon
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #default>
|
|
|
|
|
|
<div class="bonus-detail">
|
|
|
|
|
|
<span>实际到账:¥{{ formatPrice(parseFloat(alipayForm.amount || 0) + getCurrentBonusAmount()) }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-alert>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
|
|
<el-form-item>
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
size="large"
|
|
|
|
|
|
@click="handleAlipayRecharge"
|
|
|
|
|
|
:loading="alipayLoading"
|
|
|
|
|
|
class="submit-btn"
|
|
|
|
|
|
>
|
|
|
|
|
|
立即充值
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
</el-form>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 对公转账信息 -->
|
|
|
|
|
|
<div v-if="selectedMethod === 'transfer'" class="transfer-info-section">
|
|
|
|
|
|
<h3 class="section-title">对公转账信息</h3>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="transfer-info-card">
|
|
|
|
|
|
<div class="transfer-info-item">
|
|
|
|
|
|
<label class="info-label">开户银行</label>
|
|
|
|
|
|
<span class="info-value">{{ transferInfo.bankName }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="transfer-info-item">
|
|
|
|
|
|
<label class="info-label">银行账号</label>
|
|
|
|
|
|
<span class="info-value account-number">{{ transferInfo.bankAccount }}</span>
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
size="small"
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
@click="copyToClipboard(transferInfo.bankAccount)"
|
|
|
|
|
|
class="copy-btn"
|
|
|
|
|
|
>
|
|
|
|
|
|
复制
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="transfer-info-item">
|
|
|
|
|
|
<label class="info-label">开户名</label>
|
|
|
|
|
|
<span class="info-value">{{ transferInfo.accountName }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="transfer-info-item">
|
|
|
|
|
|
<label class="info-label">转账金额</label>
|
|
|
|
|
|
<span class="info-value amount">请按实际充值金额转账</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="transfer-notice">
|
|
|
|
|
|
<el-alert title="转账说明" type="info" :closable="false" show-icon>
|
|
|
|
|
|
<template #default>
|
|
|
|
|
|
<ul class="notice-list">
|
|
|
|
|
|
<li>
|
|
|
|
|
|
转账时请在备注中填写您的企业名称<strong>{{
|
|
|
|
|
|
userInfo.enterprise_info.company_name
|
|
|
|
|
|
}}</strong>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li>转账成功后,我们会在24小时内为您确认充值</li>
|
|
|
|
|
|
<li>如有疑问,请联系客服</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-alert>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 商务洽谈弹窗 -->
|
|
|
|
|
|
<BusinessConsultationDialog v-model:visible="showBusinessConsultation" />
|
2025-12-12 15:27:21 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 微信支付二维码弹窗 -->
|
|
|
|
|
|
<el-dialog
|
|
|
|
|
|
v-model="showQrCodeDialog"
|
|
|
|
|
|
title="微信扫码支付"
|
|
|
|
|
|
width="400px"
|
|
|
|
|
|
:close-on-click-modal="false"
|
|
|
|
|
|
:close-on-press-escape="false"
|
|
|
|
|
|
class="qr-code-dialog"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="qr-code-container">
|
|
|
|
|
|
<div class="qr-code-wrapper">
|
|
|
|
|
|
<canvas ref="qrCodeCanvas" class="qr-code-canvas"></canvas>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p class="qr-code-tip">请使用微信扫描上方二维码完成支付</p>
|
|
|
|
|
|
<p class="qr-code-amount">支付金额:¥{{ formatPrice(wechatForm.amount) }}</p>
|
|
|
|
|
|
<p v-if="isCheckingPayment" class="qr-code-checking">正在确认支付状态,请稍候...</p>
|
|
|
|
|
|
<el-button type="primary" @click="closeQrCodeDialog" class="close-qr-btn">关闭</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-dialog>
|
2025-11-24 16:06:44 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
import { financeApi } from '@/api'
|
|
|
|
|
|
import BusinessConsultationDialog from '@/components/common/BusinessConsultationDialog.vue'
|
|
|
|
|
|
import { useCertification } from '@/composables/useCertification'
|
|
|
|
|
|
import { useUserStore } from '@/stores/user'
|
|
|
|
|
|
import { Check } from '@element-plus/icons-vue'
|
|
|
|
|
|
import { CreditCardIcon, CurrencyYenIcon } from '@heroicons/vue/24/outline'
|
|
|
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
2025-12-12 15:27:21 +08:00
|
|
|
|
import QRCode from 'qrcode'
|
2025-11-24 16:06:44 +08:00
|
|
|
|
|
|
|
|
|
|
const userStore = useUserStore()
|
|
|
|
|
|
const userInfo = userStore.userInfo
|
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
|
|
|
|
|
|
|
// 认证相关
|
|
|
|
|
|
const {
|
|
|
|
|
|
isCertified,
|
|
|
|
|
|
certificationLoading,
|
|
|
|
|
|
requiresCertification,
|
|
|
|
|
|
callProtectedAPI,
|
|
|
|
|
|
canCallAPI
|
|
|
|
|
|
} = useCertification()
|
|
|
|
|
|
|
|
|
|
|
|
// 响应式数据
|
|
|
|
|
|
const selectedMethod = ref('alipay')
|
|
|
|
|
|
const alipayLoading = ref(false)
|
2025-12-12 15:27:21 +08:00
|
|
|
|
const wechatLoading = ref(false)
|
2025-11-24 16:06:44 +08:00
|
|
|
|
const showBusinessConsultation = ref(false)
|
2025-12-12 15:27:21 +08:00
|
|
|
|
const showQrCodeDialog = ref(false)
|
|
|
|
|
|
const qrCodeCanvas = ref(null)
|
|
|
|
|
|
const currentWechatOrderNo = ref(null)
|
|
|
|
|
|
const isCheckingPayment = ref(false)
|
|
|
|
|
|
let wechatOrderPollTimer = null
|
2025-11-24 16:06:44 +08:00
|
|
|
|
|
|
|
|
|
|
// 钱包信息
|
|
|
|
|
|
const walletInfo = ref({
|
|
|
|
|
|
balance: 0,
|
|
|
|
|
|
balance_status: '',
|
|
|
|
|
|
is_arrears: false,
|
|
|
|
|
|
is_low_balance: false,
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 充值配置
|
|
|
|
|
|
const rechargeConfig = ref({
|
|
|
|
|
|
min_amount: '1.00',
|
|
|
|
|
|
max_amount: '100000.00',
|
|
|
|
|
|
alipay_recharge_bonus: []
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 对公转账信息
|
|
|
|
|
|
const transferInfo = ref({
|
|
|
|
|
|
bankName: '中国银行股份有限公司海口美苑路支行',
|
|
|
|
|
|
bankAccount: '2662 9305 2910',
|
2025-12-18 19:14:18 +08:00
|
|
|
|
accountName: '海南海宇大数据有限公司',
|
2025-11-24 16:06:44 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 支付宝充值表单
|
|
|
|
|
|
const alipayFormRef = ref()
|
|
|
|
|
|
const alipayForm = reactive({
|
|
|
|
|
|
amount: '',
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2025-12-12 15:27:21 +08:00
|
|
|
|
// 微信充值表单
|
|
|
|
|
|
const wechatFormRef = ref()
|
|
|
|
|
|
const wechatForm = reactive({
|
|
|
|
|
|
amount: '',
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2025-11-24 16:06:44 +08:00
|
|
|
|
// 预设金额选择
|
|
|
|
|
|
const selectedPresetAmount = ref(null)
|
|
|
|
|
|
|
|
|
|
|
|
// 格式化金额输入
|
|
|
|
|
|
const formatAmountInput = (value) => {
|
|
|
|
|
|
// 移除非数字和小数点
|
|
|
|
|
|
let formatted = value.replace(/[^\d.]/g, '')
|
|
|
|
|
|
|
|
|
|
|
|
// 确保只有一个小数点
|
|
|
|
|
|
const parts = formatted.split('.')
|
|
|
|
|
|
if (parts.length > 2) {
|
|
|
|
|
|
formatted = parts[0] + '.' + parts.slice(1).join('')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 限制小数点后最多两位
|
|
|
|
|
|
if (parts.length === 2 && parts[1].length > 2) {
|
|
|
|
|
|
formatted = parts[0] + '.' + parts[1].substring(0, 2)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return formatted
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理金额输入变化
|
|
|
|
|
|
const handleAmountInput = (value) => {
|
|
|
|
|
|
// Element Plus 的 @input 事件直接传递值,而不是事件对象
|
|
|
|
|
|
const formatted = formatAmountInput(value || '')
|
|
|
|
|
|
alipayForm.amount = formatted
|
|
|
|
|
|
|
|
|
|
|
|
// 如果输入了自定义金额,更新选择状态
|
|
|
|
|
|
if (formatted && selectedPresetAmount.value !== 'custom') {
|
|
|
|
|
|
selectedPresetAmount.value = 'custom'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-12 15:27:21 +08:00
|
|
|
|
// 处理微信金额输入变化
|
|
|
|
|
|
const handleWechatAmountInput = (value) => {
|
|
|
|
|
|
const formatted = formatAmountInput(value || '')
|
|
|
|
|
|
wechatForm.amount = formatted
|
|
|
|
|
|
|
|
|
|
|
|
// 如果输入了自定义金额,更新选择状态
|
|
|
|
|
|
if (formatted && selectedPresetAmount.value !== 'custom') {
|
|
|
|
|
|
selectedPresetAmount.value = 'custom'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-24 16:06:44 +08:00
|
|
|
|
const alipayRules = {
|
|
|
|
|
|
amount: [
|
|
|
|
|
|
{ required: true, message: '请输入充值金额', trigger: 'blur' },
|
|
|
|
|
|
{
|
|
|
|
|
|
validator: (rule, value, callback) => {
|
|
|
|
|
|
if (!value) {
|
|
|
|
|
|
callback()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否为有效数字格式
|
|
|
|
|
|
const amountRegex = /^\d+(\.\d{1,2})?$/
|
|
|
|
|
|
if (!amountRegex.test(value)) {
|
|
|
|
|
|
callback(new Error('请输入正确的金额格式,最多支持两位小数'))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查金额范围
|
|
|
|
|
|
const amount = parseFloat(value)
|
|
|
|
|
|
const minAmount = parseFloat(rechargeConfig.value.min_amount)
|
|
|
|
|
|
const maxAmount = parseFloat(rechargeConfig.value.max_amount)
|
|
|
|
|
|
|
|
|
|
|
|
if (amount < minAmount) {
|
|
|
|
|
|
callback(new Error(`充值金额不能少于${minAmount}元`))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (amount > maxAmount) {
|
|
|
|
|
|
callback(new Error(`单次充值金额不能超过${maxAmount}元`))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
callback()
|
|
|
|
|
|
},
|
|
|
|
|
|
trigger: 'blur',
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-12 15:27:21 +08:00
|
|
|
|
const wechatRules = {
|
|
|
|
|
|
amount: [
|
|
|
|
|
|
{ required: true, message: '请输入充值金额', trigger: 'blur' },
|
|
|
|
|
|
{
|
|
|
|
|
|
validator: (rule, value, callback) => {
|
|
|
|
|
|
if (!value) {
|
|
|
|
|
|
callback()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否为有效数字格式
|
|
|
|
|
|
const amountRegex = /^\d+(\.\d{1,2})?$/
|
|
|
|
|
|
if (!amountRegex.test(value)) {
|
|
|
|
|
|
callback(new Error('请输入正确的金额格式,最多支持两位小数'))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查金额范围
|
|
|
|
|
|
const amount = parseFloat(value)
|
|
|
|
|
|
const minAmount = parseFloat(rechargeConfig.value.min_amount)
|
|
|
|
|
|
const maxAmount = parseFloat(rechargeConfig.value.max_amount)
|
|
|
|
|
|
|
|
|
|
|
|
if (amount < minAmount) {
|
|
|
|
|
|
callback(new Error(`充值金额不能少于${minAmount}元`))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (amount > maxAmount) {
|
|
|
|
|
|
callback(new Error(`单次充值金额不能超过${maxAmount}元`))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
callback()
|
|
|
|
|
|
},
|
|
|
|
|
|
trigger: 'blur',
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-24 16:06:44 +08:00
|
|
|
|
// 初始化
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
loadWalletInfo()
|
|
|
|
|
|
loadRechargeConfig()
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 加载钱包信息
|
|
|
|
|
|
const loadWalletInfo = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const response = await callProtectedAPI(financeApi.getWallet)
|
|
|
|
|
|
if (response) {
|
|
|
|
|
|
walletInfo.value = response.data || { balance: 0 }
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果API调用被阻止,显示默认数据
|
|
|
|
|
|
walletInfo.value = { balance: 0, balance_status: '', is_arrears: false, is_low_balance: false }
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('加载钱包信息失败:', error)
|
|
|
|
|
|
if (canCallAPI.value) {
|
|
|
|
|
|
ElMessage.error('加载钱包信息失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 加载充值配置
|
|
|
|
|
|
const loadRechargeConfig = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 直接调用API,不需要认证保护
|
|
|
|
|
|
const response = await financeApi.getRechargeConfig()
|
|
|
|
|
|
if (response && response.data) {
|
|
|
|
|
|
rechargeConfig.value = response.data || {
|
|
|
|
|
|
min_amount: '50.00',
|
|
|
|
|
|
max_amount: '100000.00',
|
|
|
|
|
|
alipay_recharge_bonus: []
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设置默认选中的预设金额(选择第一个赠送规则)
|
|
|
|
|
|
if (rechargeConfig.value.alipay_recharge_bonus && rechargeConfig.value.alipay_recharge_bonus.length > 0) {
|
|
|
|
|
|
const firstBonus = rechargeConfig.value.alipay_recharge_bonus[0]
|
|
|
|
|
|
selectedPresetAmount.value = firstBonus.recharge_amount
|
2025-12-12 15:27:21 +08:00
|
|
|
|
const amountStr = firstBonus.recharge_amount.toString()
|
|
|
|
|
|
alipayForm.amount = amountStr
|
|
|
|
|
|
wechatForm.amount = amountStr
|
2025-11-24 16:06:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('加载充值配置失败:', error)
|
|
|
|
|
|
// 使用默认配置,不显示错误信息
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 选择充值方式
|
|
|
|
|
|
const selectMethod = (method) => {
|
|
|
|
|
|
selectedMethod.value = method
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 格式化价格
|
|
|
|
|
|
const formatPrice = (price) => {
|
|
|
|
|
|
if (!price) return '0.00'
|
|
|
|
|
|
return Number(price).toFixed(2)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取余额状态文本
|
|
|
|
|
|
const getBalanceStatusText = () => {
|
|
|
|
|
|
switch (walletInfo.value.balance_status) {
|
|
|
|
|
|
case 'arrears':
|
|
|
|
|
|
return '账户欠费'
|
|
|
|
|
|
case 'low':
|
|
|
|
|
|
return '余额较低'
|
|
|
|
|
|
case 'normal':
|
|
|
|
|
|
return '余额正常'
|
|
|
|
|
|
default:
|
|
|
|
|
|
return ''
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取余额卡片样式类
|
|
|
|
|
|
const getBalanceCardClass = () => {
|
|
|
|
|
|
if (walletInfo.value.is_arrears) {
|
|
|
|
|
|
return 'balance-card-arrears'
|
|
|
|
|
|
} else if (walletInfo.value.is_low_balance) {
|
|
|
|
|
|
return 'balance-card-low'
|
|
|
|
|
|
}
|
|
|
|
|
|
return ''
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 复制到剪贴板
|
|
|
|
|
|
const copyToClipboard = async (text) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await navigator.clipboard.writeText(text)
|
|
|
|
|
|
ElMessage.success('已复制到剪贴板')
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('复制失败:', error)
|
|
|
|
|
|
ElMessage.error('复制失败')
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 显示商务洽谈弹窗
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 选择预设金额
|
|
|
|
|
|
const selectPresetAmount = (amount) => {
|
|
|
|
|
|
selectedPresetAmount.value = amount
|
2025-12-12 15:27:21 +08:00
|
|
|
|
const amountStr = amount.toString()
|
|
|
|
|
|
alipayForm.amount = amountStr
|
|
|
|
|
|
wechatForm.amount = amountStr
|
2025-11-24 16:06:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 选择自定义金额
|
|
|
|
|
|
const selectCustomAmount = () => {
|
|
|
|
|
|
selectedPresetAmount.value = 'custom'
|
|
|
|
|
|
alipayForm.amount = '' // 清空金额输入框
|
2025-12-12 15:27:21 +08:00
|
|
|
|
wechatForm.amount = '' // 清空微信金额输入框
|
2025-11-24 16:06:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据充值金额获取赠送金额
|
|
|
|
|
|
const getBonusAmount = (rechargeAmount) => {
|
|
|
|
|
|
if (!rechargeAmount || !rechargeConfig.value.alipay_recharge_bonus) {
|
|
|
|
|
|
return 0
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const amount = parseFloat(rechargeAmount)
|
|
|
|
|
|
const bonusRules = rechargeConfig.value.alipay_recharge_bonus
|
|
|
|
|
|
|
|
|
|
|
|
// 按充值金额从高到低排序,找到第一个匹配的赠送规则
|
|
|
|
|
|
for (let i = bonusRules.length - 1; i >= 0; i--) {
|
|
|
|
|
|
const rule = bonusRules[i]
|
|
|
|
|
|
if (amount >= rule.recharge_amount) {
|
|
|
|
|
|
return rule.bonus_amount
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前预设金额的赠送金额
|
|
|
|
|
|
const getCurrentBonusAmount = () => {
|
|
|
|
|
|
if (selectedPresetAmount.value === 'custom') {
|
2025-12-12 15:27:21 +08:00
|
|
|
|
// 根据当前选择的充值方式获取金额
|
|
|
|
|
|
const currentAmount = selectedMethod.value === 'wechat' ? wechatForm.amount : alipayForm.amount
|
|
|
|
|
|
return getBonusAmount(currentAmount)
|
2025-11-24 16:06:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const bonus = rechargeConfig.value.alipay_recharge_bonus.find(
|
|
|
|
|
|
(item) => item.recharge_amount === selectedPresetAmount.value
|
|
|
|
|
|
)
|
|
|
|
|
|
return bonus ? parseFloat(bonus.bonus_amount) : 0
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取自定义金额的赠送文本
|
|
|
|
|
|
const getCustomBonusText = () => {
|
|
|
|
|
|
if (selectedPresetAmount.value === 'custom') {
|
|
|
|
|
|
return '根据实际充值金额计算'
|
|
|
|
|
|
}
|
|
|
|
|
|
return '0.00'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取自定义金额的总到账金额
|
|
|
|
|
|
const getCustomTotalAmount = () => {
|
|
|
|
|
|
if (selectedPresetAmount.value === 'custom') {
|
2025-12-12 15:27:21 +08:00
|
|
|
|
// 根据当前选择的充值方式获取金额
|
|
|
|
|
|
const currentAmount = selectedMethod.value === 'wechat' ? wechatForm.amount : alipayForm.amount
|
|
|
|
|
|
const amount = parseFloat(currentAmount || 0)
|
2025-11-24 16:06:44 +08:00
|
|
|
|
const bonus = getBonusAmount(amount)
|
|
|
|
|
|
return formatPrice(amount + bonus)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const bonus = rechargeConfig.value.alipay_recharge_bonus.find(
|
|
|
|
|
|
(item) => item.recharge_amount === selectedPresetAmount.value
|
|
|
|
|
|
)
|
|
|
|
|
|
return bonus ? formatPrice(parseFloat(bonus.recharge_amount) + parseFloat(bonus.bonus_amount)) : '0.00'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 支付宝充值
|
|
|
|
|
|
const handleAlipayRecharge = async () => {
|
|
|
|
|
|
if (!alipayFormRef.value) return
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
await alipayFormRef.value.validate()
|
|
|
|
|
|
|
|
|
|
|
|
// 显示确认框
|
|
|
|
|
|
await ElMessageBox.confirm(
|
|
|
|
|
|
`确认充值 ¥${alipayForm.amount} 到您的钱包吗?`,
|
|
|
|
|
|
'确认充值',
|
|
|
|
|
|
{
|
|
|
|
|
|
confirmButtonText: '确认充值',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning',
|
|
|
|
|
|
customClass: 'custom-message-box',
|
|
|
|
|
|
dangerouslyUseHTMLString: false
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
alipayLoading.value = true
|
|
|
|
|
|
|
|
|
|
|
|
// 调用后端创建支付宝充值订单
|
|
|
|
|
|
const response = await callProtectedAPI(financeApi.createAlipayRecharge, {
|
|
|
|
|
|
amount: alipayForm.amount, // 直接传递字符串类型
|
|
|
|
|
|
subject: `钱包充值 ¥${alipayForm.amount}`,
|
|
|
|
|
|
platform: 'pc' // 根据实际需求设置:pc/h5/app
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if (!response) {
|
|
|
|
|
|
ElMessage.error('请先完成企业认证后再进行充值操作')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (response.data && response.data.pay_url) {
|
|
|
|
|
|
ElMessage.success('正在跳转到支付宝支付...')
|
|
|
|
|
|
|
|
|
|
|
|
// 跳转到支付宝支付页面
|
|
|
|
|
|
window.location.href = response.data.pay_url
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
// 如果是用户取消,不显示错误信息
|
|
|
|
|
|
if (error === 'cancel' || error === 'close') {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.error('支付宝充值失败:', error)
|
|
|
|
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
alipayLoading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-12 15:27:21 +08:00
|
|
|
|
|
|
|
|
|
|
// 微信充值
|
|
|
|
|
|
const handleWechatRecharge = async () => {
|
|
|
|
|
|
if (!wechatFormRef.value) return
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
await wechatFormRef.value.validate()
|
|
|
|
|
|
|
|
|
|
|
|
// 显示确认框
|
|
|
|
|
|
await ElMessageBox.confirm(
|
|
|
|
|
|
`确认充值 ¥${wechatForm.amount} 到您的钱包吗?`,
|
|
|
|
|
|
'确认充值',
|
|
|
|
|
|
{
|
|
|
|
|
|
confirmButtonText: '确认充值',
|
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
|
type: 'warning',
|
|
|
|
|
|
customClass: 'custom-message-box',
|
|
|
|
|
|
dangerouslyUseHTMLString: false
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
wechatLoading.value = true
|
|
|
|
|
|
|
|
|
|
|
|
// 调用后端创建微信充值订单
|
|
|
|
|
|
const response = await callProtectedAPI(financeApi.createWechatRecharge, {
|
|
|
|
|
|
amount: wechatForm.amount, // 直接传递字符串类型
|
|
|
|
|
|
subject: `钱包充值 ¥${wechatForm.amount}`,
|
|
|
|
|
|
platform: 'wx_h5', // PC/H5 场景,后端已兼容无 openid
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if (!response) {
|
|
|
|
|
|
ElMessage.error('请先完成企业认证后再进行充值操作')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理微信支付响应
|
|
|
|
|
|
// prepay_data 可能包含 code_url (扫码支付) 或 pay_url (H5支付)
|
|
|
|
|
|
if (response.data && response.data.prepay_data) {
|
|
|
|
|
|
const prepayData = response.data.prepay_data
|
2025-12-18 19:14:18 +08:00
|
|
|
|
|
2025-12-12 15:27:21 +08:00
|
|
|
|
// 扫码支付:显示二维码
|
|
|
|
|
|
if (prepayData.code_url) {
|
|
|
|
|
|
// 保存订单号用于轮询(从响应中获取订单号)
|
|
|
|
|
|
if (response.data.out_trade_no) {
|
|
|
|
|
|
currentWechatOrderNo.value = response.data.out_trade_no
|
|
|
|
|
|
await showQrCode(prepayData.code_url)
|
|
|
|
|
|
// 开始轮询订单状态
|
|
|
|
|
|
startWechatOrderPolling()
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.error('获取订单号失败,请重新支付')
|
|
|
|
|
|
}
|
2025-12-18 19:14:18 +08:00
|
|
|
|
}
|
2025-12-12 15:27:21 +08:00
|
|
|
|
// H5支付:跳转到支付页面
|
|
|
|
|
|
else if (prepayData.pay_url || response.data.pay_url) {
|
|
|
|
|
|
ElMessage.success('正在跳转到微信支付...')
|
|
|
|
|
|
window.location.href = prepayData.pay_url || response.data.pay_url
|
|
|
|
|
|
}
|
|
|
|
|
|
// 小程序或APP支付
|
|
|
|
|
|
else if (prepayData.prepay_id || response.data.prepay_id) {
|
|
|
|
|
|
ElMessage.success('请使用微信扫码支付')
|
|
|
|
|
|
// 这里可以根据实际返回的数据进行处理
|
|
|
|
|
|
} else {
|
|
|
|
|
|
console.warn('微信支付返回数据格式异常:', response.data)
|
|
|
|
|
|
ElMessage.warning('支付数据格式异常,请联系客服')
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (response.data && response.data.pay_url) {
|
|
|
|
|
|
// 兼容旧的返回格式(直接返回 pay_url)
|
|
|
|
|
|
ElMessage.success('正在跳转到微信支付...')
|
|
|
|
|
|
window.location.href = response.data.pay_url
|
|
|
|
|
|
} else {
|
|
|
|
|
|
console.warn('微信支付返回数据异常:', response.data)
|
|
|
|
|
|
ElMessage.warning('获取支付信息失败,请稍后重试')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
// 如果是用户取消,不显示错误信息
|
|
|
|
|
|
if (error === 'cancel' || error === 'close') {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.error('微信充值失败:', error)
|
|
|
|
|
|
if (canCallAPI.value) {
|
|
|
|
|
|
ElMessage.error('微信充值失败,请稍后重试')
|
|
|
|
|
|
}
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
wechatLoading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 显示二维码
|
|
|
|
|
|
const showQrCode = async (codeUrl) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
showQrCodeDialog.value = true
|
2025-12-18 19:14:18 +08:00
|
|
|
|
|
2025-12-12 15:27:21 +08:00
|
|
|
|
// 等待DOM更新
|
|
|
|
|
|
await nextTick()
|
2025-12-18 19:14:18 +08:00
|
|
|
|
|
2025-12-12 15:27:21 +08:00
|
|
|
|
if (qrCodeCanvas.value) {
|
|
|
|
|
|
// 生成二维码
|
|
|
|
|
|
await QRCode.toCanvas(qrCodeCanvas.value, codeUrl, {
|
|
|
|
|
|
width: 256,
|
|
|
|
|
|
margin: 2,
|
|
|
|
|
|
color: {
|
|
|
|
|
|
dark: '#000000',
|
|
|
|
|
|
light: '#FFFFFF'
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('生成二维码失败:', error)
|
|
|
|
|
|
ElMessage.error('生成二维码失败,请稍后重试')
|
|
|
|
|
|
showQrCodeDialog.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭二维码弹窗
|
|
|
|
|
|
const closeQrCodeDialog = () => {
|
|
|
|
|
|
stopWechatOrderPolling()
|
|
|
|
|
|
showQrCodeDialog.value = false
|
|
|
|
|
|
currentWechatOrderNo.value = null
|
|
|
|
|
|
isCheckingPayment.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 开始轮询微信订单状态
|
|
|
|
|
|
const startWechatOrderPolling = () => {
|
|
|
|
|
|
// 清除之前的定时器
|
|
|
|
|
|
stopWechatOrderPolling()
|
2025-12-18 19:14:18 +08:00
|
|
|
|
|
2025-12-12 15:27:21 +08:00
|
|
|
|
// 立即检查一次
|
|
|
|
|
|
checkWechatOrderStatus()
|
2025-12-18 19:14:18 +08:00
|
|
|
|
|
2025-12-12 15:27:21 +08:00
|
|
|
|
// 每3秒轮询一次
|
|
|
|
|
|
wechatOrderPollTimer = setInterval(() => {
|
|
|
|
|
|
checkWechatOrderStatus()
|
|
|
|
|
|
}, 3000)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 停止轮询
|
|
|
|
|
|
const stopWechatOrderPolling = () => {
|
|
|
|
|
|
if (wechatOrderPollTimer) {
|
|
|
|
|
|
clearInterval(wechatOrderPollTimer)
|
|
|
|
|
|
wechatOrderPollTimer = null
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查微信订单状态
|
|
|
|
|
|
const checkWechatOrderStatus = async () => {
|
|
|
|
|
|
if (!currentWechatOrderNo.value) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
isCheckingPayment.value = true
|
|
|
|
|
|
const response = await callProtectedAPI(financeApi.getWechatOrderStatus, {
|
|
|
|
|
|
out_trade_no: currentWechatOrderNo.value
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if (!response || !response.data) {
|
|
|
|
|
|
isCheckingPayment.value = false
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const orderStatus = response.data.status
|
|
|
|
|
|
|
|
|
|
|
|
// 订单状态:pending, success, failed, closed
|
|
|
|
|
|
if (orderStatus === 'success') {
|
|
|
|
|
|
// 支付成功
|
|
|
|
|
|
stopWechatOrderPolling()
|
|
|
|
|
|
isCheckingPayment.value = false
|
|
|
|
|
|
closeQrCodeDialog()
|
|
|
|
|
|
ElMessage.success('充值成功!')
|
2025-12-18 19:14:18 +08:00
|
|
|
|
|
2025-12-12 15:27:21 +08:00
|
|
|
|
// 刷新钱包余额
|
|
|
|
|
|
await loadWalletInfo()
|
2025-12-18 19:14:18 +08:00
|
|
|
|
|
2025-12-12 15:27:21 +08:00
|
|
|
|
// 重置表单
|
|
|
|
|
|
wechatForm.amount = ''
|
|
|
|
|
|
selectedPresetAmount.value = null
|
|
|
|
|
|
} else if (orderStatus === 'failed' || orderStatus === 'closed') {
|
|
|
|
|
|
// 支付失败或关闭
|
|
|
|
|
|
stopWechatOrderPolling()
|
|
|
|
|
|
isCheckingPayment.value = false
|
|
|
|
|
|
ElMessage.error('支付失败,请重新支付')
|
|
|
|
|
|
closeQrCodeDialog()
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// pending 状态继续轮询
|
|
|
|
|
|
isCheckingPayment.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('查询微信订单状态失败:', error)
|
|
|
|
|
|
isCheckingPayment.value = false
|
|
|
|
|
|
// 不显示错误,继续轮询
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 组件卸载时清理定时器
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
|
|
|
|
stopWechatOrderPolling()
|
|
|
|
|
|
})
|
2025-11-24 16:06:44 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
/* 钱包信息区域 */
|
|
|
|
|
|
.wallet-info-section {
|
|
|
|
|
|
margin-bottom: 32px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.wallet-balance-card {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
|
|
|
border-radius: 16px;
|
|
|
|
|
|
padding: 24px;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
box-shadow: 0 8px 32px rgba(102, 126, 234, 0.3);
|
|
|
|
|
|
}
|
|
|
|
|
|
.list-page-wrapper {
|
|
|
|
|
|
padding: 32px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.balance-icon {
|
|
|
|
|
|
font-size: 48px;
|
|
|
|
|
|
margin-right: 20px;
|
|
|
|
|
|
opacity: 0.9;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.balance-content {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.balance-label {
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
opacity: 0.9;
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.balance-amount {
|
|
|
|
|
|
font-size: 36px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
line-height: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.balance-status {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
opacity: 0.8;
|
|
|
|
|
|
margin-top: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 充值优惠提示 */
|
|
|
|
|
|
.recharge-benefit-alert {
|
|
|
|
|
|
margin: 16px 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.benefit-content {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
gap: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.consultation-btn {
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 余额状态卡片样式 */
|
|
|
|
|
|
.balance-card-arrears {
|
|
|
|
|
|
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%) !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.balance-card-low {
|
|
|
|
|
|
background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%) !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 余额状态提示 */
|
|
|
|
|
|
.balance-alert {
|
|
|
|
|
|
margin-top: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.arrears-alert {
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 确认框样式 */
|
|
|
|
|
|
:deep(.custom-message-box) {
|
|
|
|
|
|
.el-message-box__header {
|
|
|
|
|
|
padding: 20px 20px 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.el-message-box__content {
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.el-message-box__btns {
|
|
|
|
|
|
padding: 10px 20px 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.el-button--warning {
|
|
|
|
|
|
background-color: #e6a23c;
|
|
|
|
|
|
border-color: #e6a23c;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.el-button--warning:hover {
|
|
|
|
|
|
background-color: #cf9236;
|
|
|
|
|
|
border-color: #cf9236;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.low-balance-alert {
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 充值方式选择 */
|
|
|
|
|
|
.recharge-methods-section {
|
|
|
|
|
|
margin-bottom: 32px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.recharge-methods-grid {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
|
|
|
|
gap: 20px;
|
|
|
|
|
|
margin-top: 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.recharge-method-card {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
background: rgba(255, 255, 255, 0.8);
|
|
|
|
|
|
border: 2px solid rgba(226, 232, 240, 0.6);
|
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.recharge-method-card:hover {
|
|
|
|
|
|
border-color: rgba(59, 130, 246, 0.4);
|
|
|
|
|
|
transform: translateY(-2px);
|
|
|
|
|
|
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.recharge-method-card.active {
|
|
|
|
|
|
border-color: #3b82f6;
|
|
|
|
|
|
background: rgba(59, 130, 246, 0.05);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.method-icon {
|
|
|
|
|
|
width: 48px;
|
|
|
|
|
|
height: 48px;
|
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
|
margin-right: 16px;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.alipay-icon {
|
|
|
|
|
|
background: linear-gradient(135deg, #1677ff 0%, #4096ff 100%);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-12 15:27:21 +08:00
|
|
|
|
.wechat-icon {
|
|
|
|
|
|
background: linear-gradient(135deg, #07c160 0%, #06ad56 100%);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-24 16:06:44 +08:00
|
|
|
|
.transfer-icon {
|
|
|
|
|
|
background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.method-content {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.method-title {
|
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #1e293b;
|
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.method-description {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #64748b;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.method-check {
|
|
|
|
|
|
width: 24px;
|
|
|
|
|
|
height: 24px;
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
transition: background 0.2s;
|
|
|
|
|
|
}
|
|
|
|
|
|
.method-check.checked {
|
|
|
|
|
|
background: #3b82f6;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
}
|
|
|
|
|
|
.method-check.unchecked {
|
|
|
|
|
|
background: #e5e7eb;
|
|
|
|
|
|
color: #94a3b8;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 预设金额选择 */
|
|
|
|
|
|
.preset-amounts-section {
|
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.preset-title {
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #374151;
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.preset-amounts-grid {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.preset-amount-card {
|
|
|
|
|
|
background: rgba(248, 250, 252, 0.8);
|
|
|
|
|
|
border: 2px solid rgba(226, 232, 240, 0.6);
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
padding: 12px;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.preset-amount-card:hover {
|
|
|
|
|
|
border-color: rgba(59, 130, 246, 0.4);
|
|
|
|
|
|
transform: translateY(-1px);
|
|
|
|
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.preset-amount-card.active {
|
|
|
|
|
|
border-color: #3b82f6;
|
|
|
|
|
|
background: rgba(59, 130, 246, 0.05);
|
|
|
|
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.preset-amount-main {
|
|
|
|
|
|
margin-bottom: 6px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.preset-amount-value {
|
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
color: #1e293b;
|
|
|
|
|
|
margin-bottom: 2px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.preset-bonus-info {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
gap: 2px;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #64748b;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.bonus-label {
|
|
|
|
|
|
color: #10b981;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.bonus-amount {
|
|
|
|
|
|
color: #10b981;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.preset-amount-total {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #374151;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
background: rgba(16, 185, 129, 0.1);
|
|
|
|
|
|
padding: 2px 6px;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
border: 1px solid rgba(16, 185, 129, 0.2);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.custom-amount-card {
|
|
|
|
|
|
border-style: dashed;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.custom-amount-card .preset-amount-value {
|
|
|
|
|
|
color: #6b7280;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 赠送信息提示 */
|
|
|
|
|
|
.bonus-info {
|
|
|
|
|
|
margin-top: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.bonus-detail {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #10b981;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 充值表单 */
|
|
|
|
|
|
.recharge-form-section,
|
|
|
|
|
|
.transfer-info-section {
|
|
|
|
|
|
margin-top: 32px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.recharge-form,
|
|
|
|
|
|
.transfer-form {
|
|
|
|
|
|
max-width: 500px;
|
|
|
|
|
|
margin-top: 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.amount-input {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-tip {
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
color: #64748b;
|
|
|
|
|
|
margin-top: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.submit-btn {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 48px;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 对公转账信息 */
|
|
|
|
|
|
.transfer-info-card {
|
|
|
|
|
|
background: rgba(248, 250, 252, 0.8);
|
|
|
|
|
|
border: 1px solid rgba(226, 232, 240, 0.6);
|
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
padding: 24px;
|
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.transfer-info-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
padding: 12px 0;
|
|
|
|
|
|
border-bottom: 1px solid rgba(226, 232, 240, 0.4);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.transfer-info-item:last-child {
|
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
|
border-bottom: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.info-label {
|
|
|
|
|
|
width: 120px;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #64748b;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.info-value {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
color: #1e293b;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.info-value.account-number {
|
|
|
|
|
|
font-family: 'Courier New', monospace;
|
|
|
|
|
|
background: rgba(255, 255, 255, 0.8);
|
|
|
|
|
|
padding: 8px 12px;
|
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
border: 1px solid rgba(226, 232, 240, 0.6);
|
|
|
|
|
|
margin-right: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.info-value.amount {
|
|
|
|
|
|
color: #dc2626;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.copy-btn {
|
|
|
|
|
|
margin-left: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 转账说明 */
|
|
|
|
|
|
.transfer-notice {
|
|
|
|
|
|
margin-bottom: 32px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.notice-list {
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
padding-left: 20px;
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.notice-list li {
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
color: #475569;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.notice-list li:last-child {
|
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 调试信息样式 */
|
|
|
|
|
|
.debug-info {
|
|
|
|
|
|
margin-top: 32px;
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
background-color: #f8f9fa;
|
|
|
|
|
|
border: 1px solid #e9ecef;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #495057;
|
|
|
|
|
|
white-space: pre-wrap; /* 保持换行 */
|
|
|
|
|
|
word-break: break-all; /* 允许单词换行 */
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.debug-info h4 {
|
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #212529;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 响应式设计 */
|
|
|
|
|
|
@media (max-width: 768px) {
|
|
|
|
|
|
.wallet-balance-card {
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.balance-icon {
|
|
|
|
|
|
font-size: 36px;
|
|
|
|
|
|
margin-right: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.balance-amount {
|
|
|
|
|
|
font-size: 28px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.benefit-content {
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
gap: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.consultation-btn {
|
|
|
|
|
|
align-self: flex-end;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.recharge-methods-grid {
|
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
|
gap: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.recharge-method-card {
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.method-icon {
|
|
|
|
|
|
width: 40px;
|
|
|
|
|
|
height: 40px;
|
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
|
margin-right: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.method-title {
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.transfer-info-item {
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.info-label {
|
|
|
|
|
|
width: auto;
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.info-value.account-number {
|
|
|
|
|
|
margin-right: 0;
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.copy-btn {
|
|
|
|
|
|
margin-left: 0;
|
|
|
|
|
|
align-self: flex-start;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.benefits-list {
|
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.qr-code-wrapper {
|
|
|
|
|
|
width: 160px;
|
|
|
|
|
|
height: 160px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 预设金额选择响应式 */
|
|
|
|
|
|
.preset-amounts-grid {
|
|
|
|
|
|
grid-template-columns: repeat(3, 1fr);
|
|
|
|
|
|
gap: 6px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.preset-amount-card {
|
|
|
|
|
|
padding: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.preset-amount-value {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.preset-bonus-info {
|
|
|
|
|
|
font-size: 9px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.preset-amount-total {
|
|
|
|
|
|
font-size: 9px;
|
|
|
|
|
|
padding: 2px 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-12 15:27:21 +08:00
|
|
|
|
|
|
|
|
|
|
/* 二维码弹窗样式 */
|
|
|
|
|
|
.qr-code-dialog :deep(.el-dialog) {
|
|
|
|
|
|
border-radius: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.qr-code-dialog :deep(.el-dialog__header) {
|
|
|
|
|
|
padding: 20px 20px 10px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.qr-code-dialog :deep(.el-dialog__title) {
|
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.qr-code-container {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding: 20px 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.qr-code-wrapper {
|
|
|
|
|
|
width: 256px;
|
|
|
|
|
|
height: 256px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
|
border: 2px solid #e5e7eb;
|
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.qr-code-canvas {
|
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
|
max-height: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.qr-code-tip {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #64748b;
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.qr-code-amount {
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #dc2626;
|
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.qr-code-checking {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #3b82f6;
|
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
animation: pulse 1.5s ease-in-out infinite;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@keyframes pulse {
|
|
|
|
|
|
0%, 100% {
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
50% {
|
|
|
|
|
|
opacity: 0.6;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.close-qr-btn {
|
|
|
|
|
|
width: 120px;
|
|
|
|
|
|
height: 40px;
|
|
|
|
|
|
}
|
2025-11-24 16:06:44 +08:00
|
|
|
|
</style>
|