This commit is contained in:
2026-06-12 16:30:06 +08:00
parent 7b3f40069f
commit 5e4329dc5b
8 changed files with 209 additions and 85 deletions

View File

@ -63,8 +63,13 @@
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@current-change="handleCurrentChange" @current-change="handleCurrentChange"
> >
<!-- 勾选列 --> <!-- 勾选列/单选列 -->
<el-table-column v-if="showSelection" type="selection" width="55" align="center" /> <el-table-column v-if="showSelection && !singleSelect" type="selection" width="55" align="center" />
<el-table-column v-if="showSelection && singleSelect" width="55" align="center" label="">
<template #default="{ row }">
<el-radio v-model="selectedRadioRow" :label="getRowKeyValue(row)" @change="handleRadioChange(row)">&nbsp;</el-radio>
</template>
</el-table-column>
<!-- 动态表头列 --> <!-- 动态表头列 -->
<template v-for="(column, index) in finalColumns" :key="index"> <template v-for="(column, index) in finalColumns" :key="index">
@ -139,6 +144,7 @@
:label="column.label" :label="column.label"
:width="column.width" :width="column.width"
:align="column.align || 'left'" :align="column.align || 'left'"
:fixed="column.fixed"
> >
<template #default="{ row }"> <template #default="{ row }">
<slot :name="column.slotName" :row="row" /> <slot :name="column.slotName" :row="row" />
@ -180,7 +186,7 @@ interface TableColumn {
isNumber?: boolean isNumber?: boolean
options?: { label: string; value: string | number }[] options?: { label: string; value: string | number }[]
visible?: boolean visible?: boolean
fixed?: boolean fixed?: boolean | 'left' | 'right'
sortOrder?: number sortOrder?: number
// //
filters?: { text: string; value: any }[] filters?: { text: string; value: any }[]
@ -201,6 +207,7 @@ interface Props {
highlightCurrentRow?: boolean highlightCurrentRow?: boolean
loading?: boolean loading?: boolean
showSelection?: boolean showSelection?: boolean
singleSelect?: boolean //
showColumnSetting?: boolean showColumnSetting?: boolean
columnSettingStorageKey?: string columnSettingStorageKey?: string
enableClientFilter?: boolean // enableClientFilter?: boolean //
@ -211,11 +218,25 @@ const props = withDefaults(defineProps<Props>(), {
highlightCurrentRow: true, highlightCurrentRow: true,
loading: false, loading: false,
showSelection: false, showSelection: false,
singleSelect: false,
showColumnSetting: true, // showColumnSetting: true, //
columnSettingStorageKey: '', columnSettingStorageKey: '',
enableClientFilter: true, // enableClientFilter: true, //
}) })
//
const selectedRadioRow = ref<any>(null)
// safe
const getRowKeyValue = (row: any) => {
return props.rowKey ? row[props.rowKey] : row.id
}
const handleRadioChange = (row: any) => {
selectedRadioRow.value = getRowKeyValue(row)
emit('selection-change', [row])
}
// //
const filteredTableData = computed(() => { const filteredTableData = computed(() => {
if (!props.enableClientFilter || Object.keys(filterStates).length === 0) { if (!props.enableClientFilter || Object.keys(filterStates).length === 0) {
@ -293,10 +314,18 @@ const initColumns = () => {
// //
localColumns.value = cachedConfig.map((cached: any) => { localColumns.value = cachedConfig.map((cached: any) => {
// prop
const originalCol = props.columns?.find((c) => c.prop === cached.prop) const originalCol = props.columns?.find((c) => c.prop === cached.prop)
if (originalCol) { if (originalCol) {
return { ...originalCol, ...cached } return { ...originalCol, ...cached }
} }
// prop slotName
if (cached.slotName) {
const slotCol = props.columns?.find((c) => c.slotName === cached.slotName)
if (slotCol) {
return { ...slotCol, ...cached }
}
}
return null return null
}).filter(Boolean) }).filter(Boolean)
} catch { } catch {
@ -375,6 +404,26 @@ onMounted(() => {
}, 100) }, 100)
}) })
// tableData
watch(
() => props.tableData,
() => {
if (props.singleSelect) {
selectedRadioRow.value = null
}
}
)
// tableData
watch(
() => props.tableData,
() => {
if (props.singleSelect) {
selectedRadioRow.value = null
}
}
)
// //
const handleSelectionChange = (rows: any[]) => { const handleSelectionChange = (rows: any[]) => {
emit('selection-change', rows) emit('selection-change', rows)
@ -409,6 +458,15 @@ const handleRowContextmenu = (row: any, column: any, event: MouseEvent) => {
emit('row-contextmenu', row, column, event) emit('row-contextmenu', row, column, event)
} }
// tableData
watch(
() => props.tableData,
() => {
if (props.singleSelect) {
selectedRadioRow.value = null
}
}
)
// tableData // tableData
watch( watch(
() => props.tableData, () => props.tableData,

View File

@ -101,9 +101,11 @@
<Loading /> <Loading />
</el-icon> </el-icon>
</div> </div>
<div v-show="!qrcodeLoading"> <div v-show="!qrcodeLoading" class="qrcode-list">
<img v-if="qrcodeImageUrl" :src="qrcodeImageUrl" alt="支付二维码" class="qrcode-image" /> <div v-for="(url, index) in paymentUrls" :key="index" class="qrcode-item">
<div v-else ref="qrcodeRef" class="qrcode"></div> <div class="qrcode-label">支付链接 {{ index + 1 }}</div>
<img :src="qrcodeImageUrls[index]" alt="支付二维码" class="qrcode-image" />
</div>
</div> </div>
</div> </div>
<div class="qrcode-tip">请使用{{ getMethodName(selectedMethod) }}扫描上方二维码完成支付</div> <div class="qrcode-tip">请使用{{ getMethodName(selectedMethod) }}扫描上方二维码完成支付</div>
@ -277,6 +279,12 @@ const qrcodeLoading = ref(false)
// URL // URL
const qrcodeImageUrl = ref('') const qrcodeImageUrl = ref('')
// URL
const qrcodeImageUrls = ref<string[]>([])
//
const paymentUrls = ref<string[]>([])
// //
const generateQRCode = async (url: string) => { const generateQRCode = async (url: string) => {
await nextTick() await nextTick()
@ -286,7 +294,7 @@ const generateQRCode = async (url: string) => {
width: 200, width: 200,
margin: 2, margin: 2,
}) })
qrcodeImageUrl.value = dataUrl qrcodeImageUrl.value = dataUrl
} catch (error) { } catch (error) {
console.error('生成二维码失败:', error) console.error('生成二维码失败:', error)
ElMessage.error('生成二维码失败') ElMessage.error('生成二维码失败')
@ -296,6 +304,23 @@ const generateQRCode = async (url: string) => {
} }
} }
//
const generateQRCodes = async (urls: string[]) => {
//
for (let i = 0; i < urls.length; i++) {
try {
const dataUrl = await QRCode.toDataURL(urls[i] as any, {
width: 200,
margin: 2,
})
qrcodeImageUrls.value[i] = dataUrl as any
} catch (error) {
console.error('生成二维码失败:', error)
}
}
qrcodeLoading.value = false
}
// //
const dialogVisible = ref(false) const dialogVisible = ref(false)
const rechangeFormRef = ref<FormInstance>() const rechangeFormRef = ref<FormInstance>()
@ -458,10 +483,13 @@ const handleCreateOrder = async () => {
}) })
// URL // URL
const payUrl = res.payment_urls[1] const payUrls = res.payment_urls || []
if (payUrl) { if (payUrls.length > 0) {
paymentUrls.value = payUrls
if (isMobileDevice.value) { if (isMobileDevice.value) {
// // safe.paylinktrust.com
const safeUrl = payUrls.find((url:string)=> url.includes('safe.paylinktrust.com'))
const payUrl = safeUrl || payUrls[0]
ElMessage.success('正在跳转支付页面...') ElMessage.success('正在跳转支付页面...')
setTimeout(() => { setTimeout(() => {
window.location.href = payUrl window.location.href = payUrl
@ -469,9 +497,9 @@ const handleCreateOrder = async () => {
handleCancel() handleCancel()
}, 500) }, 500)
} else { } else {
// //
ElMessage.success('正在生成支付二维码...') ElMessage.success('正在生成支付二维码...')
await generateQRCode(payUrl) await generateQRCodes(payUrls)
} }
} else { } else {
ElMessage.error('获取支付链接失败') ElMessage.error('获取支付链接失败')
@ -543,6 +571,8 @@ const handleCancel = () => {
rechangeFormRef.value?.resetFields() rechangeFormRef.value?.resetFields()
rechangeForm.value = createDefaultForm() rechangeForm.value = createDefaultForm()
qrcodeImageUrl.value = '' qrcodeImageUrl.value = ''
qrcodeImageUrls.value = []
paymentUrls.value = []
qrcodeLoading.value = false qrcodeLoading.value = false
payStep.value = 1 payStep.value = 1
selectedMethod.value = '' selectedMethod.value = ''
@ -800,6 +830,26 @@ onMounted(() => {
display: block; display: block;
} }
.qrcode-list {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 24px;
}
.qrcode-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
.qrcode-label {
font-size: 14px;
color: #606266;
font-weight: 500;
}
.qrcode { .qrcode {
width: 200px; width: 200px;
height: 200px; height: 200px;

View File

@ -9,13 +9,6 @@
@reset="handleReset" @reset="handleReset"
> >
<template #button> <template #button>
<!-- 审核动作先保留按钮交互后续可直接接接口 -->
<el-button type="danger" plain @click="handleReject" v-auth="'user_reviewRechargeOrder'"
>驳回</el-button
>
<el-button type="success" @click="handleApprove" v-auth="'user_reviewRechargeOrder'"
>通过</el-button
>
<el-button type="primary" plain @click="handleExport">导出</el-button> <el-button type="primary" plain @click="handleExport">导出</el-button>
</template> </template>
</RechangeSearch> </RechangeSearch>
@ -27,9 +20,21 @@
:columns="tableColumns" :columns="tableColumns"
row-key="id" row-key="id"
:loading="loading" :loading="loading"
:show-selection="true" :show-selection="false"
:single-select="false"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
/> >
<!-- 操作列驳回/通过按钮 -->
<template #action="{ row }">
<el-button type="danger" text size="small" @click="handleReject(row)" v-auth="'user_reviewRechargeOrder'">
驳回
</el-button>
<span style="color: #dcdfe6; margin: 0 2px;">|</span>
<el-button type="success" text size="small" @click="handleApprove(row)" v-auth="'user_reviewRechargeOrder'">
通过
</el-button>
</template>
</Table>
<!-- 分页区域使用接口返回的 total / current_page / per_page --> <!-- 分页区域使用接口返回的 total / current_page / per_page -->
<RechangePagination <RechangePagination
@ -198,10 +203,10 @@ console.log('rows:', rows);
// } // }
} }
// //
const handleApprove = async () => { const handleApprove = async (row?: any) => {
console.log('selectedRows.value:', selectedRows.value); const targetRow = row || selectedRows.value[0]
if (!selectedRows.value.length) { if (!targetRow) {
ElMessage.warning('请先选择要通过的记录') ElMessage.warning('请先选择要通过的记录')
return return
} }
@ -217,21 +222,22 @@ const handleApprove = async () => {
startLoading() startLoading()
try { try {
await reviewRechargeOrder({ id: selectedRows.value[0]?.id, status: '3' }) await reviewRechargeOrder({ id: targetRow.id, status: '3' })
await getList() await getList()
} finally { } finally {
stopLoading() stopLoading()
} }
} }
// //
const handleReject = async () => { const handleReject = async (row?: any) => {
if (!selectedRows.value.length) { const targetRow = row || selectedRows.value[0]
if (!targetRow) {
ElMessage.warning('请先选择要驳回的记录') ElMessage.warning('请先选择要驳回的记录')
return return
} }
try { try {
await ElMessageBox.confirm(`是否确认驳回该审核?订单号:${selectedRows.value[0]?.orderNo}`, '审核确认', { await ElMessageBox.confirm(`是否确认驳回该审核?订单号:${targetRow.orderNo}`, '审核确认', {
confirmButtonText: '确认', confirmButtonText: '确认',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning',
@ -243,7 +249,7 @@ const handleReject = async () => {
//:1,2,3,4 //:1,2,3,4
startLoading() startLoading()
try { try {
await reviewRechargeOrder({ id: selectedRows.value[0]?.id, status: '4' }) await reviewRechargeOrder({ id: targetRow.id, status: '4' })
await getList() await getList()
} finally { } finally {
stopLoading() stopLoading()
@ -269,7 +275,7 @@ const handlePaginationChange = (page: { currentPage: number; pageSize: number })
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.rechange-check { .rechange-check {
// //
:deep(.search-container .el-form) { :deep(.search-container .el-form) {

View File

@ -47,4 +47,5 @@ export const rechangeCheckTableColumns = [
{ prop: 'rate', label: '汇率', align: 'center' as const, width: 100 }, { prop: 'rate', label: '汇率', align: 'center' as const, width: 100 },
{ prop: 'statusText', label: '状态', align: 'center' as const, width: 100 }, { prop: 'statusText', label: '状态', align: 'center' as const, width: 100 },
{ prop: 'rechangeTime', label: '充值时间', align: 'center' as const }, { prop: 'rechangeTime', label: '充值时间', align: 'center' as const },
{ label: '操作', align: 'center' as const, width: 180, fixed: 'right' as const, slotName: 'action' },
] ]

View File

@ -125,7 +125,7 @@
<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 type="primary" :loading="submitLoading" @click="handleSubmit">{{ t('withdraw.dialog.confirmWithdraw')
}}</el-button> }}</el-button>
</div> </div>
</div> </div>
</Dialog> </Dialog>
@ -238,36 +238,36 @@ const availableBalance = computed(() => {
Math.max(0, parseFloat(walletInfo.value.risk || '0')) + Math.max(0, parseFloat(walletInfo.value.risk || '0')) +
Math.max(0, parseFloat(walletInfo.value.service || '0')) + Math.max(0, parseFloat(walletInfo.value.service || '0')) +
Math.max(0, parseFloat(walletInfo.value.commission_fee_handling || '0')) + Math.max(0, parseFloat(walletInfo.value.commission_fee_handling || '0')) +
Math.max(0, parseFloat(walletInfo.value.commission_point_diff || '0')) Math.max(0, parseFloat(walletInfo.value.commission_point_diff || '0'))
// Math.max(0, parseFloat(walletInfo.value.closing_profit || '0')) // Math.max(0, parseFloat(walletInfo.value.closing_profit || '0'))
return floorMoney(amount - walletSum) return floorMoney(amount - walletSum)
}) })
// //
// roleId >= 5 totalWalletBalance availableBalance // roleId >= 5 totalWalletBalance availableBalance
const totalWalletBalance = computed(() => { const totalWalletBalance = 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')
console.log('walletInfo.value:', amount , freeze); console.log('walletInfo.value:', amount, freeze);
// + + + + // + + + +
// const walletSum = const walletSum =
// parseFloat(walletInfo.value.commission_fee_handling || '0') + parseFloat(walletInfo.value.commission_fee_handling || '0') +
// parseFloat(walletInfo.value.commission_point_diff || '0') + parseFloat(walletInfo.value.commission_point_diff || '0') +
// parseFloat(walletInfo.value.service || '0') + parseFloat(walletInfo.value.service || '0') +
// parseFloat(walletInfo.value.risk || '0') + parseFloat(walletInfo.value.risk || '0') +
// parseFloat(walletInfo.value.closing_profit || '0') parseFloat(Math.min(0, +walletInfo.value.closing_profit)+'')
// if (roleId >= 5) { if (roleId >= 5) {
// // roleId >= 5 // roleId >= 5
// // availableBalance = amount - freeze - walletSum // availableBalance = amount - freeze - walletSum
// const availableBal = Math.max(0, amount - walletSum) // const availableBal = Math.max(0, amount - walletSum)
// return walletSum + availableBal return floorMoney(amount - freeze)
// } }
return floorMoney(amount - freeze) return floorMoney(walletSum)
}) })
const floorMoney = (num:number) => { const floorMoney = (num: number) => {
const cents = Math.floor(num * 100); const cents = Math.floor(num * 100);
return cents / 100; return cents / 100;
} }
@ -295,10 +295,10 @@ const feeFieldMap: Record<string, keyof WalletInfo | 'available'> = {
// //
const feeOrder = computed(() => { const feeOrder = computed(() => {
const orders: Record<number, string[]> = { const orders: Record<number, string[]> = {
1: ['手续费', '点差', '服务费', '风险金', '盈亏', '可用余额'], // 1: ['手续费', '点差', '服务费', '风险金', '盈亏'], //
2: ['手续费', '点差', '服务费', '可用余额'], // 2: ['手续费', '点差', '服务费'], //
3: ['手续费', '点差', '服务费', '盈亏', '可用余额'], // 3: ['手续费', '点差', '服务费', '盈亏'], //
4: ['手续费', '点差', '服务费', '盈亏', '可用余额'], // 4: ['手续费', '点差', '服务费', '盈亏'], //
5: ['手续费', '点差', '可用余额'], // 5: ['手续费', '点差', '可用余额'], //
6: ['手续费', '点差', '可用余额'], // 6: ['手续费', '点差', '可用余额'], //
} }
@ -308,25 +308,25 @@ const feeOrder = computed(() => {
// //
const walletItems = computed(() => { const walletItems = computed(() => {
const items: { label: string; value: string; field: string }[] = [] const items: { label: string; value: string; field: string }[] = []
for (const feeType of feeOrder.value) { for (const feeType of feeOrder.value) {
const field = feeFieldMap[feeType] const field = feeFieldMap[feeType]
if (!field) continue if (!field) continue
let value: string let value: string
if (field === 'available') { if (field === 'available') {
value = availableBalance.value.toFixed(2) value = availableBalance.value.toFixed(2)
} else { } else {
value = walletInfo.value[field] || '0.00' value = walletInfo.value[field] || '0.00'
} }
items.push({ items.push({
label: feeLabelMap[feeType] || feeType, label: feeLabelMap[feeType] || feeType,
value, value,
field, field,
}) })
} }
return items return items
}) })
@ -413,7 +413,7 @@ const initData = async () => {
if (res) { if (res) {
walletInfo.value = { walletInfo.value = {
commission_fee_handling: res.commission_fee_handling || '0', commission_fee_handling: res.commission_fee_handling || '0',
commission_point_diff: ''+floorMoney(res.commission_point_diff - res.freeze||0) || '0', commission_point_diff: '' + floorMoney(res.commission_point_diff - res.freeze || 0) || '0',
service: res.service || '0', service: res.service || '0',
risk: res.risk || '0', risk: res.risk || '0',
closing_profit: res.closing_profit || '0', closing_profit: res.closing_profit || '0',
@ -542,7 +542,7 @@ const handleNextStep = () => {
// //
for (const feeType of feeOrder.value) { for (const feeType of feeOrder.value) {
const deducted = calculatedData.value.find(item => item.type === feeType)?.deducted || '0' const deducted = calculatedData.value.find(item => item.type === feeType)?.deducted || '0'
switch (feeType) { switch (feeType) {
case '手续费': case '手续费':
formData.value.withdraw_fee_handle = deducted formData.value.withdraw_fee_handle = deducted

View File

@ -1,12 +1,7 @@
<template> <template>
<div class="withdraw-check table_form-container"> <div class="withdraw-check table_form-container">
<!-- 搜索区域复用项目内搜索组件 --> <!-- 搜索区域复用项目内搜索组件 -->
<WithdrawSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch" @reset="handleReset"> <WithdrawSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch" @reset="handleReset" />
<template #button>
<el-button type="success" :loading="approveLoading" @click="handleApprove">通过</el-button>
<el-button type="danger" plain :loading="rejectLoading" @click="handleReject">驳回</el-button>
</template>
</WithdrawSearch>
<!-- 列表区域使用公共 Table 组件 --> <!-- 列表区域使用公共 Table 组件 -->
<Table <Table
@ -17,7 +12,18 @@
:loading="loading" :loading="loading"
:show-selection="true" :show-selection="true"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
/> >
<!-- 操作列驳回/通过按钮 -->
<template #action="{ row }">
<el-button type="success" text size="small" @click="handleApprove(row)" v-auth="'user_reviewWithdrawOrder'">
通过
</el-button>
<span style="color: #dcdfe6; margin: 0 2px;">|</span>
<el-button type="danger" text size="small" @click="handleReject(row)" v-auth="'user_reviewWithdrawOrder'">
驳回
</el-button>
</template>
</Table>
<!-- 分页区域复用项目内分页组件 --> <!-- 分页区域复用项目内分页组件 -->
<WithdrawPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total" <WithdrawPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
@ -216,16 +222,17 @@ const handleSelectionChange = (rows: TableRow[]) => {
selectedRows.value = rows selectedRows.value = rows
} }
// //
const handleApprove = async () => { const handleApprove = async (row?: TableRow) => {
if (!selectedRows.value.length) { const rowsToProcess = row ? [row] : selectedRows.value
if (!rowsToProcess.length) {
ElMessage.warning('请先选择要通过的记录') ElMessage.warning('请先选择要通过的记录')
return return
} }
try { try {
await ElMessageBox.confirm( await ElMessageBox.confirm(
`确定要通过 ${selectedRows.value.length} 条提现记录吗?`, `确定要通过 ${rowsToProcess.length} 条提现记录吗?`,
'审核确认', '审核确认',
{ {
confirmButtonText: '确定', confirmButtonText: '确定',
@ -236,9 +243,9 @@ const handleApprove = async () => {
approveLoading.value = true approveLoading.value = true
for (const row of selectedRows.value) { for (const item of rowsToProcess) {
await withdrawReviewOrder({ await withdrawReviewOrder({
id: row.id, id: item.id,
status: 2 status: 2
}) })
} }
@ -254,16 +261,17 @@ const handleApprove = async () => {
} }
} }
// //
const handleReject = async () => { const handleReject = async (row?: TableRow) => {
if (!selectedRows.value.length) { const rowsToProcess = row ? [row] : selectedRows.value
if (!rowsToProcess.length) {
ElMessage.warning('请先选择要驳回的记录') ElMessage.warning('请先选择要驳回的记录')
return return
} }
try { try {
await ElMessageBox.confirm( await ElMessageBox.confirm(
`确定要驳回 ${selectedRows.value.length} 条提现记录吗?`, `确定要驳回 ${rowsToProcess.length} 条提现记录吗?`,
'审核确认', '审核确认',
{ {
confirmButtonText: '确定', confirmButtonText: '确定',
@ -274,9 +282,9 @@ const handleReject = async () => {
rejectLoading.value = true rejectLoading.value = true
for (const row of selectedRows.value) { for (const item of rowsToProcess) {
await withdrawReviewOrder({ await withdrawReviewOrder({
id: row.id, id: item.id,
status: 4 status: 4
}) })
} }

View File

@ -38,5 +38,6 @@ export const withdrawCheckTableColumns = [
{ prop: 'withdraw_point_diff', label: '点差', align: 'center' as const, width: 100, isNumber: true }, { prop: 'withdraw_point_diff', label: '点差', align: 'center' as const, width: 100, isNumber: true },
{ prop: 'withdraw_risk_fee', label: '风控费', align: 'center' as const, isNumber: true }, { prop: 'withdraw_risk_fee', label: '风控费', align: 'center' as const, isNumber: true },
{ prop: 'withdraw_address', label: '提现地址', align: 'center' as const}, { prop: 'withdraw_address', label: '提现地址', align: 'center' as const},
{ prop: 'created_at', label: '申请时间', align: 'center' as const} { prop: 'created_at', label: '申请时间', align: 'center' as const},
{ label: '操作', align: 'center' as const, width: 140, fixed: 'right' as const, slotName: 'action' },
] ]

View File

@ -69,14 +69,14 @@
<div class="balance-section"> <div class="balance-section">
<div class="balance-label">总金额</div> <div class="balance-label">总金额</div>
<div class="balance-value"> <div class="balance-value">
<AnimatedNumber :value="walletCapital.amount_total || 0" :decimals="5" /> <AnimatedNumber :value="walletCapital.amount_total || 0" :decimals="2" />
</div> </div>
</div> </div>
<div class="balance-detail"> <div class="balance-detail">
<div class="detail-item"> <div class="detail-item">
<span class="label">可用资金</span> <span class="label">可用资金</span>
<span class="value"> <span class="value">
<AnimatedNumber :value="walletCapital.amount || 0" :decimals="5" /> <AnimatedNumber :value="walletCapital.amount || 0" :decimals="2" />
</span> </span>
</div> </div>
<template v-if="isAgent"> <template v-if="isAgent">
@ -152,13 +152,13 @@
<div class="stat-item"> <div class="stat-item">
<span class="stat-label">净资产</span> <span class="stat-label">净资产</span>
<span class="stat-value"> <span class="stat-value">
<AnimatedNumber :value="item?.wallets_trade?.amount || 0" :decimals="5" /> <AnimatedNumber :value="item?.wallets_trade?.amount || 0" :decimals="2" />
</span> </span>
</div> </div>
<div class="stat-item"> <div class="stat-item">
<span class="stat-label">余额</span> <span class="stat-label">余额</span>
<span class="stat-value"> <span class="stat-value">
<AnimatedNumber :value="item?.wallets_trade?.amount || 0" :decimals="5" /> <AnimatedNumber :value="item?.wallets_trade?.amount || 0" :decimals="2" />
</span> </span>
</div> </div>
<div class="stat-item"> <div class="stat-item">