833 lines
36 KiB
Vue
833 lines
36 KiB
Vue
<template>
|
||
<div class="p-4 bg-gradient-to-b from-blue-50/30 to-gray-50 min-h-screen">
|
||
<!-- 实名认证提示 -->
|
||
<div v-if="!agentStore.isRealName" class="mb-4">
|
||
<div class="rounded-xl shadow-lg p-6" style="background-color: var(--van-theme-primary-light);">
|
||
<div class="flex items-center mb-3">
|
||
<van-icon name="warning-o" class="text-xl mr-2" style="color: var(--van-theme-primary);" />
|
||
<h2 class="text-lg font-bold" style="color: var(--van-text-color);">
|
||
未完成实名认证
|
||
</h2>
|
||
</div>
|
||
<p class="text-sm mb-4" style="color: var(--van-text-color-2);">
|
||
根据相关规定,提现功能需要完成实名认证后才能使用,提现金额将转入您实名认证的账户中。
|
||
</p>
|
||
<van-button type="primary" block class="text-white rounded-xl h-10"
|
||
style="background-color: var(--van-theme-primary);"
|
||
@click="openRealNameAuth">
|
||
立即实名认证
|
||
</van-button>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<!-- 提现方式切换标签 -->
|
||
<van-tabs v-if="showTabs" v-model:active="activeTab" class="mb-4" @change="onTabChange">
|
||
<van-tab v-if="showAlipay" title="支付宝提现" name="alipay">
|
||
<div class="rounded-xl shadow-lg p-6 mb-4 mt-4"
|
||
style="background: linear-gradient(135deg, var(--van-theme-primary-light), rgba(255,255,255,0.8));">
|
||
<div class="flex items-center mb-6">
|
||
<van-icon name="alipay" class="text-xl mr-2" style="color: #1677FF;" />
|
||
<h1 class="text-xl font-bold" style="color: var(--van-text-color);">支付宝提现</h1>
|
||
</div>
|
||
|
||
<!-- 支付宝账号 -->
|
||
<div class="mb-6">
|
||
<label class="text-sm mb-2 block" style="color: var(--van-text-color);">支付宝账号</label>
|
||
<van-field v-model="alipayAccount" placeholder="请输入支付宝账号"
|
||
class="flex items-center rounded-lg bg-white/90 backdrop-blur-sm shadow-sm"
|
||
:rules="[{ required: true, message: ' ' }]">
|
||
<template #left-icon>
|
||
<van-icon name="phone-o" style="color: var(--van-text-color-2);" />
|
||
</template>
|
||
</van-field>
|
||
<small class="text-xs mt-1 block"
|
||
style="color: var(--van-text-color-2);">可填写支付宝账户绑定的手机号</small>
|
||
</div>
|
||
<!-- 支付宝实名姓名 -->
|
||
<div class="mb-6">
|
||
<label class="text-sm mb-2 block" style="color: var(--van-text-color);">实名姓名</label>
|
||
<van-field v-model="alipayRealName" placeholder="请输入支付宝认证姓名"
|
||
class="flex items-center rounded-lg bg-white/90 backdrop-blur-sm shadow-sm" :rules="[
|
||
{
|
||
required: true,
|
||
message: ' ',
|
||
validator: (val) =>
|
||
/^[\u4e00-\u9fa5]{2,4}$/.test(val),
|
||
},
|
||
]">
|
||
<template #left-icon>
|
||
<van-icon name="contact-o" style="color: var(--van-text-color-2);" />
|
||
</template>
|
||
</van-field>
|
||
<small class="text-xs mt-1 block"
|
||
style="color: var(--van-text-color-2);">请填写支付宝账户认证的真实姓名</small>
|
||
</div>
|
||
</div>
|
||
</van-tab>
|
||
<van-tab v-if="showBankcard" title="银行卡提现" name="bankcard">
|
||
<div class="rounded-xl shadow-lg p-6 mb-4 mt-4"
|
||
style="background: linear-gradient(135deg, var(--van-theme-primary-light), rgba(255,255,255,0.8));">
|
||
<div class="flex items-center mb-6">
|
||
<van-icon name="credit-pay" class="text-xl mr-2" style="color: #1677FF;" />
|
||
<h1 class="text-xl font-bold" style="color: var(--van-text-color);">银行卡提现</h1>
|
||
</div>
|
||
|
||
<!-- 实名信息展示 -->
|
||
<div v-if="bankCardInfo.payee_name" class="mb-4 p-4 rounded-lg"
|
||
style="background-color: rgba(22, 119, 255, 0.1);">
|
||
<div class="text-xs mb-2" style="color: var(--van-text-color-2);">您的实名信息</div>
|
||
<div class="text-sm" style="color: var(--van-text-color);">
|
||
<div class="mb-1">姓名:<span class="font-semibold">{{ bankCardInfo.payee_name }}</span>
|
||
</div>
|
||
<div>身份证号:<span class="font-semibold">{{ formatIdCard(bankCardInfo.id_card) }}</span>
|
||
</div>
|
||
</div>
|
||
<div class="text-xs mt-2" style="color: #f59e0b;">
|
||
<van-icon name="warning-o" class="mr-1" />提示:银行卡信息需与实名认证信息一致
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 银行卡号 -->
|
||
<div class="mb-6">
|
||
<label class="text-sm mb-2 block" style="color: var(--van-text-color);">银行卡号</label>
|
||
<van-field v-model="bankCardNo" type="number" placeholder="请输入银行卡号(16-19位)"
|
||
class="flex items-center rounded-lg bg-white/90 backdrop-blur-sm shadow-sm" :rules="[
|
||
{ required: true, message: ' ' },
|
||
{ validator: validateBankCardNo, message: ' ' },
|
||
]">
|
||
<template #left-icon>
|
||
<van-icon name="credit-pay" style="color: var(--van-text-color-2);" />
|
||
</template>
|
||
</van-field>
|
||
<small class="text-xs mt-1 block"
|
||
style="color: var(--van-text-color-2);">请输入16-19位银行卡号</small>
|
||
</div>
|
||
<!-- 开户支行 -->
|
||
<div class="mb-6">
|
||
<label class="text-sm mb-2 block" style="color: var(--van-text-color);">开户支行</label>
|
||
<van-field v-model="bankName" placeholder="请输入开户支行"
|
||
class="flex items-center rounded-lg bg-white/90 backdrop-blur-sm shadow-sm"
|
||
:rules="[{ required: true, message: ' ' }]">
|
||
<template #left-icon>
|
||
<van-icon name="location-o" style="color: var(--van-text-color-2);" />
|
||
</template>
|
||
</van-field>
|
||
<small class="text-xs mt-1 block"
|
||
style="color: var(--van-text-color-2);">例如:中国工商银行XX支行</small>
|
||
</div>
|
||
</div>
|
||
</van-tab>
|
||
</van-tabs>
|
||
|
||
<!-- 如果只显示一种方式,不显示 tabs,直接显示内容 -->
|
||
<div v-if="!showTabs">
|
||
<!-- 只显示支付宝提现 -->
|
||
<div v-if="showAlipay && !showBankcard" class="rounded-xl shadow-lg p-6 mb-4 mt-4"
|
||
style="background: linear-gradient(135deg, var(--van-theme-primary-light), rgba(255,255,255,0.8));">
|
||
<div class="flex items-center mb-6">
|
||
<van-icon name="alipay" class="text-xl mr-2" style="color: #1677FF;" />
|
||
<h1 class="text-xl font-bold" style="color: var(--van-text-color);">支付宝提现</h1>
|
||
</div>
|
||
|
||
<!-- 支付宝账号 -->
|
||
<div class="mb-6">
|
||
<label class="text-sm mb-2 block" style="color: var(--van-text-color);">支付宝账号</label>
|
||
<van-field v-model="alipayAccount" placeholder="请输入支付宝账号"
|
||
class="flex items-center rounded-lg bg-white/90 backdrop-blur-sm shadow-sm"
|
||
:rules="[{ required: true, message: ' ' }]">
|
||
<template #left-icon>
|
||
<van-icon name="phone-o" style="color: var(--van-text-color-2);" />
|
||
</template>
|
||
</van-field>
|
||
<small class="text-xs mt-1 block" style="color: var(--van-text-color-2);">可填写支付宝账户绑定的手机号</small>
|
||
</div>
|
||
<!-- 支付宝实名姓名 -->
|
||
<div class="mb-6">
|
||
<label class="text-sm mb-2 block" style="color: var(--van-text-color);">实名姓名</label>
|
||
<van-field v-model="alipayRealName" placeholder="请输入支付宝认证姓名"
|
||
class="flex items-center rounded-lg bg-white/90 backdrop-blur-sm shadow-sm" :rules="[
|
||
{
|
||
required: true,
|
||
message: ' ',
|
||
validator: (val) =>
|
||
/^[\u4e00-\u9fa5]{2,4}$/.test(val),
|
||
},
|
||
]">
|
||
<template #left-icon>
|
||
<van-icon name="contact-o" style="color: var(--van-text-color-2);" />
|
||
</template>
|
||
</van-field>
|
||
<small class="text-xs mt-1 block"
|
||
style="color: var(--van-text-color-2);">请填写支付宝账户认证的真实姓名</small>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 只显示银行卡提现 -->
|
||
<div v-if="showBankcard && !showAlipay" class="rounded-xl shadow-lg p-6 mb-4 mt-4"
|
||
style="background: linear-gradient(135deg, var(--van-theme-primary-light), rgba(255,255,255,0.8));">
|
||
<div class="flex items-center mb-6">
|
||
<van-icon name="credit-pay" class="text-xl mr-2" style="color: #1677FF;" />
|
||
<h1 class="text-xl font-bold" style="color: var(--van-text-color);">银行卡提现</h1>
|
||
</div>
|
||
|
||
<!-- 实名信息展示 -->
|
||
<div v-if="bankCardInfo.payee_name" class="mb-4 p-4 rounded-lg"
|
||
style="background-color: rgba(22, 119, 255, 0.1);">
|
||
<div class="text-xs mb-2" style="color: var(--van-text-color-2);">您的实名信息</div>
|
||
<div class="text-sm" style="color: var(--van-text-color);">
|
||
<div class="mb-1">姓名:<span class="font-semibold">{{ bankCardInfo.payee_name }}</span>
|
||
</div>
|
||
<div>身份证号:<span class="font-semibold">{{ formatIdCard(bankCardInfo.id_card) }}</span>
|
||
</div>
|
||
</div>
|
||
<div class="text-xs mt-2" style="color: #f59e0b;">
|
||
<van-icon name="warning-o" class="mr-1" />提示:银行卡信息需与实名认证信息一致
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 银行卡号 -->
|
||
<div class="mb-6">
|
||
<label class="text-sm mb-2 block" style="color: var(--van-text-color);">银行卡号</label>
|
||
<van-field v-model="bankCardNo" type="number" placeholder="请输入银行卡号(16-19位)"
|
||
class="flex items-center rounded-lg bg-white/90 backdrop-blur-sm shadow-sm" :rules="[
|
||
{ required: true, message: ' ' },
|
||
{ validator: validateBankCardNo, message: ' ' },
|
||
]">
|
||
<template #left-icon>
|
||
<van-icon name="credit-pay" style="color: var(--van-text-color-2);" />
|
||
</template>
|
||
</van-field>
|
||
<small class="text-xs mt-1 block" style="color: var(--van-text-color-2);">请输入16-19位银行卡号</small>
|
||
</div>
|
||
<!-- 开户支行 -->
|
||
<div class="mb-6">
|
||
<label class="text-sm mb-2 block" style="color: var(--van-text-color);">开户支行</label>
|
||
<van-field v-model="bankName" placeholder="请输入开户支行"
|
||
class="flex items-center rounded-lg bg-white/90 backdrop-blur-sm shadow-sm"
|
||
:rules="[{ required: true, message: ' ' }]">
|
||
<template #left-icon>
|
||
<van-icon name="location-o" style="color: var(--van-text-color-2);" />
|
||
</template>
|
||
</van-field>
|
||
<small class="text-xs mt-1 block" style="color: var(--van-text-color-2);">例如:中国工商银行XX支行</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 提现金额(共用) -->
|
||
<div class="mb-4">
|
||
<label class="text-sm mb-2 block" style="color: var(--van-text-color);">提现金额</label>
|
||
<van-field v-model.number="amount" type="number" placeholder="请输入提现金额"
|
||
class="flex items-center rounded-lg bg-white/90 backdrop-blur-sm shadow-sm" :rules="[
|
||
{ required: true, message: ' ' },
|
||
{ validator: validateAmount, message: ' ' },
|
||
]">
|
||
<template #left-icon>
|
||
<van-icon name="gold-coin-o" style="color: var(--van-text-color-2);" />
|
||
</template>
|
||
<template #right-icon> 元 </template>
|
||
<template #button>
|
||
<van-button size="small" type="primary" class="rounded-full px-3 shadow-sm"
|
||
style="background-color: var(--van-theme-primary); color: white;" @click="fillMaxAmount">
|
||
全部提现
|
||
</van-button>
|
||
</template>
|
||
</van-field>
|
||
</div>
|
||
|
||
<!-- 金额提示 -->
|
||
<div class="text-sm mb-2" style="color: var(--van-text-color);">
|
||
可提现金额:<span class="font-semibold" style="color: var(--van-theme-primary);">¥{{ availableAmount }}</span>
|
||
</div>
|
||
|
||
<!-- 提现规则 -->
|
||
<div class="p-4 rounded-xl backdrop-blur-sm mb-4" style="background-color: var(--van-theme-primary-light);">
|
||
<div class="flex items-center text-sm mb-2" style="color: var(--van-theme-primary);">
|
||
<van-icon name="warning" class="mr-1" />提现须知
|
||
</div>
|
||
<ul class="text-xs space-y-1" style="color: var(--van-text-color);">
|
||
<li>· 每日限提现1次,最低50元</li>
|
||
<li>· 提现收取6%税收</li>
|
||
<li v-if="activeTab === 'alipay'">· 到账时间:24小时内</li>
|
||
<li v-else>· 到账时间:管理员审核后手动转账</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<!-- 税收说明 -->
|
||
<div class="p-4 rounded-xl backdrop-blur-sm mb-4" style="background-color: rgba(251, 191, 36, 0.1);">
|
||
<div class="flex items-center text-sm mb-2" style="color: #f59e0b;">
|
||
<van-icon name="info-o" class="mr-1" />税收说明
|
||
</div>
|
||
<div class="text-xs leading-relaxed" style="color: var(--van-text-color);">
|
||
<p>根据相关规定,提现时将统一收取6%的税收,该税收用于相关税费支出。</p>
|
||
<p class="mt-2" style="color: #f59e0b;">• 税率标准:统一按6%收取</p>
|
||
<p style="color: #f59e0b;">• 适用范围:所有提现金额</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 提交按钮 -->
|
||
<van-button type="primary" block :loading="isSubmitting"
|
||
class="text-white rounded-xl shadow-lg h-12 font-bold text-base"
|
||
style="background: linear-gradient(135deg, var(--van-theme-primary), var(--van-theme-primary-dark));"
|
||
@click="handleSubmit">
|
||
立即提现
|
||
</van-button>
|
||
</div>
|
||
|
||
<!-- 税务确认弹窗 -->
|
||
<van-popup v-model:show="showTaxConfirmPopup" round position="center"
|
||
:style="{ width: '85%', borderRadius: '20px' }" :overlay-style="{ backgroundColor: 'rgba(0,0,0,0.4)' }">
|
||
<div class="p-8 bg-gradient-to-b from-white to-blue-50/30 relative">
|
||
<div class="text-center space-y-5">
|
||
<!-- 标题 -->
|
||
<div>
|
||
<h2 class="text-xl font-semibold text-gray-800 mb-2">提现确认</h2>
|
||
<p class="text-sm text-gray-500">请确认以下提现信息</p>
|
||
</div>
|
||
|
||
<!-- 金额详情 -->
|
||
<div class="rounded-xl p-4 space-y-3" style="background-color: var(--van-background-color-light);">
|
||
<div class="flex justify-between items-center">
|
||
<span style="color: var(--van-text-color-2);">提现金额:</span>
|
||
<span class="font-semibold" style="color: var(--van-text-color);">¥{{ amount }}</span>
|
||
</div>
|
||
<div class="flex justify-between items-center">
|
||
<span style="color: var(--van-text-color-2);">税收:</span>
|
||
<span class="font-semibold text-red-500">
|
||
-¥{{ taxAmount.toFixed(2) }}
|
||
</span>
|
||
</div>
|
||
<div class="border-t pt-2" style="border-color: var(--van-border-color);">
|
||
<div class="flex justify-between items-center">
|
||
<span class="font-medium" style="color: var(--van-text-color);">实际到账:</span>
|
||
<span class="font-bold text-lg" style="color: var(--van-theme-primary);">¥{{ actualAmount.toFixed(2) }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 提示信息 -->
|
||
<div class="bg-blue-50 rounded-lg p-3 text-xs">
|
||
<p class="text-blue-600 font-medium mb-2">
|
||
税收说明
|
||
</p>
|
||
<div class="text-gray-600 space-y-1">
|
||
<p>• 提现金额:¥{{ amount }}</p>
|
||
<p>• 税率:6%</p>
|
||
<p class="text-blue-600">• 税收计算:¥{{ amount }} × 6% = ¥{{ taxAmount.toFixed(2) }}</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 操作按钮 -->
|
||
<div class="flex space-x-3 mt-6">
|
||
<van-button block round class="flex-1 h-11"
|
||
style="background-color: var(--van-background-color-light); color: var(--van-text-color-2);"
|
||
@click="showTaxConfirmPopup = false">
|
||
取消
|
||
</van-button>
|
||
<van-button block round class="flex-1 h-11 font-medium shadow-sm"
|
||
style="background-color: var(--van-theme-primary); color: white;"
|
||
:loading="isSubmitting" @click="confirmWithdraw">
|
||
确认提现
|
||
</van-button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</van-popup>
|
||
|
||
<!-- 提现结果弹窗 -->
|
||
<van-popup v-model:show="showStatusPopup" round position="center"
|
||
:style="{ width: '85%', borderRadius: '20px' }" :overlay-style="{ backgroundColor: 'rgba(0,0,0,0.4)' }">
|
||
<div class="p-8 bg-gradient-to-b from-white to-blue-50/30 relative">
|
||
<!-- 状态内容 -->
|
||
<div class="text-center space-y-5">
|
||
<!-- 状态图标 -->
|
||
<div class="relative inline-block">
|
||
<div class="absolute inset-0 bg-gradient-to-r opacity-20 rounded-full animate-pulse blur-sm"
|
||
:class="statusBg[status]"></div>
|
||
<van-icon :name="statusIcon[status]" size="56" class="p-1 rounded-full border-[3px]"
|
||
:class="statusIconClass[status]" />
|
||
</div>
|
||
|
||
<!-- 状态文案 -->
|
||
<div>
|
||
<h2 class="text-xl font-semibold mb-1" :class="statusTextColors[status]">
|
||
{{ statusMessages[status] }}
|
||
</h2>
|
||
<template v-if="status === 2">
|
||
<p class="text-sm" style="color: var(--van-text-color-2);">
|
||
<span v-if="activeTab === 'alipay'">
|
||
已向
|
||
<span style="color: var(--van-theme-primary);">{{ alipayAccount }}</span>
|
||
转账
|
||
</span>
|
||
<span v-else>
|
||
提现申请已通过,管理员将手动转账
|
||
</span>
|
||
</p>
|
||
<p class="text-2xl font-bold mt-2" style="color: #10b981;">
|
||
¥{{ amount }}
|
||
</p>
|
||
</template>
|
||
<template v-if="status === 3">
|
||
<p class="text-sm px-4" style="color: #ef4444;">
|
||
{{ failMsg }}
|
||
</p>
|
||
</template>
|
||
</div>
|
||
|
||
<!-- 进度条(处理中状态) -->
|
||
<van-progress v-if="status === 1" :percentage="60" stroke-width="8"
|
||
:color="`linear-gradient(to right, var(--van-theme-primary), var(--van-theme-primary-light))`"
|
||
:track-color="`var(--van-theme-primary-light)`"
|
||
class="!rounded-full" />
|
||
|
||
<!-- 辅助文案 -->
|
||
<div class="text-xs space-y-1.5" style="color: var(--van-text-color-2);">
|
||
<template v-if="status === 2">
|
||
<p v-if="activeTab === 'alipay'">预计24小时内到账</p>
|
||
<p v-else>请等待管理员审核并转账</p>
|
||
</template>
|
||
<template v-if="status === 1">
|
||
<p v-if="activeTab === 'alipay'">您的申请已进入处理队列</p>
|
||
<p v-else>您的申请已提交,等待管理员审核</p>
|
||
<p>可在提现记录中查看结果</p>
|
||
</template>
|
||
</div>
|
||
|
||
<!-- 操作按钮 -->
|
||
<van-button block round size="small"
|
||
class="mt-4 h-11 font-medium shadow-sm"
|
||
:style="{ backgroundColor: statusButtonColor[status], color: status === 1 ? 'var(--van-theme-primary)' : 'white' }"
|
||
@click="handlePopupAction">
|
||
{{
|
||
status === 1
|
||
? "知道了"
|
||
: status === 2
|
||
? "完成"
|
||
: "重新提现"
|
||
}}
|
||
</van-button>
|
||
</div>
|
||
</div>
|
||
</van-popup>
|
||
</div>
|
||
<!-- 引入实名认证对话框 -->
|
||
<RealNameAuthDialog />
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed, onBeforeMount } from "vue";
|
||
import { showToast } from "vant";
|
||
import RealNameAuthDialog from "@/components/RealNameAuthDialog.vue";
|
||
|
||
const agentStore = useAgentStore();
|
||
const dialogStore = useDialogStore();
|
||
|
||
// ========== 提现方式配置开关 ==========
|
||
// 可以通过环境变量或后端接口控制
|
||
// 配置选项:
|
||
// - 'alipay': 只显示支付宝提现
|
||
// - 'bankcard': 只显示银行卡提现
|
||
// - 'both': 显示两种提现方式(默认)
|
||
// - 数组形式: ['alipay', 'bankcard'] 或 ['alipay'] 或 ['bankcard']
|
||
const WITHDRAW_CONFIG = import.meta.env.VITE_WITHDRAW_METHODS || 'bankcard';
|
||
// 解析配置:支持字符串和数组格式
|
||
const getWithdrawMethods = () => {
|
||
if (Array.isArray(WITHDRAW_CONFIG)) {
|
||
return WITHDRAW_CONFIG;
|
||
}
|
||
if (typeof WITHDRAW_CONFIG === 'string') {
|
||
if (WITHDRAW_CONFIG === 'alipay') return ['alipay'];
|
||
if (WITHDRAW_CONFIG === 'bankcard') return ['bankcard'];
|
||
if (WITHDRAW_CONFIG === 'both') return ['alipay', 'bankcard'];
|
||
// 支持逗号分隔的字符串: "alipay,bankcard" 或 "alipay" 或 "bankcard"
|
||
return WITHDRAW_CONFIG.split(',').map(s => s.trim()).filter(Boolean);
|
||
}
|
||
return ['alipay', 'bankcard']; // 默认都显示
|
||
};
|
||
|
||
const enabledMethods = getWithdrawMethods();
|
||
const showAlipay = enabledMethods.includes('alipay');
|
||
const showBankcard = enabledMethods.includes('bankcard');
|
||
const showTabs = showAlipay && showBankcard; // 只有两种都显示时才显示 tabs
|
||
|
||
// 标签页管理
|
||
const getInitialTab = () => {
|
||
// 如果只显示一种方式,直接设置为该方式
|
||
if (showAlipay && !showBankcard) return 'alipay';
|
||
if (showBankcard && !showAlipay) return 'bankcard';
|
||
// 如果两种都显示,默认支付宝
|
||
return 'alipay';
|
||
};
|
||
const activeTab = ref(getInitialTab());
|
||
|
||
// 状态管理
|
||
const status = ref(null);
|
||
const failMsg = ref("");
|
||
const isSubmitting = ref(false);
|
||
const showStatusPopup = ref(false);
|
||
const showTaxConfirmPopup = ref(false);
|
||
|
||
// 税务
|
||
const taxFreeAmount = ref(0);
|
||
const usedExemptionAmount = ref(0);
|
||
const remainingExemptionAmount = ref(0);
|
||
const taxRate = ref(0);
|
||
|
||
// 计算扣税金额和实际到账金额
|
||
const taxAmount = computed(() => {
|
||
if (!amount.value) return 0;
|
||
const withdrawAmount = Number(amount.value);
|
||
return withdrawAmount * 0.06;
|
||
});
|
||
|
||
const actualAmount = computed(() => {
|
||
if (!amount.value) return 0;
|
||
return Number(amount.value) - taxAmount.value;
|
||
});
|
||
|
||
// 样式配置
|
||
const statusIcon = {
|
||
1: "clock",
|
||
2: "checked",
|
||
3: "close",
|
||
};
|
||
|
||
const statusIconClass = {
|
||
1: "text-blue-400 border-blue-100 bg-blue-50",
|
||
2: "text-green-500 border-green-100 bg-green-50",
|
||
3: "text-red-500 border-red-100 bg-red-50",
|
||
};
|
||
|
||
const statusBg = {
|
||
1: "from-blue-100 to-blue-50",
|
||
2: "from-green-100 to-green-50",
|
||
3: "from-red-100 to-red-50",
|
||
};
|
||
|
||
const statusTextColors = {
|
||
1: "text-blue-600",
|
||
2: "text-green-600",
|
||
3: "text-red-600",
|
||
};
|
||
|
||
const statusButtonColor = {
|
||
1: "var(--van-theme-primary-light)",
|
||
2: "#10b981",
|
||
3: "#ef4444",
|
||
};
|
||
|
||
const statusMessages = {
|
||
1: activeTab.value === 'alipay' ? "提现申请处理中,请稍后再查询结果" : "提现申请已提交,等待管理员审核",
|
||
2: "提现成功",
|
||
3: "提现失败",
|
||
};
|
||
|
||
// 表单数据 - 支付宝
|
||
const alipayAccount = ref("");
|
||
const alipayRealName = ref("");
|
||
|
||
// 表单数据 - 银行卡
|
||
const bankCardNo = ref("");
|
||
const bankName = ref("");
|
||
const bankCardInfo = ref({
|
||
bank_card_no: "",
|
||
bank_name: "",
|
||
payee_name: "",
|
||
id_card: "",
|
||
});
|
||
|
||
// 共用数据
|
||
const amount = ref(0);
|
||
const availableAmount = ref(null);
|
||
|
||
// 标签页切换
|
||
const onTabChange = (name) => {
|
||
if (name === 'bankcard') {
|
||
loadBankCardInfo();
|
||
}
|
||
resetForm();
|
||
};
|
||
|
||
// 加载银行卡信息
|
||
const loadBankCardInfo = async () => {
|
||
try {
|
||
const { data, error } = await useApiFetch("/agent/withdrawal/bank-card/info")
|
||
.get()
|
||
.json();
|
||
if (data.value?.code === 200 && !error.value) {
|
||
bankCardInfo.value = data.value.data;
|
||
// 自动填充历史银行卡信息
|
||
if (data.value.data.bank_card_no) {
|
||
bankCardNo.value = data.value.data.bank_card_no;
|
||
}
|
||
if (data.value.data.bank_name) {
|
||
bankName.value = data.value.data.bank_name;
|
||
}
|
||
}
|
||
} catch (err) {
|
||
console.error("加载银行卡信息失败", err);
|
||
}
|
||
};
|
||
|
||
// 格式化身份证号(显示前6位和后4位)
|
||
const formatIdCard = (idCard) => {
|
||
if (!idCard) return "";
|
||
if (idCard.length <= 10) return idCard;
|
||
return idCard.substring(0, 6) + "****" + idCard.substring(idCard.length - 4);
|
||
};
|
||
|
||
// 验证银行卡号
|
||
const validateBankCardNo = (val) => {
|
||
if (!val) return false;
|
||
const cardNo = String(val).replace(/\s/g, "");
|
||
return /^\d{16,19}$/.test(cardNo);
|
||
};
|
||
|
||
const getData = async () => {
|
||
const { data: res, error } = await useApiFetch("/agent/revenue")
|
||
.get()
|
||
.json();
|
||
|
||
if (res.value?.code === 200 && !error.value) {
|
||
availableAmount.value = res.value.data.balance;
|
||
}
|
||
};
|
||
|
||
onBeforeMount(() => {
|
||
getData();
|
||
getTax();
|
||
// 根据配置加载对应的数据
|
||
if (showBankcard && (activeTab.value === 'bankcard' || !showTabs)) {
|
||
loadBankCardInfo();
|
||
}
|
||
});
|
||
|
||
// 表单验证
|
||
const validateAmount = (val) => {
|
||
const num = Number(val);
|
||
return num >= 50 && num <= availableAmount.value;
|
||
};
|
||
|
||
const validateForm = () => {
|
||
if (activeTab.value === 'alipay') {
|
||
// 支付宝提现验证
|
||
if (!alipayRealName.value.trim()) {
|
||
showToast("请输入账户实名姓名");
|
||
return false;
|
||
}
|
||
if (!/^[\u4e00-\u9fa5]{2,4}$/.test(alipayRealName.value)) {
|
||
showToast("请输入2-4位中文姓名");
|
||
return false;
|
||
}
|
||
if (!alipayAccount.value.trim()) {
|
||
showToast("请输入支付宝账号");
|
||
return false;
|
||
}
|
||
} else {
|
||
// 银行卡提现验证
|
||
if (!bankCardNo.value.trim()) {
|
||
showToast("请输入银行卡号");
|
||
return false;
|
||
}
|
||
const cardNo = String(bankCardNo.value).replace(/\s/g, "");
|
||
if (!/^\d{16,19}$/.test(cardNo)) {
|
||
showToast("银行卡号格式不正确,请输入16-19位数字");
|
||
return false;
|
||
}
|
||
if (!bankName.value.trim()) {
|
||
showToast("请输入开户支行");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
const amountNum = Number(amount.value);
|
||
if (!amount.value || isNaN(amountNum)) {
|
||
showToast("请输入有效金额");
|
||
return false;
|
||
}
|
||
|
||
if (amountNum < 50) {
|
||
showToast("提现金额不能低于50元");
|
||
return false;
|
||
}
|
||
|
||
if (amountNum > availableAmount.value) {
|
||
showToast("超过可提现金额");
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
// 打开实名认证对话框
|
||
const openRealNameAuth = () => {
|
||
dialogStore.openRealNameAuth();
|
||
};
|
||
|
||
// 获取税务
|
||
const getTax = async () => {
|
||
const { data, error } = await useApiFetch("/agent/withdrawal/tax/exemption")
|
||
.get()
|
||
.json();
|
||
if (data.value?.code === 200 && !error.value) {
|
||
taxFreeAmount.value = data.value.data.total_exemption_amount;
|
||
usedExemptionAmount.value = data.value.data.used_exemption_amount;
|
||
remainingExemptionAmount.value = data.value.data.remaining_exemption_amount;
|
||
taxRate.value = data.value.data.tax_rate;
|
||
}
|
||
};
|
||
|
||
const handleSubmit = async () => {
|
||
// 检查实名认证状态
|
||
if (!agentStore.isRealName) {
|
||
showToast("请先完成实名认证");
|
||
openRealNameAuth();
|
||
return;
|
||
}
|
||
|
||
// 先进行表单验证
|
||
if (!validateForm()) return;
|
||
|
||
// 显示税务确认弹窗
|
||
showTaxConfirmPopup.value = true;
|
||
};
|
||
|
||
// 确认提现
|
||
const confirmWithdraw = async () => {
|
||
isSubmitting.value = true;
|
||
try {
|
||
let apiUrl, requestData;
|
||
|
||
if (activeTab.value === 'alipay') {
|
||
// 支付宝提现
|
||
apiUrl = "/agent/withdrawal";
|
||
requestData = {
|
||
payee_account: alipayAccount.value,
|
||
amount: amount.value,
|
||
payee_name: alipayRealName.value,
|
||
};
|
||
} else {
|
||
// 银行卡提现
|
||
apiUrl = "/agent/withdrawal/bank-card";
|
||
requestData = {
|
||
bank_card_no: String(bankCardNo.value).replace(/\s/g, ""),
|
||
bank_name: bankName.value,
|
||
amount: amount.value,
|
||
};
|
||
}
|
||
|
||
const { data, error } = await useApiFetch(apiUrl)
|
||
.post(requestData)
|
||
.json();
|
||
|
||
if (data.value?.code === 200) {
|
||
status.value = data.value.data.status;
|
||
showTaxConfirmPopup.value = false;
|
||
showStatusPopup.value = true;
|
||
if (status.value === 3) {
|
||
failMsg.value = data.value.data.fail_msg || "提现失败";
|
||
}
|
||
getData();
|
||
} else {
|
||
showToast(data.value?.msg || "提现失败");
|
||
}
|
||
} catch (err) {
|
||
showToast("提现失败,请重试");
|
||
console.error("提现失败", err);
|
||
} finally {
|
||
isSubmitting.value = false;
|
||
}
|
||
};
|
||
|
||
// 弹窗操作
|
||
const handlePopupAction = () => {
|
||
if (status.value === 3) {
|
||
showStatusPopup.value = false;
|
||
resetForm();
|
||
} else {
|
||
showStatusPopup.value = false;
|
||
if (status.value === 2) resetPage();
|
||
}
|
||
};
|
||
|
||
// 填充最大金额
|
||
const fillMaxAmount = () => {
|
||
amount.value = availableAmount.value;
|
||
};
|
||
|
||
// 重置页面
|
||
const resetForm = () => {
|
||
status.value = null;
|
||
if (activeTab.value === 'alipay') {
|
||
alipayAccount.value = "";
|
||
alipayRealName.value = "";
|
||
} else {
|
||
// 银行卡提现不清空,保留历史信息
|
||
// bankCardNo.value = "";
|
||
// bankName.value = "";
|
||
}
|
||
amount.value = "";
|
||
};
|
||
|
||
const resetPage = () => {
|
||
resetForm();
|
||
// 可以跳转到提现记录页面
|
||
};
|
||
</script>
|
||
|
||
<style>
|
||
/* 自定义表单样式 */
|
||
.van-field__control {
|
||
@apply py-1 px-4 text-gray-800;
|
||
}
|
||
|
||
.van-field__error-message {
|
||
@apply mt-1;
|
||
}
|
||
|
||
.van-button--disabled {
|
||
@apply opacity-60 cursor-not-allowed;
|
||
}
|
||
|
||
/* 弹窗入场动画 */
|
||
.van-popup {
|
||
transition: transform 0.4s cubic-bezier(0.22, 0.61, 0.36, 1),
|
||
opacity 0.3s ease;
|
||
}
|
||
|
||
.van-popup-enter-active,
|
||
.van-popup-leave-active {
|
||
transition: opacity 0.3s;
|
||
}
|
||
|
||
.van-popup-enter-from,
|
||
.van-popup-leave-to {
|
||
opacity: 0;
|
||
}
|
||
|
||
.van-popup-enter-active {
|
||
transform: scale(0.95);
|
||
}
|
||
|
||
.van-popup-enter-to {
|
||
transform: scale(1);
|
||
}
|
||
|
||
/* 状态图标动画 */
|
||
.animate-pulse {
|
||
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||
}
|
||
|
||
@keyframes pulse {
|
||
50% {
|
||
opacity: 0.5;
|
||
}
|
||
}
|
||
|
||
/* 实名认证提示样式 */
|
||
.pointer-events-none {
|
||
pointer-events: none;
|
||
}
|
||
</style>
|