增加提现相关的与打款相关逻辑
This commit is contained in:
@@ -0,0 +1,307 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Plus, Delete, Star, StarFilled, Edit } from '@element-plus/icons-vue'
|
||||
|
||||
import {
|
||||
fetchPaymentAccounts,
|
||||
deletePaymentAccount,
|
||||
setDefaultPaymentAccount,
|
||||
type PaymentAccount,
|
||||
} from '../api/withdrawal'
|
||||
|
||||
import PaymentAccountDialog from '../components/PaymentAccountDialog.vue'
|
||||
|
||||
const loading = ref(false)
|
||||
const accounts = ref<PaymentAccount[]>([])
|
||||
const total = ref(0)
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(20)
|
||||
|
||||
const showDialog = ref(false)
|
||||
const editingAccount = ref<PaymentAccount | null>(null)
|
||||
|
||||
onMounted(() => {
|
||||
loadAccounts()
|
||||
})
|
||||
|
||||
async function loadAccounts() {
|
||||
loading.value = true
|
||||
try {
|
||||
const result = await fetchPaymentAccounts(currentPage.value, pageSize.value)
|
||||
accounts.value = result.items
|
||||
total.value = result.total
|
||||
} catch (error: any) {
|
||||
ElMessage.error(error.response?.data?.message || '加载失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function openCreateDialog() {
|
||||
editingAccount.value = null
|
||||
showDialog.value = true
|
||||
}
|
||||
|
||||
function openEditDialog(account: PaymentAccount) {
|
||||
editingAccount.value = account
|
||||
showDialog.value = true
|
||||
}
|
||||
|
||||
async function handleSetDefault(account: PaymentAccount) {
|
||||
if (account.is_default) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
await setDefaultPaymentAccount(account.id)
|
||||
ElMessage.success('已设为默认账号')
|
||||
await loadAccounts()
|
||||
} catch (error: any) {
|
||||
ElMessage.error(error.response?.data?.message || '操作失败')
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDelete(account: PaymentAccount) {
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定要删除此收款账号吗?`, '删除确认', {
|
||||
confirmButtonText: '确认删除',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
await deletePaymentAccount(account.id)
|
||||
ElMessage.success('删除成功')
|
||||
await loadAccounts()
|
||||
} catch (error: any) {
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error(error.response?.data?.message || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function accountTypeLabel(type: string) {
|
||||
const labels: Record<string, string> = {
|
||||
alipay: '支付宝',
|
||||
wechat: '微信',
|
||||
bank: '银行卡',
|
||||
}
|
||||
return labels[type] || type
|
||||
}
|
||||
|
||||
function accountTypeColor(type: string) {
|
||||
const colors: Record<string, string> = {
|
||||
alipay: '#1677ff',
|
||||
wechat: '#07c160',
|
||||
bank: '#ff6a00',
|
||||
}
|
||||
return colors[type] || '#999'
|
||||
}
|
||||
|
||||
const canAddMore = computed(() => accounts.value.length < 5)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="payment-accounts-page">
|
||||
<div class="page-header">
|
||||
<div>
|
||||
<h2>收款账号管理</h2>
|
||||
<p class="page-desc">管理您的收款账号,用于提现时接收资金(最多5个)</p>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="canAddMore"
|
||||
type="primary"
|
||||
:icon="Plus"
|
||||
@click="openCreateDialog"
|
||||
>
|
||||
添加收款账号
|
||||
</el-button>
|
||||
<el-tag v-else type="info">已达账号数量上限</el-tag>
|
||||
</div>
|
||||
|
||||
<el-alert
|
||||
v-if="accounts.length === 0 && !loading"
|
||||
title="还没有收款账号"
|
||||
type="info"
|
||||
description="请先添加收款账号,才能进行提现操作。账户名必须与您的实名认证姓名一致。"
|
||||
show-icon
|
||||
:closable="false"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
|
||||
<div v-loading="loading" class="accounts-grid">
|
||||
<div
|
||||
v-for="account in accounts"
|
||||
:key="account.id"
|
||||
class="account-card"
|
||||
:class="{ 'is-default': account.is_default }"
|
||||
>
|
||||
<div class="account-header">
|
||||
<div class="account-type">
|
||||
<el-tag
|
||||
:color="accountTypeColor(account.account_type)"
|
||||
effect="dark"
|
||||
size="large"
|
||||
>
|
||||
{{ accountTypeLabel(account.account_type) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div class="account-actions">
|
||||
<el-tooltip
|
||||
:content="account.is_default ? '默认账号' : '设为默认'"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
:icon="account.is_default ? StarFilled : Star"
|
||||
:type="account.is_default ? 'warning' : 'default'"
|
||||
circle
|
||||
size="small"
|
||||
@click="handleSetDefault(account)"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<el-button
|
||||
:icon="Edit"
|
||||
circle
|
||||
size="small"
|
||||
@click="openEditDialog(account)"
|
||||
/>
|
||||
<el-button
|
||||
:icon="Delete"
|
||||
circle
|
||||
size="small"
|
||||
type="danger"
|
||||
@click="handleDelete(account)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="account-info">
|
||||
<div class="info-row">
|
||||
<span class="label">账户名:</span>
|
||||
<span class="value">{{ account.account_name }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="label">账号:</span>
|
||||
<span class="value monospace">{{ account.account_no }}</span>
|
||||
</div>
|
||||
<div v-if="account.account_type === 'bank'" class="info-row">
|
||||
<span class="label">银行:</span>
|
||||
<span class="value">{{ account.bank_name }}</span>
|
||||
</div>
|
||||
<div v-if="account.account_type === 'bank' && account.bank_branch" class="info-row">
|
||||
<span class="label">支行:</span>
|
||||
<span class="value">{{ account.bank_branch }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="account-footer">
|
||||
<span class="created-time">添加于 {{ new Date(account.created_at).toLocaleDateString() }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<PaymentAccountDialog
|
||||
v-model="showDialog"
|
||||
:account="editingAccount"
|
||||
@saved="loadAccounts"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.payment-accounts-page {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.page-header h2 {
|
||||
margin: 0 0 8px;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.page-desc {
|
||||
margin: 0;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.accounts-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.account-card {
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.account-card:hover {
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.account-card.is-default {
|
||||
border-color: #f59e0b;
|
||||
background: linear-gradient(135deg, #fffbeb 0%, #ffffff 100%);
|
||||
}
|
||||
|
||||
.account-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.account-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.account-info {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.info-row .label {
|
||||
width: 70px;
|
||||
color: #666;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info-row .value {
|
||||
flex: 1;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.info-row .value.monospace {
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.account-footer {
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.created-time {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user