This commit is contained in:
parent
f8f1159666
commit
0449c4fe8f
|
|
@ -45,3 +45,19 @@ export const withdraw = (params: {
|
||||||
}) => {
|
}) => {
|
||||||
return request.post('/withdraw/withdraw', params)
|
return request.post('/withdraw/withdraw', params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 提现审核列表
|
||||||
|
export const getWithdrawReviewList = (params: {
|
||||||
|
page: number
|
||||||
|
page_size: number
|
||||||
|
start_time?: string
|
||||||
|
end_time?: string
|
||||||
|
user_name?: string
|
||||||
|
}) => {
|
||||||
|
return request.get('/withdraw/withdrawReviewList', params as any)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提现审核操作(通过/驳回)
|
||||||
|
export const withdrawReviewOrder = (params: { id: number; status: number }) => {
|
||||||
|
return request.post('/withdraw/withdrawReviewOrder', params)
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<Dialog
|
<Dialog :visible="dialogVisible"
|
||||||
:visible="dialogVisible"
|
:title="currentStep === 1 ? t('withdraw.dialog.title1') : t('withdraw.dialog.title2')" width="600px"
|
||||||
:title="currentStep === 1 ? t('withdraw.dialog.title1') : t('withdraw.dialog.title2')"
|
:show-footer="false" @close="handleUpdateVisible">
|
||||||
width="600px"
|
|
||||||
:show-footer="false"
|
|
||||||
@close="handleUpdateVisible"
|
|
||||||
>
|
|
||||||
<!-- 第一步:输入金额并展示计算明细 -->
|
<!-- 第一步:输入金额并展示计算明细 -->
|
||||||
<div v-if="currentStep === 1" class="step1-container">
|
<div v-if="currentStep === 1" class="step1-container">
|
||||||
<!-- 钱包余额展示 -->
|
<!-- 钱包余额展示 -->
|
||||||
|
|
@ -14,27 +10,27 @@
|
||||||
<div class="wallet-grid">
|
<div class="wallet-grid">
|
||||||
<div class="wallet-item">
|
<div class="wallet-item">
|
||||||
<span class="wallet-label">{{ t('withdraw.wallet.feeHandling') }}</span>
|
<span class="wallet-label">{{ t('withdraw.wallet.feeHandling') }}</span>
|
||||||
<span class="wallet-value">{{ walletInfo.commission_fee_handling || 0 }}</span>
|
<span class="wallet-value">{{ walletInfo.commission_fee_handling || '0.00'}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="wallet-item">
|
<div class="wallet-item">
|
||||||
<span class="wallet-label">{{ t('withdraw.wallet.pointDiff') }}</span>
|
<span class="wallet-label">{{ t('withdraw.wallet.pointDiff') }}</span>
|
||||||
<span class="wallet-value">{{ walletInfo.commission_point_diff || 0 }}</span>
|
<span class="wallet-value">{{ walletInfo.commission_point_diff || '0.00'}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="wallet-item">
|
<div class="wallet-item">
|
||||||
<span class="wallet-label">{{ t('withdraw.wallet.service') }}</span>
|
<span class="wallet-label">{{ t('withdraw.wallet.service') }}</span>
|
||||||
<span class="wallet-value">{{ walletInfo.service || 0 }}</span>
|
<span class="wallet-value">{{ walletInfo.service || '0.00'}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="wallet-item" v-if="showRiskFee">
|
<div class="wallet-item" v-if="showRiskFee">
|
||||||
<span class="wallet-label">{{ t('withdraw.wallet.risk') }}</span>
|
<span class="wallet-label">{{ t('withdraw.wallet.risk') }}</span>
|
||||||
<span class="wallet-value">{{ walletInfo.risk || 0 }}</span>
|
<span class="wallet-value">{{ walletInfo.risk || '0.00'}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="wallet-item">
|
<div class="wallet-item">
|
||||||
<span class="wallet-label">{{ t('withdraw.wallet.profit') }}</span>
|
<span class="wallet-label">{{ t('withdraw.wallet.profit') }}</span>
|
||||||
<span class="wallet-value">{{ walletInfo.closing_profit || 0 }}</span>
|
<span class="wallet-value">{{ walletInfo.closing_profit || '0.00'}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="wallet-item" v-if="roleId >= 5">
|
<div class="wallet-item" v-if="roleId >= 5">
|
||||||
<span class="wallet-label">{{ t('withdraw.wallet.available') }}</span>
|
<span class="wallet-label">{{ t('withdraw.wallet.available') }}</span>
|
||||||
<span class="wallet-value available">{{ availableBalance.toFixed(2) }}</span>
|
<span class="wallet-value available">{{ availableBalance || '0.00' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -45,12 +41,8 @@
|
||||||
{{ t('withdraw.dialog.amount') }}
|
{{ t('withdraw.dialog.amount') }}
|
||||||
<span class="max-balance">(最大可取:{{ totalWalletBalance }} {{ currentCurrency }})</span>
|
<span class="max-balance">(最大可取:{{ totalWalletBalance }} {{ currentCurrency }})</span>
|
||||||
</div>
|
</div>
|
||||||
<el-input
|
<el-input v-model="withdrawAmount" type="number" :placeholder="t('withdraw.dialog.amountPlaceholder')"
|
||||||
v-model="withdrawAmount"
|
@input="handleAmountInput">
|
||||||
type="number"
|
|
||||||
:placeholder="t('withdraw.dialog.amountPlaceholder')"
|
|
||||||
@input="handleAmountInput"
|
|
||||||
>
|
|
||||||
<template #prepend>{{ currentCurrency }}</template>
|
<template #prepend>{{ currentCurrency }}</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<div v-if="amountError" class="amount-error">{{ amountError }}</div>
|
<div v-if="amountError" class="amount-error">{{ amountError }}</div>
|
||||||
|
|
@ -92,12 +84,7 @@
|
||||||
|
|
||||||
<!-- 快捷金额 -->
|
<!-- 快捷金额 -->
|
||||||
<div class="quick-amounts">
|
<div class="quick-amounts">
|
||||||
<el-button
|
<el-button v-for="amount in quickAmounts" :key="amount" size="small" @click="handleQuickAmount(amount)">
|
||||||
v-for="amount in quickAmounts"
|
|
||||||
:key="amount"
|
|
||||||
size="small"
|
|
||||||
@click="handleQuickAmount(amount)"
|
|
||||||
>
|
|
||||||
{{ amount }}
|
{{ amount }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -111,12 +98,7 @@
|
||||||
|
|
||||||
<!-- 第二步:确认表单 -->
|
<!-- 第二步:确认表单 -->
|
||||||
<div v-else class="step2-container">
|
<div v-else class="step2-container">
|
||||||
<el-form
|
<el-form ref="formRef" :model="formData" :rules="formRules" label-position="top">
|
||||||
ref="formRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="formRules"
|
|
||||||
label-position="top"
|
|
||||||
>
|
|
||||||
|
|
||||||
<!-- 金额信息(只读) -->
|
<!-- 金额信息(只读) -->
|
||||||
<div class="amount-info">
|
<div class="amount-info">
|
||||||
|
|
@ -138,19 +120,23 @@
|
||||||
<!-- 用户取款额外字段 (role_id >= 5) -->
|
<!-- 用户取款额外字段 (role_id >= 5) -->
|
||||||
<template v-if="!isAgent">
|
<template v-if="!isAgent">
|
||||||
<el-form-item :label="t('withdraw.dialog.beneficiaryName')" prop="beneficiary_name">
|
<el-form-item :label="t('withdraw.dialog.beneficiaryName')" prop="beneficiary_name">
|
||||||
<el-input v-model="formData.beneficiary_name" :placeholder="t('withdraw.dialog.beneficiaryNamePlaceholder')" />
|
<el-input v-model="formData.beneficiary_name"
|
||||||
|
:placeholder="t('withdraw.dialog.beneficiaryNamePlaceholder')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('withdraw.dialog.bankName')" prop="beneficiary_bank_name">
|
<el-form-item :label="t('withdraw.dialog.bankName')" prop="beneficiary_bank_name">
|
||||||
<el-input v-model="formData.beneficiary_bank_name" :placeholder="t('withdraw.dialog.bankNamePlaceholder')" />
|
<el-input v-model="formData.beneficiary_bank_name"
|
||||||
|
:placeholder="t('withdraw.dialog.bankNamePlaceholder')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('withdraw.dialog.swiftCode')" prop="swift_bic_code">
|
<el-form-item :label="t('withdraw.dialog.swiftCode')" prop="swift_bic_code">
|
||||||
<el-input v-model="formData.swift_bic_code" :placeholder="t('withdraw.dialog.swiftCodePlaceholder')" />
|
<el-input v-model="formData.swift_bic_code" :placeholder="t('withdraw.dialog.swiftCodePlaceholder')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('withdraw.dialog.bankAddress')" prop="beneficiary_bank_address">
|
<el-form-item :label="t('withdraw.dialog.bankAddress')" prop="beneficiary_bank_address">
|
||||||
<el-input v-model="formData.beneficiary_bank_address" :placeholder="t('withdraw.dialog.bankAddressPlaceholder')" />
|
<el-input v-model="formData.beneficiary_bank_address"
|
||||||
|
:placeholder="t('withdraw.dialog.bankAddressPlaceholder')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('withdraw.dialog.bankAccount')" prop="beneficiary_bank_account">
|
<el-form-item :label="t('withdraw.dialog.bankAccount')" prop="beneficiary_bank_account">
|
||||||
<el-input v-model="formData.beneficiary_bank_account" :placeholder="t('withdraw.dialog.bankAccountPlaceholder')" />
|
<el-input v-model="formData.beneficiary_bank_account"
|
||||||
|
:placeholder="t('withdraw.dialog.bankAccountPlaceholder')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
@ -158,7 +144,8 @@
|
||||||
<!-- 底部按钮 -->
|
<!-- 底部按钮 -->
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="handleBack">{{ t('common.cancel') }}</el-button>
|
<el-button @click="handleBack">{{ t('common.cancel') }}</el-button>
|
||||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">{{ t('withdraw.dialog.confirmWithdraw') }}</el-button>
|
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">{{ t('withdraw.dialog.confirmWithdraw')
|
||||||
|
}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
@ -261,18 +248,17 @@ const isAgent = computed(() => roleId >= 5)
|
||||||
// 当前货币类型(从渠道信息获取)
|
// 当前货币类型(从渠道信息获取)
|
||||||
const currentCurrency = computed(() => props.channelInfo?.currency?.symbol || '-')
|
const currentCurrency = computed(() => props.channelInfo?.currency?.symbol || '-')
|
||||||
|
|
||||||
// 计算可用余额 = amount - 所有钱包余额 - freeze
|
// 计算可用余额 = amount - freeze - (手续费 + 点差 + 服务费 + 风险金 + 头寸)
|
||||||
// availableBalance = amount - freeze - (手续费 + 点差 + 服务费 + 风险金 + 头寸)
|
|
||||||
const availableBalance = computed(() => {
|
const availableBalance = computed(() => {
|
||||||
const amount = parseFloat(walletInfo.value.amount || '0')
|
const amount = parseFloat(walletInfo.value.amount || '0')
|
||||||
const freeze = parseFloat(walletInfo.value.freeze || '0')
|
const freeze = parseFloat(walletInfo.value.freeze || '0')
|
||||||
// 钱包余额总和
|
// 钱包余额总和
|
||||||
const walletSum =
|
const walletSum =
|
||||||
parseFloat(walletInfo.value.commission_fee_handling || '0') +
|
Math.max(0, parseFloat(walletInfo.value.commission_fee_handling || '0')) +
|
||||||
parseFloat(walletInfo.value.commission_point_diff || '0') +
|
Math.max(0, parseFloat(walletInfo.value.commission_point_diff || '0')) +
|
||||||
parseFloat(walletInfo.value.service || '0') +
|
Math.max(0, parseFloat(walletInfo.value.service || '0')) +
|
||||||
parseFloat(walletInfo.value.risk || '0') +
|
Math.max(0, parseFloat(walletInfo.value.risk || '0')) +
|
||||||
parseFloat(walletInfo.value.closing_profit || '0')
|
Math.max(0, parseFloat(walletInfo.value.closing_profit || '0'))
|
||||||
return Math.max(0, amount - freeze - walletSum)
|
return Math.max(0, amount - freeze - walletSum)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -290,11 +276,10 @@ const totalWalletBalance = computed(() => {
|
||||||
parseFloat(walletInfo.value.risk || '0') +
|
parseFloat(walletInfo.value.risk || '0') +
|
||||||
parseFloat(walletInfo.value.closing_profit || '0')
|
parseFloat(walletInfo.value.closing_profit || '0')
|
||||||
|
|
||||||
// availableBalance = amount - freeze - walletSum
|
|
||||||
const availableBal = Math.max(0, amount - freeze - walletSum)
|
|
||||||
|
|
||||||
if (roleId >= 5) {
|
if (roleId >= 5) {
|
||||||
// roleId >= 5 时,总余额包含可用余额
|
// roleId >= 5 时,总余额包含可用余额
|
||||||
|
// availableBalance = amount - freeze - walletSum
|
||||||
|
const availableBal = Math.max(0, amount - freeze - walletSum)
|
||||||
return walletSum + availableBal
|
return walletSum + availableBal
|
||||||
}
|
}
|
||||||
return walletSum
|
return walletSum
|
||||||
|
|
@ -318,13 +303,13 @@ const feeOrder = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
// 费用项对应的字段
|
// 费用项对应的字段
|
||||||
const feeFieldMap: Record<string, keyof WalletInfo> = {
|
const feeFieldMap: Record<string, keyof WalletInfo | 'available'> = {
|
||||||
'手续费': 'commission_fee_handling',
|
'手续费': 'commission_fee_handling',
|
||||||
'点差': 'commission_point_diff',
|
'点差': 'commission_point_diff',
|
||||||
'服务费': 'service',
|
'服务费': 'service',
|
||||||
'风险金': 'risk',
|
'风险金': 'risk',
|
||||||
'头寸': 'closing_profit',
|
'头寸': 'closing_profit',
|
||||||
'可用余额': 'amount',
|
'可用余额': 'available', // 特殊处理,用 computed 计算
|
||||||
}
|
}
|
||||||
|
|
||||||
// 费用项标签映射
|
// 费用项标签映射
|
||||||
|
|
@ -381,6 +366,7 @@ const formData = ref({
|
||||||
withdraw_service_fee: '',
|
withdraw_service_fee: '',
|
||||||
withdraw_head_fee: '',
|
withdraw_head_fee: '',
|
||||||
withdraw_risk_fee: '',
|
withdraw_risk_fee: '',
|
||||||
|
withdraw_blance: '', // 可用余额使用量
|
||||||
// 用户取款额外字段
|
// 用户取款额外字段
|
||||||
beneficiary_name: '',
|
beneficiary_name: '',
|
||||||
beneficiary_bank_name: '',
|
beneficiary_bank_name: '',
|
||||||
|
|
@ -474,7 +460,14 @@ const calculateWithdraw = () => {
|
||||||
const field = feeFieldMap[feeType]
|
const field = feeFieldMap[feeType]
|
||||||
if (!field) continue
|
if (!field) continue
|
||||||
|
|
||||||
const original = parseFloat(walletInfo.value[field] || '0')
|
// 获取原始值(特殊处理 available)
|
||||||
|
let original: number
|
||||||
|
if (field === 'available') {
|
||||||
|
original = availableBalance.value
|
||||||
|
} else {
|
||||||
|
original = parseFloat(walletInfo.value[field] || '0')
|
||||||
|
}
|
||||||
|
|
||||||
if (original <= 0) continue
|
if (original <= 0) continue
|
||||||
|
|
||||||
const deducted = Math.min(remaining, original).toFixed(2)
|
const deducted = Math.min(remaining, original).toFixed(2)
|
||||||
|
|
@ -536,6 +529,7 @@ const handleNextStep = () => {
|
||||||
formData.value.withdraw_service_fee = calculatedData.value.find(item => item.type === '服务费')?.deducted || '0'
|
formData.value.withdraw_service_fee = calculatedData.value.find(item => item.type === '服务费')?.deducted || '0'
|
||||||
formData.value.withdraw_risk_fee = calculatedData.value.find(item => item.type === '风险金')?.deducted || '0'
|
formData.value.withdraw_risk_fee = calculatedData.value.find(item => item.type === '风险金')?.deducted || '0'
|
||||||
formData.value.withdraw_head_fee = calculatedData.value.find(item => item.type === '头寸')?.deducted || '0'
|
formData.value.withdraw_head_fee = calculatedData.value.find(item => item.type === '头寸')?.deducted || '0'
|
||||||
|
formData.value.withdraw_blance = calculatedData.value.find(item => item.type === '可用余额')?.deducted || '0'
|
||||||
|
|
||||||
currentStep.value = 2
|
currentStep.value = 2
|
||||||
}
|
}
|
||||||
|
|
@ -561,7 +555,7 @@ const handleSubmit = async () => {
|
||||||
|
|
||||||
if (isAgent.value) {
|
if (isAgent.value) {
|
||||||
// 用户取款
|
// 用户取款
|
||||||
params.withdraw_blance = walletInfo.value.amount
|
params.withdraw_blance = formData.value.withdraw_blance
|
||||||
params.beneficiary_name = formData.value.beneficiary_name
|
params.beneficiary_name = formData.value.beneficiary_name
|
||||||
params.beneficiary_bank_name = formData.value.beneficiary_bank_name
|
params.beneficiary_bank_name = formData.value.beneficiary_bank_name
|
||||||
params.swift_bic_code = formData.value.swift_bic_code
|
params.swift_bic_code = formData.value.swift_bic_code
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,8 @@
|
||||||
<!-- 搜索区域:复用项目内搜索组件 -->
|
<!-- 搜索区域:复用项目内搜索组件 -->
|
||||||
<WithdrawSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch" @reset="handleReset">
|
<WithdrawSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch" @reset="handleReset">
|
||||||
<template #button>
|
<template #button>
|
||||||
<!-- 当前阶段仅完成页面,按钮先保留交互占位 -->
|
<el-button type="success" :loading="approveLoading" @click="handleApprove">通过</el-button>
|
||||||
<el-button type="success" @click="handleApprove">通过</el-button>
|
<el-button type="danger" plain :loading="rejectLoading" @click="handleReject">驳回</el-button>
|
||||||
<el-button type="danger" plain @click="handleReject">驳回</el-button>
|
|
||||||
<el-button type="primary" plain @click="handleExport">导出</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</WithdrawSearch>
|
</WithdrawSearch>
|
||||||
|
|
||||||
|
|
@ -41,231 +39,161 @@
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'WithdrawCheck'
|
name: 'WithdrawCheck'
|
||||||
})
|
})
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { computed, onMounted, ref } from 'vue'
|
import { computed, onMounted, ref } from 'vue'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
import WithdrawSearch from '@/components/common/Search.vue'
|
import WithdrawSearch from '@/components/common/Search.vue'
|
||||||
import WithdrawPagination from '@/components/common/Pagination.vue'
|
import WithdrawPagination from '@/components/common/Pagination.vue'
|
||||||
import { withdrawCheckSearch, withdrawCheckTableColumns } from './options'
|
import { withdrawCheckSearch, withdrawCheckTableColumns } from './options'
|
||||||
|
import { getWithdrawReviewList, withdrawReviewOrder } from '@/api/modules/capital/withdraw'
|
||||||
|
|
||||||
// 表格单行数据结构
|
// 表格单行数据结构
|
||||||
interface TableRow {
|
interface TableRow {
|
||||||
id: number
|
id: number
|
||||||
account: string
|
trade_id: string
|
||||||
agentName: string
|
return_trade_id: string | null
|
||||||
walletAddress: string
|
user_id: number
|
||||||
walletType: string
|
withdraw_currency: {
|
||||||
holderName: string
|
id: number
|
||||||
bankName: string
|
symbol: string
|
||||||
bankCode: string
|
}
|
||||||
bankAddress: string
|
withdraw_amount: string
|
||||||
withdrawAmount: string
|
real_currency: {
|
||||||
deductAmount: string
|
id: number
|
||||||
withdrawCurrency: string
|
symbol: string
|
||||||
arrivalAmount: string
|
}
|
||||||
arrivalCurrency: string
|
real_amount: string
|
||||||
feeAmount: string
|
rate: string
|
||||||
positionAmount: string
|
status: number
|
||||||
userType: number
|
channel_id: number
|
||||||
|
withdraw_fee_handle: string
|
||||||
|
withdraw_point_diff: string
|
||||||
|
withdraw_service_fee: string
|
||||||
|
withdraw_head_fee: string
|
||||||
|
withdraw_risk_fee: string
|
||||||
|
withdraw_address: string
|
||||||
|
beneficiary_name: string | null
|
||||||
|
beneficiary_bank_name: string | null
|
||||||
|
swift_bic_code: string | null
|
||||||
|
beneficiary_bank_address: string | null
|
||||||
|
beneficiary_bank_account: string | null
|
||||||
|
created_at: string
|
||||||
|
updated_at: string
|
||||||
|
deleted_at: string | null
|
||||||
|
user: {
|
||||||
|
id: number
|
||||||
|
username: string
|
||||||
|
}
|
||||||
|
channel: {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// mock 数据:当前仅用于页面展示,后续接接口时可直接替换为接口返回结果
|
// 转换后的表格数据
|
||||||
const mockTableData: TableRow[] = [
|
interface TransformedTableRow {
|
||||||
{
|
id: number
|
||||||
id: 1,
|
trade_id: string
|
||||||
account: 'U100101',
|
user_name: string
|
||||||
agentName: '一级代理A',
|
withdraw_currency_symbol: string
|
||||||
walletAddress: 'TRX8x2f...7Kp9',
|
withdraw_amount: string
|
||||||
walletType: 'TRC20',
|
real_currency_symbol: string
|
||||||
holderName: '张三',
|
real_amount: string
|
||||||
bankName: '中国银行',
|
rate: string
|
||||||
bankCode: 'BKCHCNBJ',
|
channel_name: string
|
||||||
bankAddress: '上海市浦东新区世纪大道100号',
|
withdraw_service_fee: string
|
||||||
withdrawAmount: '1000.00',
|
withdraw_head_fee: string
|
||||||
deductAmount: '20.00',
|
withdraw_fee_handle: string
|
||||||
withdrawCurrency: 'USDT',
|
withdraw_point_diff: string
|
||||||
arrivalAmount: '980.00',
|
withdraw_risk_fee: string
|
||||||
arrivalCurrency: 'USDT',
|
withdraw_address: string
|
||||||
feeAmount: '20.00',
|
created_at: string
|
||||||
positionAmount: '1.20',
|
}
|
||||||
userType: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
account: 'U100102',
|
|
||||||
agentName: '一级代理B',
|
|
||||||
walletAddress: '0x5fa1...ac20',
|
|
||||||
walletType: 'ERC20',
|
|
||||||
holderName: '李四',
|
|
||||||
bankName: '工商银行',
|
|
||||||
bankCode: 'ICBKCNBJ',
|
|
||||||
bankAddress: '北京市朝阳区建国路88号',
|
|
||||||
withdrawAmount: '5000.00',
|
|
||||||
deductAmount: '50.00',
|
|
||||||
withdrawCurrency: 'USD',
|
|
||||||
arrivalAmount: '4950.00',
|
|
||||||
arrivalCurrency: 'USD',
|
|
||||||
feeAmount: '50.00',
|
|
||||||
positionAmount: '2.50',
|
|
||||||
userType: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
account: 'A200101',
|
|
||||||
agentName: '总代运营中心',
|
|
||||||
walletAddress: 'bc1q7m...91fa',
|
|
||||||
walletType: 'BTC',
|
|
||||||
holderName: '王五',
|
|
||||||
bankName: '建设银行',
|
|
||||||
bankCode: 'PCBCCNBJ',
|
|
||||||
bankAddress: '深圳市南山区科技园中一路1号',
|
|
||||||
withdrawAmount: '20000.00',
|
|
||||||
deductAmount: '120.00',
|
|
||||||
withdrawCurrency: 'CNY',
|
|
||||||
arrivalAmount: '19880.00',
|
|
||||||
arrivalCurrency: 'CNY',
|
|
||||||
feeAmount: '120.00',
|
|
||||||
positionAmount: '3.00',
|
|
||||||
userType: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
account: 'U100103',
|
|
||||||
agentName: '一级代理C',
|
|
||||||
walletAddress: 'TRX9m4k...6Ts1',
|
|
||||||
walletType: 'TRC20',
|
|
||||||
holderName: '赵六',
|
|
||||||
bankName: '农业银行',
|
|
||||||
bankCode: 'ABOCCNBJ',
|
|
||||||
bankAddress: '广州市天河区珠江新城华夏路18号',
|
|
||||||
withdrawAmount: '3000.00',
|
|
||||||
deductAmount: '15.00',
|
|
||||||
withdrawCurrency: 'USDT',
|
|
||||||
arrivalAmount: '2985.00',
|
|
||||||
arrivalCurrency: 'USDT',
|
|
||||||
feeAmount: '15.00',
|
|
||||||
positionAmount: '1.10',
|
|
||||||
userType: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
account: 'A200102',
|
|
||||||
agentName: '华东代理中心',
|
|
||||||
walletAddress: '0x9bd7...b3f2',
|
|
||||||
walletType: 'ERC20',
|
|
||||||
holderName: '孙七',
|
|
||||||
bankName: '招商银行',
|
|
||||||
bankCode: 'CMBCCNBS',
|
|
||||||
bankAddress: '杭州市西湖区文三路90号',
|
|
||||||
withdrawAmount: '8000.00',
|
|
||||||
deductAmount: '80.00',
|
|
||||||
withdrawCurrency: 'USD',
|
|
||||||
arrivalAmount: '7920.00',
|
|
||||||
arrivalCurrency: 'USD',
|
|
||||||
feeAmount: '80.00',
|
|
||||||
positionAmount: '2.20',
|
|
||||||
userType: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
account: 'U100104',
|
|
||||||
agentName: '一级代理D',
|
|
||||||
walletAddress: 'TRX6a1d...3Lm8',
|
|
||||||
walletType: 'TRC20',
|
|
||||||
holderName: '周八',
|
|
||||||
bankName: '交通银行',
|
|
||||||
bankCode: 'COMMCNSH',
|
|
||||||
bankAddress: '成都市高新区天府大道北段966号',
|
|
||||||
withdrawAmount: '1200.00',
|
|
||||||
deductAmount: '12.00',
|
|
||||||
withdrawCurrency: 'USDT',
|
|
||||||
arrivalAmount: '1188.00',
|
|
||||||
arrivalCurrency: 'USDT',
|
|
||||||
feeAmount: '12.00',
|
|
||||||
positionAmount: '0.80',
|
|
||||||
userType: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 7,
|
|
||||||
account: 'U100105',
|
|
||||||
agentName: '一级代理E',
|
|
||||||
walletAddress: 'bc1qx8...0de4',
|
|
||||||
walletType: 'BTC',
|
|
||||||
holderName: '吴九',
|
|
||||||
bankName: '浦发银行',
|
|
||||||
bankCode: 'SPDBCNBS',
|
|
||||||
bankAddress: '苏州市工业园区星湖街328号',
|
|
||||||
withdrawAmount: '15000.00',
|
|
||||||
deductAmount: '105.00',
|
|
||||||
withdrawCurrency: 'CNY',
|
|
||||||
arrivalAmount: '14895.00',
|
|
||||||
arrivalCurrency: 'CNY',
|
|
||||||
feeAmount: '105.00',
|
|
||||||
positionAmount: '2.80',
|
|
||||||
userType: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 8,
|
|
||||||
account: 'A200103',
|
|
||||||
agentName: '华南代理中心',
|
|
||||||
walletAddress: '0x8e2f...d1a0',
|
|
||||||
walletType: 'ERC20',
|
|
||||||
holderName: '郑十',
|
|
||||||
bankName: '民生银行',
|
|
||||||
bankCode: 'MSBCCNBJ',
|
|
||||||
bankAddress: '厦门市思明区湖滨南路258号',
|
|
||||||
withdrawAmount: '6000.00',
|
|
||||||
deductAmount: '36.00',
|
|
||||||
withdrawCurrency: 'USD',
|
|
||||||
arrivalAmount: '5964.00',
|
|
||||||
arrivalCurrency: 'USD',
|
|
||||||
feeAmount: '36.00',
|
|
||||||
positionAmount: '1.90',
|
|
||||||
userType: 2,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
// 搜索配置和表格配置
|
// 搜索配置和表格配置
|
||||||
const searchOptions = ref(withdrawCheckSearch)
|
const searchOptions = ref(withdrawCheckSearch)
|
||||||
const searchForm = ref({
|
const searchForm = ref({
|
||||||
account: '',
|
user_name: '',
|
||||||
userType: 1,
|
timeRange: [] as string[]
|
||||||
})
|
})
|
||||||
|
|
||||||
// 表格、勾选状态和 loading 状态
|
// 表格、勾选状态和 loading 状态
|
||||||
const tableColumns = computed(() => withdrawCheckTableColumns)
|
const tableColumns = computed(() => withdrawCheckTableColumns)
|
||||||
const tableData = ref<TableRow[]>([])
|
const tableData = ref<TransformedTableRow[]>([])
|
||||||
const selectedRows = ref<TableRow[]>([])
|
const selectedRows = ref<TableRow[]>([])
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 审核操作 loading 状态
|
||||||
|
const approveLoading = ref(false)
|
||||||
|
const rejectLoading = ref(false)
|
||||||
|
|
||||||
// 分页状态
|
// 分页状态
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const currentPage = ref(1)
|
const currentPage = ref(1)
|
||||||
const pageSize = ref(10)
|
const pageSize = ref(30)
|
||||||
|
|
||||||
// 根据搜索条件过滤 mock 数据,并做前端分页切片
|
// 获取默认时间范围(一周)
|
||||||
const applyFilters = () => {
|
const getDefaultTimeRange = () => {
|
||||||
const keyword = searchForm.value.account.trim().toLowerCase()
|
const end = dayjs()
|
||||||
const filtered = mockTableData.filter((item) => {
|
const start = end.subtract(7, 'day')
|
||||||
const matchAccount = !keyword || item.account.toLowerCase().includes(keyword)
|
return [start.format('YYYY-MM-DD HH:mm:ss'), end.format('YYYY-MM-DD HH:mm:ss')]
|
||||||
const matchUserType = !searchForm.value.userType || item.userType === searchForm.value.userType
|
}
|
||||||
return matchAccount && matchUserType
|
|
||||||
})
|
|
||||||
|
|
||||||
total.value = filtered.length
|
// 初始化时间范围
|
||||||
const start = (currentPage.value - 1) * pageSize.value
|
searchForm.value.timeRange = getDefaultTimeRange()
|
||||||
const end = start + pageSize.value
|
|
||||||
tableData.value = filtered.slice(start, end)
|
// 转换接口数据为表格数据
|
||||||
|
const transformTableData = (data: TableRow[]): TransformedTableRow[] => {
|
||||||
|
return data.map(item => ({
|
||||||
|
id: item.id,
|
||||||
|
trade_id: item.trade_id,
|
||||||
|
user_name: item.user?.username || '-',
|
||||||
|
withdraw_currency_symbol: item.withdraw_currency?.symbol || '-',
|
||||||
|
withdraw_amount: item.withdraw_amount,
|
||||||
|
real_currency_symbol: item.real_currency?.symbol || '-',
|
||||||
|
real_amount: item.real_amount,
|
||||||
|
rate: item.rate,
|
||||||
|
channel_name: item.channel?.name || '-',
|
||||||
|
withdraw_service_fee: item.withdraw_service_fee,
|
||||||
|
withdraw_head_fee: item.withdraw_head_fee,
|
||||||
|
withdraw_fee_handle: item.withdraw_fee_handle,
|
||||||
|
withdraw_point_diff: item.withdraw_point_diff,
|
||||||
|
withdraw_risk_fee: item.withdraw_risk_fee,
|
||||||
|
withdraw_address: item.withdraw_address,
|
||||||
|
created_at: item.created_at
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列表响应数据结构
|
||||||
|
interface ListResponse {
|
||||||
|
data: TableRow[]
|
||||||
|
total: number
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取列表数据
|
// 获取列表数据
|
||||||
// 当前阶段用 mock 数据模拟加载态,后续接接口时可在这里替换为真实请求
|
const getList = async () => {
|
||||||
const getList = () => {
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
selectedRows.value = []
|
selectedRows.value = []
|
||||||
window.setTimeout(() => {
|
|
||||||
applyFilters()
|
const [start_time, end_time] = searchForm.value.timeRange || []
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await getWithdrawReviewList({
|
||||||
|
page: currentPage.value,
|
||||||
|
page_size: pageSize.value,
|
||||||
|
start_time: start_time || undefined,
|
||||||
|
end_time: end_time || undefined,
|
||||||
|
user_name: searchForm.value.user_name || undefined
|
||||||
|
}) as unknown as ListResponse
|
||||||
|
|
||||||
|
tableData.value = transformTableData(res.data || [])
|
||||||
|
total.value = res.total || 0
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取提现审核列表失败:', error)
|
||||||
|
ElMessage.error('获取列表失败')
|
||||||
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}, 120)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 页面初始化时加载一次列表
|
// 页面初始化时加载一次列表
|
||||||
|
|
@ -282,46 +210,107 @@ const handleSearch = () => {
|
||||||
// 重置:恢复默认搜索条件
|
// 重置:恢复默认搜索条件
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
searchForm.value = {
|
searchForm.value = {
|
||||||
account: '',
|
user_name: '',
|
||||||
userType: 1,
|
timeRange: getDefaultTimeRange()
|
||||||
}
|
}
|
||||||
currentPage.value = 1
|
currentPage.value = 1
|
||||||
getList()
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表格勾选变化
|
// 表格勾选变化
|
||||||
const handleSelectionChange = (rows: TableRow[]) => {
|
const handleSelectionChange = (rows: TransformedTableRow[]) => {
|
||||||
selectedRows.value = rows
|
// 根据选中行的 id 找到原始数据
|
||||||
|
selectedRows.value = rows.map(row => {
|
||||||
|
return tableData.value.find(item => item.id === row.id) as unknown as TableRow
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 审核通过:当前保留前端提示,等待后续接接口
|
// 审核通过
|
||||||
const handleApprove = () => {
|
const handleApprove = async () => {
|
||||||
if (!selectedRows.value.length) {
|
if (!selectedRows.value.length) {
|
||||||
ElMessage.warning('请先选择要通过的记录')
|
ElMessage.warning('请先选择要通过的记录')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ElMessage.success('页面已完成,接口后续接入')
|
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm(
|
||||||
|
`确定要通过 ${selectedRows.value.length} 条提现记录吗?`,
|
||||||
|
'审核确认',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
approveLoading.value = true
|
||||||
|
|
||||||
|
for (const row of selectedRows.value) {
|
||||||
|
await withdrawReviewOrder({
|
||||||
|
id: row.id,
|
||||||
|
status: 2
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ElMessage.success('审核通过成功')
|
||||||
|
getList()
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error !== 'cancel') {
|
||||||
|
ElMessage.error(error.message || '审核通过失败')
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
approveLoading.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 审核驳回:当前保留前端提示,等待后续接接口
|
// 审核驳回
|
||||||
const handleReject = () => {
|
const handleReject = async () => {
|
||||||
if (!selectedRows.value.length) {
|
if (!selectedRows.value.length) {
|
||||||
ElMessage.warning('请先选择要驳回的记录')
|
ElMessage.warning('请先选择要驳回的记录')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ElMessage.success('页面已完成,接口后续接入')
|
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm(
|
||||||
|
`确定要驳回 ${selectedRows.value.length} 条提现记录吗?`,
|
||||||
|
'审核确认',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
rejectLoading.value = true
|
||||||
|
|
||||||
|
for (const row of selectedRows.value) {
|
||||||
|
await withdrawReviewOrder({
|
||||||
|
id: row.id,
|
||||||
|
status: 4
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ElMessage.success('审核驳回成功')
|
||||||
|
getList()
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error !== 'cancel') {
|
||||||
|
ElMessage.error(error.message || '审核驳回失败')
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
rejectLoading.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出:当前保留前端提示,等待后续接接口
|
// 导出
|
||||||
const handleExport = () => {
|
const handleExport = () => {
|
||||||
ElMessage.success('页面已完成,接口后续接入')
|
ElMessage.info('导出功能开发中')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分页变化:更新页码和每页条数后重新切片数据
|
// 分页变化
|
||||||
const handlePaginationChange = (page: { currentPage: number; pageSize: number }) => {
|
const handlePaginationChange = (page: { currentPage: number; pageSize: number }) => {
|
||||||
currentPage.value = page.currentPage
|
currentPage.value = page.currentPage
|
||||||
pageSize.value = page.pageSize
|
pageSize.value = page.pageSize
|
||||||
applyFilters()
|
getList()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,42 @@
|
||||||
// 搜索区域配置
|
// 搜索区域配置
|
||||||
export const withdrawCheckSearch = [
|
export const withdrawCheckSearch = [
|
||||||
{
|
{
|
||||||
// 取款账户关键词
|
// 账户持有人姓名
|
||||||
prop: 'account',
|
prop: 'user_name',
|
||||||
label: '取款账户',
|
label: '账户持有人',
|
||||||
type: 'input' as const,
|
type: 'input' as const,
|
||||||
placeholder: '请输入取款账户',
|
placeholder: '请输入账户持有人',
|
||||||
width: '220px'
|
width: '280px'
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
// 客户类型:1=客户,2=代理
|
// // 时间范围选择
|
||||||
prop: 'userType',
|
// prop: 'timeRange',
|
||||||
label: '客户类型',
|
// label: '申请时间',
|
||||||
type: 'select' as const,
|
// type: 'date' as const,
|
||||||
placeholder: '请选择客户类型',
|
// dateType: 'datetimerange' as const,
|
||||||
width: '180px',
|
// rangeSeparator: '至',
|
||||||
options: [
|
// startPlaceholder: '开始时间',
|
||||||
{ label: '客户', value: 1 },
|
// endPlaceholder: '结束时间',
|
||||||
{ label: '代理', value: 2 }
|
// valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
]
|
// width: '380px'
|
||||||
}
|
// }
|
||||||
]
|
]
|
||||||
|
|
||||||
// 表格列配置
|
// 表格列配置
|
||||||
export const withdrawCheckTableColumns = [
|
export const withdrawCheckTableColumns = [
|
||||||
{ prop: 'account', label: '账户', align: 'center' as const, width: 140 },
|
{ prop: 'trade_id', label: '订单号', align: 'center' as const, width: 200 },
|
||||||
{ prop: 'agentName', label: '所属代理', align: 'center' as const, width: 140 },
|
{ prop: 'user_name', label: '账户持有人', align: 'center' as const, width: 120 },
|
||||||
{ prop: 'walletAddress', label: '钱包地址', align: 'center' as const, width: 220 },
|
{ prop: 'withdraw_currency_symbol', label: '取款币种', align: 'center' as const, width: 100 },
|
||||||
{ prop: 'walletType', label: '钱包类型', align: 'center' as const, width: 120 },
|
{ prop: 'withdraw_amount', label: '取款金额', align: 'center' as const, width: 120 },
|
||||||
{ prop: 'holderName', label: '账户持有人姓名', align: 'center' as const, width: 160 },
|
{ prop: 'real_currency_symbol', label: '到账币种', align: 'center' as const, width: 100 },
|
||||||
{ prop: 'bankName', label: '银行名称', align: 'center' as const, width: 160 },
|
{ prop: 'real_amount', label: '到账金额', align: 'center' as const, width: 120 },
|
||||||
{ prop: 'bankCode', label: '银行识别代码', align: 'center' as const, width: 160 },
|
{ prop: 'rate', label: '汇率', align: 'center' as const, width: 100 },
|
||||||
{ prop: 'bankAddress', label: '银行地址', align: 'center' as const, width: 200 },
|
{ prop: 'channel_name', label: '渠道', align: 'center' as const, width: 140 },
|
||||||
{ prop: 'withdrawAmount', label: '取款金额', align: 'center' as const, width: 120 },
|
{ prop: 'withdraw_service_fee', label: '服务费', align: 'center' as const, width: 100 },
|
||||||
{ prop: 'deductAmount', label: '取款扣除金额', align: 'center' as const, width: 140 },
|
{ prop: 'withdraw_head_fee', label: '总部手续费', align: 'center' as const, width: 120 },
|
||||||
{ prop: 'withdrawCurrency', label: '取款币种', align: 'center' as const, width: 120 },
|
{ prop: 'withdraw_fee_handle', label: '代理手续费', align: 'center' as const, width: 120 },
|
||||||
{ prop: 'arrivalAmount', label: '到账金额', align: 'center' as const, width: 120 },
|
{ prop: 'withdraw_point_diff', label: '点差', align: 'center' as const, width: 100 },
|
||||||
{ prop: 'arrivalCurrency', label: '到账币种', align: 'center' as const, width: 120 },
|
{ prop: 'withdraw_risk_fee', label: '风控费', align: 'center' as const, width: 100 },
|
||||||
{ prop: 'feeAmount', label: '手续费', align: 'center' as const, width: 100 },
|
{ prop: 'withdraw_address', label: '提现地址', align: 'center' as const, minWidth: 180 },
|
||||||
{ prop: 'positionAmount', label: '头寸', align: 'center' as const, width: 100 }
|
{ prop: 'created_at', label: '申请时间', align: 'center' as const, width: 180 }
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue