<script setup>
|
import { onMounted, reactive, ref } from 'vue'
|
import { ElMessage } from 'element-plus'
|
import { Refresh, Search } from '@element-plus/icons-vue'
|
import { getWithdrawals, processWithdrawal } from '@/api/finance'
|
|
const loading = ref(false)
|
const processing = ref(false)
|
const records = ref([])
|
const total = ref(0)
|
const dateRange = ref([])
|
const dialogVisible = ref(false)
|
const current = ref(null)
|
const query = reactive({ page: 1, size: 10, keyword: '', status: '' })
|
const processForm = reactive({ status: 'APPROVED', auditRemark: '' })
|
const statusMap = { PENDING: { label: '未处理', type: 'primary' }, TRANSFERRING: { label: '划账处理中', type: 'warning' }, TRANSFERRED: { label: '待发起取现', type: 'warning' }, PROCESSING: { label: '到账处理中', type: 'warning' }, APPROVED: { label: '已到账', type: 'success' }, REJECTED: { label: '已驳回', type: 'danger' } }
|
const formatMoney = (value) => Number(value || 0).toFixed(2)
|
const formatDateTime = (value) => value ? value.replace('T', ' ').slice(0, 19) : '-'
|
|
const loadWithdrawals = async () => {
|
loading.value = true
|
try {
|
const [startDate, endDate] = dateRange.value || []
|
const result = await getWithdrawals({ page: query.page, size: query.size, keyword: query.keyword.trim() || undefined, status: query.status || undefined, startDate, endDate })
|
records.value = result.records
|
total.value = result.total
|
} finally { loading.value = false }
|
}
|
const search = () => { query.page = 1; loadWithdrawals() }
|
const reset = () => { Object.assign(query, { page: 1, size: 10, keyword: '', status: '' }); dateRange.value = []; loadWithdrawals() }
|
const changePage = (page) => { query.page = page; loadWithdrawals() }
|
const changePageSize = (size) => { query.page = 1; query.size = size; loadWithdrawals() }
|
const openProcess = (row) => { current.value = row; Object.assign(processForm, { status: 'APPROVED', auditRemark: row.auditRemark || '' }); dialogVisible.value = true }
|
const submitProcess = async () => {
|
if (processForm.status === 'REJECTED' && !processForm.auditRemark.trim()) { ElMessage.warning('驳回提现时请填写处理备注'); return }
|
processing.value = true
|
try {
|
await processWithdrawal(current.value.id, { status: processForm.status, auditRemark: processForm.auditRemark.trim() || undefined })
|
ElMessage.success(processForm.status === 'APPROVED' ? '提现申请已受理,等待到账结果' : '提现申请已驳回')
|
dialogVisible.value = false
|
loadWithdrawals()
|
} finally { processing.value = false }
|
}
|
onMounted(loadWithdrawals)
|
</script>
|
|
<template>
|
<section class="withdrawal-page">
|
<el-card class="withdrawal-card" shadow="never">
|
<h2>查询表格</h2>
|
<el-form class="query-form" label-position="left" label-width="70px" @submit.prevent="search">
|
<el-form-item label="导游搜索"><el-input v-model="query.keyword" clearable placeholder="请输入导游手机号/导游姓名/提现编号" @keyup.enter="search" /></el-form-item>
|
<el-form-item label="申请时间"><el-date-picker v-model="dateRange" type="daterange" value-format="YYYY-MM-DD" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" /></el-form-item>
|
<el-form-item label="状态"><el-select v-model="query.status" clearable placeholder="全部"><el-option label="未处理" value="PENDING" /><el-option label="划账处理中" value="TRANSFERRING" /><el-option label="待发起取现" value="TRANSFERRED" /><el-option label="到账处理中" value="PROCESSING" /><el-option label="已到账" value="APPROVED" /><el-option label="已驳回" value="REJECTED" /></el-select></el-form-item>
|
<div class="query-actions"><el-button type="primary" :icon="Search" @click="search">查询</el-button><el-button :icon="Refresh" @click="reset">重置</el-button></div>
|
</el-form>
|
<el-table v-loading="loading" :data="records" border row-key="id">
|
<el-table-column prop="withdrawalNo" label="提现编号" min-width="145" align="center" />
|
<el-table-column prop="guideName" label="导游名称" min-width="120" align="center" />
|
<el-table-column prop="guideMobile" label="导游手机号" min-width="140" align="center" />
|
<el-table-column label="申请时间" min-width="170" align="center"><template #default="{ row }">{{ formatDateTime(row.appliedAt) }}</template></el-table-column>
|
<el-table-column label="提现金额" min-width="120" align="center"><template #default="{ row }">{{ formatMoney(row.amount) }}</template></el-table-column>
|
<el-table-column label="状态" width="110" align="center"><template #default="{ row }"><el-tag :type="statusMap[row.status]?.type || 'info'" effect="plain">{{ statusMap[row.status]?.label || row.status }}</el-tag></template></el-table-column>
|
<el-table-column label="操作" width="110" fixed="right" align="center"><template #default="{ row }"><el-button link type="primary" @click="openProcess(row)">{{ row.status === 'PENDING' ? '处理' : '查看' }}</el-button></template></el-table-column>
|
<template #empty><el-empty description="暂无提现申请" /></template>
|
</el-table>
|
<div class="pagination-row"><span>共 {{ total }} 条</span><el-pagination background layout="sizes, prev, pager, next, jumper" :current-page="query.page" :page-size="query.size" :page-sizes="[10, 20, 50]" :total="total" @current-change="changePage" @size-change="changePageSize" /></div>
|
</el-card>
|
<el-dialog v-model="dialogVisible" :title="current?.status === 'PENDING' ? '处理提现申请' : '提现申请详情'" width="560px">
|
<el-descriptions v-if="current" :column="2" border>
|
<el-descriptions-item label="提现编号">{{ current.withdrawalNo }}</el-descriptions-item><el-descriptions-item label="导游名称">{{ current.guideName }}</el-descriptions-item>
|
<el-descriptions-item label="导游手机号">{{ current.guideMobile }}</el-descriptions-item><el-descriptions-item label="提现金额">{{ formatMoney(current.amount) }}</el-descriptions-item>
|
<el-descriptions-item label="申请时间" :span="2">{{ formatDateTime(current.appliedAt) }}</el-descriptions-item>
|
<el-descriptions-item v-if="current.processor" label="处理人">{{ current.processor }}</el-descriptions-item><el-descriptions-item v-if="current.processedAt" label="处理时间">{{ formatDateTime(current.processedAt) }}</el-descriptions-item>
|
<el-descriptions-item v-if="current.transferReqSeqId" label="划账流水" :span="2">{{ current.transferReqSeqId }}</el-descriptions-item>
|
<el-descriptions-item v-if="current.cashReqSeqId" label="取现流水" :span="2">{{ current.cashReqSeqId }}</el-descriptions-item>
|
<el-descriptions-item v-if="current.payoutMessage" label="资金状态" :span="2">{{ current.payoutMessage }}</el-descriptions-item>
|
</el-descriptions>
|
<el-form v-if="current?.status === 'PENDING'" class="process-form" label-width="82px">
|
<el-form-item label="处理结果"><el-radio-group v-model="processForm.status"><el-radio-button value="APPROVED">通过</el-radio-button><el-radio-button value="REJECTED">驳回</el-radio-button></el-radio-group></el-form-item>
|
<el-form-item label="处理备注"><el-input v-model="processForm.auditRemark" type="textarea" :rows="3" maxlength="255" show-word-limit /></el-form-item>
|
</el-form>
|
<div v-else-if="current?.auditRemark" class="remark-row"><strong>处理备注:</strong>{{ current.auditRemark }}</div>
|
<template #footer><el-button @click="dialogVisible = false">关闭</el-button><el-button v-if="current?.status === 'PENDING'" type="primary" :loading="processing" @click="submitProcess">确认处理</el-button></template>
|
</el-dialog>
|
</section>
|
</template>
|
|
<style scoped>
|
.withdrawal-card { border: 0; border-radius: 4px; }
|
.withdrawal-card h2 { margin: 0 0 22px; font-size: 17px; }
|
.query-form { display: grid; grid-template-columns: minmax(290px, 1fr) minmax(340px, 1fr) minmax(220px, .75fr) auto; gap: 18px 28px; margin-bottom: 28px; padding-bottom: 24px; border-bottom: 1px solid #e5e7eb; }
|
.query-form :deep(.el-form-item) { margin: 0; }
|
.query-form :deep(.el-select), .query-form :deep(.el-date-editor) { width: 100%; }
|
.query-actions { display: flex; flex-direction: column; gap: 10px; }
|
.pagination-row { display: flex; justify-content: flex-end; align-items: center; gap: 18px; margin-top: 22px; }
|
.pagination-row > span { color: #64748b; font-size: 13px; }
|
.process-form { margin-top: 20px; }
|
.remark-row { margin-top: 18px; padding: 14px; color: #475467; background: #f7f8fa; }
|
</style>
|