提现审核页增加待收款/成功失败等明细状态筛选。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-15 06:03:53 +08:00
parent a6d339c473
commit fd2e6c1c3f

View File

@@ -1,8 +1,8 @@
<template>
<div class="withdraw-audit">
<!-- 顶部统计卡片 -->
<el-row :gutter="20" class="stats-cards">
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-row :gutter="16" class="stats-cards">
<el-col :xs="12" :sm="8" :md="4" :lg="4" :xl="4">
<el-card class="stat-card" shadow="hover">
<div class="stat-item">
<div class="stat-label">总记录</div>
@@ -10,18 +10,42 @@
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-card class="stat-card" shadow="hover" @click="changeStatus(1)">
<el-col :xs="12" :sm="8" :md="4" :lg="4" :xl="4">
<el-card class="stat-card" shadow="hover" @click="changeDetailStatus(1)">
<div class="stat-item">
<div class="stat-label">待审核</div>
<div class="stat-value warning">{{ stats.awaiting || 0 }}</div>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-col :xs="12" :sm="8" :md="4" :lg="4" :xl="4" v-if="isAutoMode">
<el-card class="stat-card" shadow="hover" @click="changeDetailStatus(6)">
<div class="stat-item">
<div class="stat-label">待收款</div>
<div class="stat-value warning">{{ stats.pending_collect || 0 }}</div>
</div>
</el-card>
</el-col>
<el-col :xs="12" :sm="8" :md="4" :lg="4" :xl="4">
<el-card class="stat-card" shadow="hover" @click="changeDetailStatus(2)">
<div class="stat-item">
<div class="stat-label">提现成功</div>
<div class="stat-value success">{{ stats.success || 0 }}</div>
</div>
</el-card>
</el-col>
<el-col :xs="12" :sm="8" :md="4" :lg="4" :xl="4">
<el-card class="stat-card" shadow="hover" @click="changeDetailStatus(3)">
<div class="stat-item">
<div class="stat-label">提现失败</div>
<div class="stat-value danger">{{ stats.fail || 0 }}</div>
</div>
</el-card>
</el-col>
<el-col :xs="12" :sm="8" :md="4" :lg="4" :xl="4">
<el-card class="stat-card" shadow="hover" @click="changeStatus(2)">
<div class="stat-item">
<div class="stat-label">已处理</div>
<div class="stat-label">已处理(全部)</div>
<div class="stat-value success">{{ stats.processed || 0 }}</div>
</div>
</el-card>
@@ -87,14 +111,52 @@
<el-col :span="24">
<div class="status-switch">
<el-button
:type="statusFilter === 1 ? 'primary' : 'default'"
@click="changeStatus(1)"
:type="isStatusActive(1) ? 'primary' : 'default'"
@click="changeDetailStatus(1)"
size="large"
>
待审核 <el-tag size="small" type="warning" v-if="stats.awaiting">{{ stats.awaiting }}</el-tag>
</el-button>
<el-button
:type="statusFilter === 2 ? 'success' : 'default'"
v-if="isAutoMode"
:type="isStatusActive(6) ? 'warning' : 'default'"
@click="changeDetailStatus(6)"
size="large"
>
待收款 <el-tag size="small" type="warning" v-if="stats.pending_collect">{{ stats.pending_collect }}</el-tag>
</el-button>
<el-button
:type="isStatusActive(2) ? 'success' : 'default'"
@click="changeDetailStatus(2)"
size="large"
>
提现成功 <el-tag size="small" type="success" v-if="stats.success">{{ stats.success }}</el-tag>
</el-button>
<el-button
:type="isStatusActive(3) ? 'danger' : 'default'"
@click="changeDetailStatus(3)"
size="large"
>
提现失败
</el-button>
<el-button
v-if="isAutoMode"
:type="isStatusActive(4) ? 'success' : 'default'"
@click="changeDetailStatus(4)"
size="large"
>
审核成功
</el-button>
<el-button
v-if="isAutoMode"
:type="isStatusActive(5) ? 'danger' : 'default'"
@click="changeDetailStatus(5)"
size="large"
>
审核失败
</el-button>
<el-button
:type="isProcessedActive ? 'success' : 'default'"
@click="changeStatus(2)"
size="large"
>
@@ -148,7 +210,7 @@
</el-card>
<!-- 自动打款批量操作栏 -->
<div v-if="isAutoMode && statusFilter === 1" class="batch-bar">
<div v-if="isAutoMode && canBatchOperate" class="batch-bar">
<span class="batch-tip">已选 {{ selectedRows.length }} </span>
<el-button
type="success"
@@ -182,7 +244,7 @@
@selection-change="handleSelectionChange"
>
<el-table-column
v-if="isAutoMode && statusFilter === 1"
v-if="isAutoMode && canBatchOperate"
type="selection"
width="48"
fixed="left"
@@ -200,13 +262,20 @@
</div>
</template>
</el-table-column>
<el-table-column prop="jine" label="金额" width="120">
<el-table-column prop="jine" label="申请金额" width="110">
<template #default="{ row }">¥{{ row.jine }}</template>
</el-table-column>
<el-table-column v-if="isAutoMode" label="手续费" width="90">
<template #default="{ row }">{{ row.shouxufei ? `¥${row.shouxufei}` : '--' }}</template>
</el-table-column>
<el-table-column v-if="isAutoMode" label="实际到账" width="100">
<template #default="{ row }">{{ row.shijidaozhang ? `¥${row.shijidaozhang}` : '--' }}</template>
</el-table-column>
<el-table-column label="提现类型" width="110">
<template #default="{ row }">{{ getTypeText(row.leixing) }}</template>
</el-table-column>
<el-table-column v-if="isAutoMode" prop="shenhe_danhao" label="审核单号" min-width="160" show-overflow-tooltip />
<el-table-column v-if="isAutoMode" prop="dakuan_mch_id" label="打款商户" min-width="120" show-overflow-tooltip />
<el-table-column label="打款方式" width="100">
<template #default="{ row }">
<el-tag :type="row.dakuan_mode === 2 ? 'success' : 'info'" size="small">
@@ -220,15 +289,18 @@
<el-table-column label="状态" width="110">
<template #default="{ row }">
<el-tag :type="getStatusType(row.zhuangtai)">
{{ getStatusText(row.zhuangtai) }}
{{ row.zhuangtai_text || getStatusText(row.zhuangtai) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="失败原因" min-width="140" show-overflow-tooltip>
<template #default="{ row }">{{ row.fail_reason || row.bhliyou || '--' }}</template>
</el-table-column>
<el-table-column prop="create_time" label="申请时间" width="160" :formatter="formatTime" />
<el-table-column label="操作" :width="isAutoMode && statusFilter === 1 ? 200 : 80" fixed="right">
<el-table-column label="操作" :width="isAutoMode && canBatchOperate ? 200 : 80" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click.stop="goToDetail(row)">详情</el-button>
<template v-if="isAutoMode && statusFilter === 1 && row.zhuangtai === 1">
<template v-if="isAutoMode && canBatchOperate && row.zhuangtai === 1">
<el-button type="success" link @click.stop="handleInlineApprove(row)">同意</el-button>
<el-button type="danger" link @click.stop="showInlineRejectDialog(row)">驳回</el-button>
</template>
@@ -294,6 +366,9 @@ const stats = ref({
total: 0,
awaiting: 0,
processed: 0,
pending_collect: 0,
success: 0,
fail: 0,
total_amount: '0.00'
})
@@ -307,7 +382,9 @@ const filters = reactive({
dakuanMode: 1
})
// statusFilter: 1=待审核粗粒度 2=已处理粗粒度detailZhuangtai: 1~6 精确态(优先生效)
const statusFilter = ref(1)
const detailZhuangtai = ref(null)
const rejectDialogVisible = ref(false)
const rejectReason = ref('')
@@ -315,6 +392,14 @@ const rejectTargetRow = ref(null)
const rejectMode = ref('single')
const isAutoMode = computed(() => filters.dakuanMode === 2)
const canBatchOperate = computed(() => {
if (detailZhuangtai.value != null) return Number(detailZhuangtai.value) === 1
return Number(statusFilter.value) === 1
})
const isProcessedActive = computed(() => (
detailZhuangtai.value == null && Number(statusFilter.value) === 2
))
const isStatusActive = (code) => Number(detailZhuangtai.value) === Number(code)
const getFullImageUrl = (url) => {
if (!url) return ''
@@ -425,6 +510,7 @@ const saveFiltersToStorage = () => {
minAmount: filters.minAmount,
maxAmount: filters.maxAmount,
statusFilter: statusFilter.value,
detailZhuangtai: detailZhuangtai.value,
dakuanMode: filters.dakuanMode
}
localStorage.setItem(STORAGE_KEY, JSON.stringify(toStore))
@@ -442,6 +528,10 @@ const loadFiltersFromStorage = () => {
if (parsed.minAmount !== undefined) filters.minAmount = parsed.minAmount
if (parsed.maxAmount !== undefined) filters.maxAmount = parsed.maxAmount
if (parsed.statusFilter !== undefined && [1, 2].includes(parsed.statusFilter)) statusFilter.value = parsed.statusFilter
if (parsed.detailZhuangtai !== undefined && parsed.detailZhuangtai !== null
&& [1, 2, 3, 4, 5, 6].includes(Number(parsed.detailZhuangtai))) {
detailZhuangtai.value = Number(parsed.detailZhuangtai)
}
if (parsed.dakuanMode !== undefined && [1, 2].includes(parsed.dakuanMode)) filters.dakuanMode = parsed.dakuanMode
} catch (e) {
console.error('恢复筛选条件失败', e)
@@ -453,13 +543,18 @@ const buildListParams = () => {
phone: localStorage.getItem('username'),
page: page.value,
page_size: pageSize.value,
status: statusFilter.value,
dakuan_mode: filters.dakuanMode,
type: filters.type || undefined,
payment: filters.payment === 0 ? undefined : filters.payment,
search_uid: filters.searchUid || undefined,
date: filters.date || undefined
}
// 明细状态优先;否则用粗粒度 status
if (detailZhuangtai.value != null && [1, 2, 3, 4, 5, 6].includes(Number(detailZhuangtai.value))) {
params.zhuangtai = Number(detailZhuangtai.value)
} else {
params.status = statusFilter.value
}
if (filters.minAmount !== null && filters.minAmount !== '') {
params.min_amount = filters.minAmount
}
@@ -501,6 +596,9 @@ const fetchData = async () => {
total: 0,
awaiting: 0,
processed: 0,
pending_collect: 0,
success: 0,
fail: 0,
total_amount: '0.00',
...(data.stats || {})
}
@@ -524,13 +622,28 @@ const fetchData = async () => {
const handleDakuanModeChange = () => {
page.value = 1
selectedRows.value = []
// 手动打款无 4/5/6若当前卡在这些态回退待审核
if (!isAutoMode.value && [4, 5, 6].includes(Number(detailZhuangtai.value))) {
detailZhuangtai.value = 1
statusFilter.value = 1
}
fetchData()
saveFiltersToStorage()
}
const changeStatus = (status) => {
if (statusFilter.value === status) return
// 粗粒度已处理 / 待审核(清掉明细态)
statusFilter.value = status
detailZhuangtai.value = null
page.value = 1
selectedRows.value = []
fetchData()
saveFiltersToStorage()
}
const changeDetailStatus = (code) => {
detailZhuangtai.value = Number(code)
statusFilter.value = Number(code) === 1 ? 1 : 2
page.value = 1
selectedRows.value = []
fetchData()
@@ -552,6 +665,7 @@ const resetFilters = () => {
filters.maxAmount = null
filters.dakuanMode = 1
statusFilter.value = 1
detailZhuangtai.value = null
page.value = 1
localStorage.removeItem(STORAGE_KEY)
fetchData()
@@ -766,6 +880,9 @@ onMounted(() => {
.stat-value.success {
color: #67c23a;
}
.stat-value.danger {
color: #f56c6c;
}
.total-amount {
display: flex;
justify-content: space-between;