445 lines
10 KiB
Vue
445 lines
10 KiB
Vue
<template>
|
||
<div class="withdrawal-management">
|
||
<!-- 提现账户信息卡片 -->
|
||
<a-row :gutter="24" class="mb-6">
|
||
|
||
<a-col :span="24">
|
||
<a-card title="可提现金额">
|
||
<div class="balance-info">
|
||
<div class="balance-amount">
|
||
<span class="amount">{{ formatCurrency(accountInfo.availableBalance) }}</span>
|
||
<span class="currency">元</span>
|
||
</div>
|
||
<div class="balance-desc">
|
||
当前可提现金额,提现将在1-3个工作日内到账
|
||
</div>
|
||
<a-button type="primary" class="w-full mt-4" @click="showWithdrawalModal"
|
||
:disabled="accountInfo.availableBalance <= 0">
|
||
去提现
|
||
</a-button>
|
||
</div>
|
||
</a-card>
|
||
</a-col>
|
||
</a-row>
|
||
|
||
<!-- 提现记录查询 -->
|
||
<a-card title="提现记录" class="mb-6">
|
||
<template #extra>
|
||
|
||
</template>
|
||
|
||
<!-- 查询条件 -->
|
||
<a-form layout="inline" :model="searchParams" class="mb-4">
|
||
<a-form-item label="提现单号">
|
||
<a-input v-model:value="searchParams.orderNo" placeholder="请输入提现单号" @pressEnter="handleSearch" />
|
||
</a-form-item>
|
||
<a-form-item label="时间">
|
||
<a-range-picker v-model:value="searchParams.dateRange" :format="dateFormat" @change="handleDateChange" />
|
||
</a-form-item>
|
||
<a-form-item>
|
||
<a-button type="primary" @click="handleSearch">查询</a-button>
|
||
<a-button @click="handleReset" class="ml-2">重置</a-button>
|
||
</a-form-item>
|
||
</a-form>
|
||
|
||
<!-- 提现记录表格 -->
|
||
<a-table :columns="columns" :data-source="withdrawalRecords" :pagination="pagination" @change="handleTableChange"
|
||
:loading="loading" rowKey="id">
|
||
<template #bodyCell="{ column, record }">
|
||
<template v-if="column.key === 'amount'">
|
||
<span class="amount-cell">{{ formatCurrency(record.amount) }}元</span>
|
||
</template>
|
||
|
||
<template v-else-if="column.key === 'status'">
|
||
<a-tag :color="getStatusColor(record.status)">
|
||
{{ getStatusText(record.status) }}
|
||
</a-tag>
|
||
</template>
|
||
|
||
<template v-else-if="column.key === 'createdAt'">
|
||
{{ formatDate(record.createdAt) }}
|
||
</template>
|
||
|
||
<template v-else-if="column.key === 'completedAt'">
|
||
{{ record.completedAt ? formatDate(record.completedAt) : '-' }}
|
||
</template>
|
||
|
||
<template v-else-if="column.key === 'actions'">
|
||
<a-button type="link" @click="viewDetail(record)">查看详情</a-button>
|
||
</template>
|
||
</template>
|
||
</a-table>
|
||
</a-card>
|
||
|
||
<!-- 提现弹窗 -->
|
||
<a-modal v-model:visible="withdrawalModal.visible" title="提现申请" @ok="handleWithdrawalSubmit"
|
||
@cancel="handleWithdrawalCancel" :confirm-loading="withdrawalModal.confirming">
|
||
<a-form ref="withdrawalFormRef" :model="withdrawalForm" :rules="withdrawalRules" layout="vertical">
|
||
<a-form-item label="提现金额" name="amount">
|
||
<a-input-number v-model:value="withdrawalForm.amount" placeholder="请输入提现金额" :min="1"
|
||
:max="accountInfo.availableBalance" style="width: 100%"
|
||
:formatter="value => `¥ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"
|
||
:parser="value => value.replace(/¥\s?|(,*)/g, '')" />
|
||
<div class="amount-hint mt-2">
|
||
<div>可提现金额: {{ formatCurrency(accountInfo.availableBalance) }}元</div>
|
||
<div>单笔最低提现: 1元</div>
|
||
</div>
|
||
</a-form-item>
|
||
|
||
<a-form-item label="提现到账账户" name="accountId">
|
||
<a-select v-model:value="withdrawalForm.accountId" placeholder="请选择提现账户">
|
||
<a-select-option :value="accountInfo.id">
|
||
{{ accountInfo.bank }} ({{ accountInfo.number }})
|
||
</a-select-option>
|
||
</a-select>
|
||
</a-form-item>
|
||
|
||
<a-alert v-if="withdrawalForm.amount"
|
||
:message="`预计到账金额: ${formatCurrency(calculateActualAmount(withdrawalForm.amount))}元`" type="info" show-icon
|
||
class="mb-4" />
|
||
</a-form>
|
||
</a-modal>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, reactive, onMounted } from 'vue'
|
||
import { message } from 'ant-design-vue'
|
||
import dayjs from 'dayjs'
|
||
import { getWithdrawList } from "@/apis/home"
|
||
// 账户信息
|
||
const accountInfo = reactive({
|
||
id: '1',
|
||
type: '银行账户',
|
||
number: '6228 **** **** 5678',
|
||
name: '张三',
|
||
bank: '中国工商银行',
|
||
availableBalance: 5000.00
|
||
})
|
||
|
||
// 提现记录查询参数
|
||
const searchParams = reactive({
|
||
orderNo: '',
|
||
account: undefined,
|
||
status: undefined,
|
||
dateRange: [dayjs().subtract(30, 'day'), dayjs()]
|
||
})
|
||
|
||
// 分页配置
|
||
const pagination = reactive({
|
||
current: 1,
|
||
pageSize: 10,
|
||
total: 0,
|
||
showSizeChanger: true,
|
||
showQuickJumper: true,
|
||
showTotal: total => `共 ${total} 条记录`
|
||
})
|
||
|
||
// 表格列定义
|
||
const columns = [
|
||
{
|
||
title: '提现单号',
|
||
dataIndex: 'orderNo',
|
||
key: 'orderNo',
|
||
width: 200
|
||
},
|
||
{
|
||
title: '账户',
|
||
key: 'account',
|
||
width: 180,
|
||
render: (_, record) => `${record.bank} (${record.accountNumber})`
|
||
},
|
||
{
|
||
title: '提现金额',
|
||
key: 'amount',
|
||
width: 120,
|
||
align: 'right'
|
||
},
|
||
{
|
||
title: '手续费',
|
||
dataIndex: 'fee',
|
||
key: 'fee',
|
||
width: 100,
|
||
align: 'right',
|
||
render: fee => fee ? `${fee}元` : '-'
|
||
},
|
||
{
|
||
title: '状态',
|
||
key: 'status',
|
||
width: 100
|
||
},
|
||
{
|
||
title: '申请时间',
|
||
key: 'createdAt',
|
||
width: 180
|
||
},
|
||
{
|
||
title: '完成时间',
|
||
key: 'completedAt',
|
||
width: 180
|
||
},
|
||
{
|
||
title: '操作',
|
||
key: 'actions',
|
||
width: 100,
|
||
fixed: 'right'
|
||
}
|
||
]
|
||
|
||
// 提现记录数据
|
||
const withdrawalRecords = ref([])
|
||
const loading = ref(false)
|
||
const accountOptions = ref([
|
||
{ value: '1', label: '工商银行(尾号5678)' },
|
||
{ value: '2', label: '建设银行(尾号1234)' }
|
||
])
|
||
|
||
// 提现弹窗
|
||
const withdrawalModal = reactive({
|
||
visible: false,
|
||
confirming: false
|
||
})
|
||
|
||
// 提现表单
|
||
const withdrawalFormRef = ref()
|
||
const withdrawalForm = reactive({
|
||
amount: undefined,
|
||
accountId: accountInfo.id
|
||
})
|
||
|
||
// 表单验证规则
|
||
const withdrawalRules = {
|
||
amount: [
|
||
{ required: true, message: '请输入提现金额' },
|
||
{ type: 'number', min: 1, max: accountInfo.availableBalance, message: `提现金额需在1-${accountInfo.availableBalance}元之间` }
|
||
],
|
||
accountId: [
|
||
{ required: true, message: '请选择提现账户' }
|
||
]
|
||
}
|
||
|
||
// 日期格式
|
||
const dateFormat = 'YYYY-MM-DD'
|
||
|
||
// 生命周期
|
||
onMounted(() => {
|
||
const userInfoStr=localStorage.getItem("userInfo")
|
||
if(userInfoStr){
|
||
const userInfo = JSON.parse(userInfoStr);
|
||
accountInfo.availableBalance=userInfo.balance
|
||
}
|
||
fetchWithdrawalRecords()
|
||
})
|
||
|
||
// 获取提现记录
|
||
const fetchWithdrawalRecords = async () => {
|
||
loading.value = true
|
||
console.log(searchParams)
|
||
try {
|
||
let params = {
|
||
withdraw_number: searchParams.orderNo,
|
||
page_num: pagination.current,
|
||
page_size: pagination.pageSize,
|
||
start_at: formatDate(searchParams.dateRange[0]),
|
||
end_at: formatDate(searchParams.dateRange[1]),
|
||
}
|
||
const res = await getWithdrawList(params)
|
||
console.log(res)
|
||
} catch (error) {
|
||
console.log(error)
|
||
message.error('获取提现记录失败')
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
// 表格分页变化
|
||
const handleTableChange = (page) => {
|
||
pagination.current = page.current
|
||
pagination.pageSize = page.pageSize
|
||
fetchWithdrawalRecords()
|
||
}
|
||
|
||
// 查询
|
||
const handleSearch = () => {
|
||
pagination.current = 1
|
||
fetchWithdrawalRecords()
|
||
}
|
||
|
||
// 重置查询
|
||
const handleReset = () => {
|
||
searchParams.orderNo = ''
|
||
searchParams.account = undefined
|
||
searchParams.status = undefined
|
||
searchParams.dateRange = [dayjs().subtract(30, 'day'), dayjs()]
|
||
handleSearch()
|
||
}
|
||
|
||
// 日期变化
|
||
const handleDateChange = () => {
|
||
handleSearch()
|
||
}
|
||
|
||
// 显示提现弹窗
|
||
const showWithdrawalModal = () => {
|
||
withdrawalModal.visible = true
|
||
}
|
||
|
||
// 处理提现提交
|
||
const handleWithdrawalSubmit = async () => {
|
||
try {
|
||
await withdrawalFormRef.value.validate()
|
||
withdrawalModal.confirming = true
|
||
|
||
// 模拟API调用
|
||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||
|
||
message.success('提现申请提交成功')
|
||
|
||
// 更新账户余额
|
||
accountInfo.availableBalance -= withdrawalForm.amount
|
||
|
||
// 重置表单并关闭弹窗
|
||
withdrawalFormRef.value.resetFields()
|
||
withdrawalModal.visible = false
|
||
|
||
// 刷新记录
|
||
fetchWithdrawalRecords()
|
||
} catch (error) {
|
||
console.error('提现提交失败:', error)
|
||
} finally {
|
||
withdrawalModal.confirming = false
|
||
}
|
||
}
|
||
|
||
// 处理提现取消
|
||
const handleWithdrawalCancel = () => {
|
||
withdrawalFormRef.value.resetFields()
|
||
withdrawalModal.visible = false
|
||
}
|
||
|
||
// 查看详情
|
||
const viewDetail = (record) => {
|
||
message.info(`查看提现记录详情: ${record.orderNo}`)
|
||
}
|
||
|
||
// 计算实际到账金额
|
||
const calculateActualAmount = (amount) => {
|
||
const fee = amount * 0.01 // 假设手续费1%
|
||
return amount - fee
|
||
}
|
||
|
||
// 格式化货币
|
||
const formatCurrency = (amount) => {
|
||
return amount.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
|
||
}
|
||
|
||
// 格式化日期
|
||
const formatDate = (dateString) => {
|
||
return dayjs(dateString).format('YYYY-MM-DD')
|
||
}
|
||
|
||
// 获取状态颜色
|
||
const getStatusColor = (status) => {
|
||
const colors = {
|
||
pending: 'orange',
|
||
success: 'green',
|
||
failed: 'red'
|
||
}
|
||
return colors[status] || 'default'
|
||
}
|
||
|
||
// 获取状态文本
|
||
const getStatusText = (status) => {
|
||
const texts = {
|
||
pending: '处理中',
|
||
success: '成功',
|
||
failed: '失败'
|
||
}
|
||
return texts[status] || status
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.withdrawal-management {
|
||
padding: 20px;
|
||
}
|
||
|
||
.account-info .info-item {
|
||
margin-bottom: 12px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.account-info .label {
|
||
color: #666;
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.account-info .value {
|
||
color: #333;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.balance-info .balance-amount {
|
||
text-align: center;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.balance-info .amount {
|
||
font-size: 32px;
|
||
font-weight: bold;
|
||
color: #1890ff;
|
||
}
|
||
|
||
.balance-info .currency {
|
||
font-size: 18px;
|
||
color: #666;
|
||
margin-left: 4px;
|
||
}
|
||
|
||
.balance-info .balance-desc {
|
||
color: #666;
|
||
font-size: 12px;
|
||
text-align: center;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.amount-hint {
|
||
color: #666;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.amount-hint div {
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.amount-cell {
|
||
color: #1890ff;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.mb-4 {
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.mb-6 {
|
||
margin-bottom: 24px;
|
||
}
|
||
|
||
.mt-2 {
|
||
margin-top: 8px;
|
||
}
|
||
|
||
.mt-4 {
|
||
margin-top: 16px;
|
||
}
|
||
|
||
.ml-2 {
|
||
margin-left: 8px;
|
||
}
|
||
|
||
.w-full {
|
||
float: inline-end;
|
||
width: 10%;
|
||
}
|
||
</style> |