feat: 优化提现功能,动态显示可提现金额和绑定账户信息

This commit is contained in:
2025-12-31 12:24:33 +08:00
parent c133169c7b
commit 111d0978a3

View File

@@ -26,7 +26,7 @@
<div class="text-xs text-slate-400 mt-2">{{ metric.subtext }}</div>
<!-- Withdraw Button for Revenue Card -->
<button v-if="metric.label === '累计总收益'" @click="showWithdraw = true"
<button v-if="metric.label === '累计总收益' && metric.canWithdraw" @click="showWithdraw = true"
class="absolute top-6 right-6 px-3 py-1.5 bg-green-50 text-green-700 text-xs font-bold rounded-lg hover:bg-green-100 transition-colors">
提现
</button>
@@ -48,7 +48,7 @@
<div class="text-xs text-orange-600">需要处理</div>
</div>
</div>
<div class="text-2xl font-bold text-orange-700">2</div>
<div class="text-2xl font-bold text-orange-700">{{ stats.pending_refunds }}</div>
</div>
<div
class="flex-1 p-4 bg-blue-50 border border-blue-100 rounded-xl flex items-center justify-between cursor-pointer hover:bg-blue-100 transition-colors">
@@ -60,7 +60,7 @@
<div class="text-xs text-blue-600">粉丝互动</div>
</div>
</div>
<div class="text-2xl font-bold text-blue-700">5</div>
<div class="text-2xl font-bold text-blue-700">{{ stats.new_messages }}</div>
</div>
</div>
</div>
@@ -80,7 +80,7 @@
class="pi pi-credit-card text-xl"></i></div>
<div class="flex-1">
<div class="font-bold text-slate-900">提现至银行卡/支付宝</div>
<div class="text-xs text-slate-500" v-if="hasPayoutAccount">已绑定招商银行 (8888)</div>
<div class="text-xs text-slate-500" v-if="hasPayoutAccount">已绑定{{ payoutAccounts[0].name }} ({{ payoutAccounts[0].account.slice(-4) }})</div>
<div class="text-xs text-orange-600 font-bold flex items-center gap-1" v-else>
<i class="pi pi-exclamation-circle"></i> 未配置收款账户
<router-link to="/creator/settings"
@@ -107,11 +107,11 @@
<div>
<label class="block text-sm font-bold text-slate-700 mb-2">提现金额 (¥)</label>
<input type="number" placeholder="请输入金额"
<input type="number" v-model="withdrawAmount" placeholder="请输入金额"
class="w-full h-12 px-4 border border-slate-200 rounded-lg text-lg font-bold outline-none focus:border-primary-500 transition-colors">
<div class="text-xs text-slate-400 mt-2 flex justify-between">
<span>可提现收益: ¥ 8,920.50</span>
<button class="text-primary-600 hover:underline">全部提现</button>
<span>可提现收益: ¥ {{ stats.total_revenue.value.toLocaleString(undefined, {minimumFractionDigits: 2}) }}</span>
<button class="text-primary-600 hover:underline" @click="withdrawAmount = stats.total_revenue.value">全部提现</button>
</div>
</div>
</div>
@@ -133,21 +133,78 @@
import Dialog from 'primevue/dialog';
import Toast from 'primevue/toast';
import { useToast } from 'primevue/usetoast';
import { ref } from 'vue';
import { ref, onMounted, computed } from 'vue';
import { creatorApi } from '../../api/creator';
const toast = useToast();
const showWithdraw = ref(false);
const withdrawMethod = ref('wallet');
const hasPayoutAccount = ref(false); // Mock state
const withdrawAmount = ref('');
const payoutAccounts = ref([]);
const stats = ref({
total_followers: { value: 0, trend: 0 },
total_revenue: { value: 0, trend: 0 },
pending_refunds: 0,
new_messages: 0
});
const metrics = ref([
{ label: '总关注用户', value: '12,548', trend: 1.2, subtext: '昨日 +125' },
{ label: '累计总收益', value: '¥ 8,920.50', trend: 5.4, subtext: '近30天 +2,300' },
const hasPayoutAccount = computed(() => payoutAccounts.value.length > 0);
const metrics = computed(() => [
{
label: '总关注用户',
value: stats.value.total_followers.value.toLocaleString(),
trend: stats.value.total_followers.trend,
subtext: '昨日数据' // Backend DTO doesn't have subtext yet, using static or simplified
},
{
label: '累计总收益',
value: '¥ ' + stats.value.total_revenue.value.toLocaleString(undefined, {minimumFractionDigits: 2}),
trend: stats.value.total_revenue.trend,
subtext: '近30天数据',
canWithdraw: stats.value.total_revenue.value > 0
},
]);
const handleWithdraw = () => {
showWithdraw.value = false;
const msg = withdrawMethod.value === 'wallet' ? '资金已转入您的个人钱包' : '提现申请已提交至银行处理';
toast.add({ severity: 'success', summary: '提现成功', detail: msg, life: 3000 });
const fetchData = async () => {
try {
const [dashboardRes, accountsRes] = await Promise.all([
creatorApi.getDashboard(),
creatorApi.listPayoutAccounts()
]);
if (dashboardRes) stats.value = dashboardRes;
if (accountsRes) payoutAccounts.value = accountsRes;
} catch (e) {
console.error("Failed to fetch creator dashboard data:", e);
}
};
onMounted(() => {
fetchData();
});
const handleWithdraw = async () => {
if (!withdrawAmount.value || withdrawAmount.value <= 0) {
toast.add({ severity: 'warn', summary: '提示', detail: '请输入有效的提现金额', life: 3000 });
return;
}
try {
const accountId = withdrawMethod.value === 'external' ? payoutAccounts.value[0]?.id : ''; // Default to first account for now if external
await creatorApi.withdraw({
amount: parseFloat(withdrawAmount.value),
method: withdrawMethod.value,
account_id: accountId
});
showWithdraw.value = false;
toast.add({ severity: 'success', summary: '提现成功', detail: '提现申请已提交', life: 3000 });
withdrawAmount.value = ''; // Reset
fetchData(); // Refresh balance/stats
} catch (e) {
console.error(e);
toast.add({ severity: 'error', summary: '提现失败', detail: '请稍后重试', life: 3000 });
}
};
</script>