feat(withdrawal): 增加提现审核对账与历史记录

This commit is contained in:
yml2213
2026-11-02 19:02:30 +08:00
parent 5334c2b218
commit 1b23b9b14b
12 changed files with 1595 additions and 250 deletions
@@ -12,26 +12,26 @@ import {
Wallet,
} from '@element-plus/icons-vue'
import { computed, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
fetchAdminWithdrawals,
fetchAdminWithdrawal,
reviewWithdrawal,
confirmPayment,
type WithdrawalDetail,
type WithdrawalListItem,
} from '@/features/admin/api/adminWithdrawal'
import { formatCentWithSymbol } from '@/shared/utils/money'
import { formatDateTime } from '@/shared/utils/time'
import { adminPath } from '@/shared/utils/adminPath'
import AdminTablePagination from '../components/AdminTablePagination.vue'
import WithdrawalDetailDialog from '../components/WithdrawalDetailDialog.vue'
const route = useRoute()
const router = useRouter()
const loading = ref(false)
const withdrawals = ref<WithdrawalDetail[]>([])
const withdrawals = ref<WithdrawalListItem[]>([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(20)
@@ -43,6 +43,7 @@ const filters = ref({
const showDetailDialog = ref(false)
const selectedWithdrawal = ref<WithdrawalDetail | null>(null)
const detailLoading = ref(false)
const statusOptions = [
{ label: '全部状态', value: '' },
@@ -53,17 +54,6 @@ const statusOptions = [
{ label: '已取消', value: 'cancelled' },
]
const withdrawalReturnQuery = computed<Record<string, string>>(() => {
const query: Record<string, string> = {
from: 'withdrawals',
withdrawal_page: String(currentPage.value),
withdrawal_page_size: String(pageSize.value),
}
if (filters.value.status) query.withdrawal_status = filters.value.status
if (filters.value.user_id) query.withdrawal_user_id = String(filters.value.user_id)
return query
})
const pendingCount = computed(() => withdrawals.value.filter(w => w.status === 'pending').length)
const processingCount = computed(
() => withdrawals.value.filter(w => w.status === 'processing').length
@@ -135,23 +125,20 @@ function resetFilters() {
void loadWithdrawals()
}
function openDetail(withdrawal: WithdrawalDetail) {
selectedWithdrawal.value = withdrawal
showDetailDialog.value = true
async function openDetail(withdrawal: WithdrawalListItem) {
if (detailLoading.value) return
detailLoading.value = true
try {
selectedWithdrawal.value = await fetchAdminWithdrawal(withdrawal.id)
showDetailDialog.value = true
} catch (error: any) {
ElMessage.error(error.response?.data?.message || '提现详情加载失败')
} finally {
detailLoading.value = false
}
}
function goToOwnerOrders(withdrawal: WithdrawalDetail) {
const keyword = withdrawal.user_phone?.trim() || String(withdrawal.user_id || '')
void router.push({
path: adminPath('orders'),
query: {
...withdrawalReturnQuery.value,
...(keyword ? { keyword } : {}),
},
})
}
async function handleReview(withdrawal: WithdrawalDetail, approved: boolean) {
async function handleReview(withdrawal: WithdrawalListItem, approved: boolean) {
const action = approved ? '通过' : '拒绝'
try {
const { value: remark } = await ElMessageBox.prompt(
@@ -179,7 +166,7 @@ async function handleReview(withdrawal: WithdrawalDetail, approved: boolean) {
}
}
async function handleConfirmPayment(withdrawal: WithdrawalDetail) {
async function handleConfirmPayment(withdrawal: WithdrawalListItem) {
try {
const { value: remark } = await ElMessageBox.prompt(
'请输入打款备注(如:已通过支付宝/微信转账)',
@@ -438,13 +425,18 @@ function money(cent: number | undefined | null) {
</template>
</el-table-column>
<el-table-column label="操作" width="240" fixed="right" align="center">
<el-table-column label="操作" width="190" fixed="right" align="center">
<template #default="{ row }">
<div class="action-cell">
<el-button link type="primary" :icon="View" @click="openDetail(row)">
<el-button
link
type="primary"
:icon="View"
:loading="detailLoading"
@click="openDetail(row)"
>
详情
</el-button>
<el-button link type="primary" @click="goToOwnerOrders(row)"> 号主订单 </el-button>
<el-button
v-if="row.status === 'pending'"
link
@@ -488,7 +480,6 @@ function money(cent: number | undefined | null) {
<WithdrawalDetailDialog
v-model="showDetailDialog"
:withdrawal="selectedWithdrawal"
:return-query="withdrawalReturnQuery"
@saved="onDetailDialogSaved"
/>
</div>