|
@@ -1,6 +1,6 @@
|
|
|
<template>
|
|
<template>
|
|
|
<div>
|
|
<div>
|
|
|
- <div class="toolbar">
|
|
|
|
|
|
|
+ <div class="filter-bar">
|
|
|
<el-select v-model="statusFilter" placeholder="审核状态" @change="loadData">
|
|
<el-select v-model="statusFilter" placeholder="审核状态" @change="loadData">
|
|
|
<el-option label="全部" value="" />
|
|
<el-option label="全部" value="" />
|
|
|
<el-option label="待审核" value="pending" />
|
|
<el-option label="待审核" value="pending" />
|
|
@@ -10,7 +10,8 @@
|
|
|
<el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" style="width:200px" />
|
|
<el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" style="width:200px" />
|
|
|
<el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
|
|
<el-button size="small" @click="loadData" :loading="loading">刷新</el-button>
|
|
|
</div>
|
|
</div>
|
|
|
- <el-table :data="list" v-loading="loading" border stripe>
|
|
|
|
|
|
|
+ <div class="table-scroll-wrap"><div style="overflow:auto;max-height:calc(100vh - 300px);">
|
|
|
|
|
+ <el-table :data="list" v-loading="loading" border stripe style="min-width:900px;">
|
|
|
<el-table-column prop="id" label="ID" width="60" />
|
|
<el-table-column prop="id" label="ID" width="60" />
|
|
|
<el-table-column label="用户" width="120">
|
|
<el-table-column label="用户" width="120">
|
|
|
<template slot-scope="{ row }">{{ row.nickname || row.userName || '-' }}</template>
|
|
<template slot-scope="{ row }">{{ row.nickname || row.userName || '-' }}</template>
|
|
@@ -26,23 +27,27 @@
|
|
|
<el-tag :type="statusType(row.status)">{{ statusLabel(row.status) }}</el-tag>
|
|
<el-tag :type="statusType(row.status)">{{ statusLabel(row.status) }}</el-tag>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
|
|
+ <el-table-column prop="createdAt" label="申请时间" width="160" />
|
|
|
<el-table-column label="操作" width="180" fixed="right">
|
|
<el-table-column label="操作" width="180" fixed="right">
|
|
|
<template slot-scope="{ row }">
|
|
<template slot-scope="{ row }">
|
|
|
<template v-if="row.status === 'pending'">
|
|
<template v-if="row.status === 'pending'">
|
|
|
- <el-button size="mini" type="success" @click="handleAudit(row, 'approved')">通过</el-button>
|
|
|
|
|
- <el-button size="mini" type="danger" @click="showReject(row)">拒绝</el-button>
|
|
|
|
|
|
|
+ <el-button size="mini" type="success" @click="handleApprove(row)">通过</el-button>
|
|
|
|
|
+ <el-button size="mini" type="danger" @click="handleReject(row)">拒绝</el-button>
|
|
|
</template>
|
|
</template>
|
|
|
- <span v-else class="no-op">—</span>
|
|
|
|
|
|
|
+ <span v-else style="color:#999">-</span>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- </el-table>
|
|
|
|
|
- <el-dialog title="拒绝原因" :visible.sync="rejectDialogVisible" width="400px">
|
|
|
|
|
- <el-input v-model="rejectReason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
|
|
|
|
|
- <span slot="footer">
|
|
|
|
|
- <el-button @click="rejectDialogVisible = false">取消</el-button>
|
|
|
|
|
- <el-button type="danger" @click="confirmReject">确认拒绝</el-button>
|
|
|
|
|
- </span>
|
|
|
|
|
- </el-dialog>
|
|
|
|
|
|
|
+ </el-table></div></div>
|
|
|
|
|
+
|
|
|
|
|
+ <el-pagination
|
|
|
|
|
+ v-if="total > 0"
|
|
|
|
|
+ :current-page="page"
|
|
|
|
|
+ :page-size="size"
|
|
|
|
|
+ :total="total"
|
|
|
|
|
+ layout="total, prev, pager, next"
|
|
|
|
|
+ @current-change="loadData"
|
|
|
|
|
+ style="margin-top:12px;text-align:right;"
|
|
|
|
|
+ />
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -50,43 +55,79 @@
|
|
|
import { getWithdrawalList, auditWithdrawal } from '@/api/admin'
|
|
import { getWithdrawalList, auditWithdrawal } from '@/api/admin'
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
|
|
|
+ name: 'WithdrawAudit',
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
|
- list: [], loading: false, keyword: '', statusFilter: 'pending',
|
|
|
|
|
- rejectDialogVisible: false, rejectTarget: null, rejectReason: ''
|
|
|
|
|
|
|
+ list: [],
|
|
|
|
|
+ loading: false,
|
|
|
|
|
+ keyword: '',
|
|
|
|
|
+ statusFilter: '',
|
|
|
|
|
+ page: 1,
|
|
|
|
|
+ size: 20,
|
|
|
|
|
+ total: 0
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
- mounted() { this.loadData() },
|
|
|
|
|
|
|
+ created() {
|
|
|
|
|
+ this.loadData()
|
|
|
|
|
+ },
|
|
|
methods: {
|
|
methods: {
|
|
|
- statusType(s) { return { pending: 'warning', approved: 'success', rejected: 'danger' }[s] || 'info' },
|
|
|
|
|
- statusLabel(s) { return { pending: '待审核', approved: '已通过', rejected: '已拒绝' }[s] || s },
|
|
|
|
|
- formatPrice(p) { if (p == null) return '-'; return '¥' + (p / 100).toFixed(2) },
|
|
|
|
|
- handleSearch() { this.loadData() },
|
|
|
|
|
async loadData() {
|
|
async loadData() {
|
|
|
this.loading = true
|
|
this.loading = true
|
|
|
try {
|
|
try {
|
|
|
- const res = await getWithdrawalList({ status: this.statusFilter, keyword: this.keyword || undefined })
|
|
|
|
|
- this.list = res.data && res.data.records || res.data || []
|
|
|
|
|
- } catch (e) { this.$message.error('加载失败')
|
|
|
|
|
- } finally { this.loading = false }
|
|
|
|
|
|
|
+ const res = await getWithdrawalList({
|
|
|
|
|
+ page: this.page,
|
|
|
|
|
+ size: this.size,
|
|
|
|
|
+ status: this.statusFilter || undefined,
|
|
|
|
|
+ keyword: this.keyword || undefined
|
|
|
|
|
+ })
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ this.list = res.data && res.data.records || res.data && res.data.list || []
|
|
|
|
|
+ this.total = (res.data && res.data.total) || 0
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ this.$message.error('加载失败')
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ this.loading = false
|
|
|
|
|
+ }
|
|
|
},
|
|
},
|
|
|
- async handleAudit(row, status) {
|
|
|
|
|
|
|
+ handleSearch() {
|
|
|
|
|
+ this.page = 1
|
|
|
|
|
+ this.loadData()
|
|
|
|
|
+ },
|
|
|
|
|
+ async handleApprove(row) {
|
|
|
try {
|
|
try {
|
|
|
- await this.$confirm(status === 'approved' ? '确认通过该提现申请?' : '确认拒绝该提现申请?', '提示')
|
|
|
|
|
- await auditWithdrawal(row.id, status, status === 'rejected' ? this.rejectReason : '')
|
|
|
|
|
- this.$message.success('操作成功')
|
|
|
|
|
- this.rejectDialogVisible = false
|
|
|
|
|
|
|
+ await this.$confirm('确认通过该提现申请?', '提示', { type: 'warning' })
|
|
|
|
|
+ await auditWithdrawal(row.id, 'approved', '')
|
|
|
|
|
+ this.$message.success('已通过')
|
|
|
this.loadData()
|
|
this.loadData()
|
|
|
} catch (e) {
|
|
} catch (e) {
|
|
|
if (e !== 'cancel') this.$message.error('操作失败')
|
|
if (e !== 'cancel') this.$message.error('操作失败')
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
- showReject(row) { this.rejectTarget = row; this.rejectReason = ''; this.rejectDialogVisible = true },
|
|
|
|
|
- confirmReject() { this.handleAudit(this.rejectTarget, 'rejected') }
|
|
|
|
|
|
|
+ async handleReject(row) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await this.$confirm('确认拒绝该提现申请?', '提示', { type: 'warning' })
|
|
|
|
|
+ await auditWithdrawal(row.id, 'rejected', '')
|
|
|
|
|
+ this.$message.success('已拒绝')
|
|
|
|
|
+ this.loadData()
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ if (e !== 'cancel') this.$message.error('操作失败')
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ formatPrice(val) {
|
|
|
|
|
+ if (val == null) return '-'
|
|
|
|
|
+ return '¥' + (val / 100).toFixed(2)
|
|
|
|
|
+ },
|
|
|
|
|
+ statusType(s) {
|
|
|
|
|
+ return { approved: 'success', pending: 'warning', rejected: 'danger' }[s] || 'info'
|
|
|
|
|
+ },
|
|
|
|
|
+ statusLabel(s) {
|
|
|
|
|
+ return { approved: '已通过', pending: '待审核', rejected: '已拒绝' }[s] || s
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
+
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
-.toolbar { display: flex; gap: 12px; align-items: center; margin-bottom: 16px; }
|
|
|
|
|
-.no-op { color: #ccc; }
|
|
|
|
|
-</style>
|
|
|
|
|
|
|
+.filter-bar { display: flex; gap: 12px; align-items: center; margin-bottom: 12px; padding: 12px; background: #fff; border-radius: 4px; box-shadow: 0 2px 4px rgba(0,0,0,0.08); }
|
|
|
|
|
+</style>
|