Files
tydata-webview-v2/src/views/Withdraw.vue

833 lines
36 KiB
Vue
Raw Normal View History

2025-09-27 17:41:14 +08:00
<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>
2025-12-25 12:57:40 +08:00
<!-- 提现方式切换标签 -->
<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>
2025-09-27 17:41:14 +08:00
2025-12-25 12:57:40 +08:00
<!-- 支付宝账号 -->
<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>
2025-09-27 17:41:14 +08:00
2025-12-25 12:57:40 +08:00
<!-- 实名信息展示 -->
<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>
2025-09-27 17:41:14 +08:00
2025-12-25 12:57:40 +08:00
<!-- 银行卡号 -->
<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>
2025-09-27 17:41:14 +08:00
2025-12-25 12:57:40 +08:00
<!-- 支付宝账号 -->
<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>
2025-09-27 17:41:14 +08:00
</div>
2025-12-25 12:57:40 +08:00
<!-- 银行卡号 -->
<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>
2025-09-27 17:41:14 +08:00
</div>
2025-12-25 12:57:40 +08:00
<!-- 开户支行 -->
<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>
2025-09-27 17:41:14 +08:00
</div>
</div>
</div>
2025-12-25 12:57:40 +08:00
<!-- 提现金额共用 -->
<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>
2025-09-27 17:41:14 +08:00
<!-- 提交按钮 -->
<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);">
2025-12-25 12:57:40 +08:00
<span v-if="activeTab === 'alipay'">
已向
<span style="color: var(--van-theme-primary);">{{ alipayAccount }}</span>
转账
</span>
<span v-else>
提现申请已通过管理员将手动转账
</span>
2025-09-27 17:41:14 +08:00
</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">
2025-12-25 12:57:40 +08:00
<p v-if="activeTab === 'alipay'">预计24小时内到账</p>
<p v-else>请等待管理员审核并转账</p>
2025-09-27 17:41:14 +08:00
</template>
<template v-if="status === 1">
2025-12-25 12:57:40 +08:00
<p v-if="activeTab === 'alipay'">您的申请已进入处理队列</p>
<p v-else>您的申请已提交等待管理员审核</p>
<p>可在提现记录中查看结果</p>
2025-09-27 17:41:14 +08:00
</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>
2025-12-25 12:57:40 +08:00
import { ref, computed, onBeforeMount } from "vue";
2025-09-27 17:41:14 +08:00
import { showToast } from "vant";
import RealNameAuthDialog from "@/components/RealNameAuthDialog.vue";
const agentStore = useAgentStore();
const dialogStore = useDialogStore();
2025-12-25 12:57:40 +08:00
// ========== 提现方式配置开关 ==========
// 可以通过环境变量或后端接口控制
// 配置选项:
// - '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());
2025-09-27 17:41:14 +08:00
// 状态管理
const status = ref(null);
const failMsg = ref("");
const isSubmitting = ref(false);
const showStatusPopup = ref(false);
const showTaxConfirmPopup = ref(false);
// 税务
2025-12-25 12:57:40 +08:00
const taxFreeAmount = ref(0);
const usedExemptionAmount = ref(0);
const remainingExemptionAmount = ref(0);
const taxRate = ref(0);
2025-09-27 17:41:14 +08:00
// 计算扣税金额和实际到账金额
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",
};
2025-12-25 12:57:40 +08:00
2025-09-27 17:41:14 +08:00
const statusMessages = {
2025-12-25 12:57:40 +08:00
1: activeTab.value === 'alipay' ? "提现申请处理中,请稍后再查询结果" : "提现申请已提交,等待管理员审核",
2025-09-27 17:41:14 +08:00
2: "提现成功",
3: "提现失败",
};
2025-12-25 12:57:40 +08:00
// 表单数据 - 支付宝
2025-09-27 17:41:14 +08:00
const alipayAccount = ref("");
2025-12-25 12:57:40 +08:00
const alipayRealName = ref("");
// 表单数据 - 银行卡
const bankCardNo = ref("");
const bankName = ref("");
const bankCardInfo = ref({
bank_card_no: "",
bank_name: "",
payee_name: "",
id_card: "",
});
// 共用数据
2025-09-27 17:41:14 +08:00
const amount = ref(0);
const availableAmount = ref(null);
2025-12-25 12:57:40 +08:00
// 标签页切换
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);
};
2025-09-27 17:41:14 +08:00
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();
2025-12-25 12:57:40 +08:00
// 根据配置加载对应的数据
if (showBankcard && (activeTab.value === 'bankcard' || !showTabs)) {
loadBankCardInfo();
}
2025-09-27 17:41:14 +08:00
});
// 表单验证
const validateAmount = (val) => {
const num = Number(val);
return num >= 50 && num <= availableAmount.value;
};
const validateForm = () => {
2025-12-25 12:57:40 +08:00
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;
}
2025-09-27 17:41:14 +08:00
}
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 {
2025-12-25 12:57:40 +08:00
let apiUrl, requestData;
if (activeTab.value === 'alipay') {
// 支付宝提现
apiUrl = "/agent/withdrawal";
requestData = {
2025-09-27 17:41:14 +08:00
payee_account: alipayAccount.value,
amount: amount.value,
2025-12-25 12:57:40 +08:00
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)
2025-09-27 17:41:14 +08:00
.json();
2025-12-25 12:57:40 +08:00
2025-09-27 17:41:14 +08:00
if (data.value?.code === 200) {
status.value = data.value.data.status;
showTaxConfirmPopup.value = false;
showStatusPopup.value = true;
if (status.value === 3) {
2025-12-25 12:57:40 +08:00
failMsg.value = data.value.data.fail_msg || "提现失败";
2025-09-27 17:41:14 +08:00
}
2025-12-25 12:57:40 +08:00
getData();
} else {
showToast(data.value?.msg || "提现失败");
2025-09-27 17:41:14 +08:00
}
2025-12-25 12:57:40 +08:00
} catch (err) {
showToast("提现失败,请重试");
console.error("提现失败", err);
2025-09-27 17:41:14 +08:00
} finally {
isSubmitting.value = false;
}
};
// 弹窗操作
const handlePopupAction = () => {
if (status.value === 3) {
showStatusPopup.value = false;
resetForm();
} else {
showStatusPopup.value = false;
if (status.value === 2) resetPage();
}
};
2025-12-25 12:57:40 +08:00
2025-09-27 17:41:14 +08:00
// 填充最大金额
const fillMaxAmount = () => {
amount.value = availableAmount.value;
};
// 重置页面
const resetForm = () => {
status.value = null;
2025-12-25 12:57:40 +08:00
if (activeTab.value === 'alipay') {
alipayAccount.value = "";
alipayRealName.value = "";
} else {
// 银行卡提现不清空,保留历史信息
// bankCardNo.value = "";
// bankName.value = "";
}
2025-09-27 17:41:14 +08:00
amount.value = "";
2025-12-25 12:57:40 +08:00
};
const resetPage = () => {
resetForm();
// 可以跳转到提现记录页面
2025-09-27 17:41:14 +08:00
};
</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>