|
|
@@ -0,0 +1,255 @@
|
|
|
+<template>
|
|
|
+ <div class="app-container">
|
|
|
+ <el-card shadow="never">
|
|
|
+ <el-form :model="queryParams" ref="queryRef" :inline="true" label-width="90px">
|
|
|
+ <el-form-item label="提现单号" prop="withdrawNo">
|
|
|
+ <el-input
|
|
|
+ v-model="queryParams.withdrawNo"
|
|
|
+ placeholder="请输入提现单号"
|
|
|
+ clearable
|
|
|
+ style="width: 220px"
|
|
|
+ @keyup.enter="handleQuery"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="审核状态" prop="withdrawStatus">
|
|
|
+ <el-select v-model="queryParams.withdrawStatus" placeholder="请选择状态" clearable style="width: 180px">
|
|
|
+ <el-option
|
|
|
+ v-for="item in statusOptions"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="申请时间">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="dateRange"
|
|
|
+ type="daterange"
|
|
|
+ range-separator="至"
|
|
|
+ start-placeholder="开始日期"
|
|
|
+ end-placeholder="结束日期"
|
|
|
+ value-format="YYYY-MM-DD"
|
|
|
+ style="width: 260px"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
|
|
+ <el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <el-table v-loading="loading" :data="withdrawList">
|
|
|
+ <el-table-column label="提现单号" prop="withdrawNo" min-width="180" show-overflow-tooltip />
|
|
|
+ <el-table-column label="企业ID" prop="companyId" width="120" />
|
|
|
+ <el-table-column label="企业名称" prop="companyName" min-width="160" show-overflow-tooltip />
|
|
|
+ <el-table-column label="提现金额" prop="withdrawAmount" width="120">
|
|
|
+ <template #default="scope">
|
|
|
+ <span>¥ {{ Number(scope.row.withdrawAmount || 0).toFixed(2) }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="账户类型" min-width="120">
|
|
|
+ <template #default="scope">
|
|
|
+ <span>{{ getAccountTypeLabel(scope.row.account?.accountType) }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="收款账户" min-width="180" show-overflow-tooltip>
|
|
|
+ <template #default="scope">
|
|
|
+ <span>{{ scope.row.account?.accountNumber || '-' }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="账户名称" min-width="140" show-overflow-tooltip>
|
|
|
+ <template #default="scope">
|
|
|
+ <span>{{ scope.row.account?.accountName || '-' }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="审核状态" width="110">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-tag :type="getStatusTagType(scope.row.withdrawStatus)">
|
|
|
+ {{ getStatusLabel(scope.row.withdrawStatus) }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="审核备注" prop="auditRemark" min-width="180" show-overflow-tooltip />
|
|
|
+ <el-table-column label="失败原因" prop="failReason" min-width="180" show-overflow-tooltip />
|
|
|
+ <el-table-column label="申请时间" prop="createTime" width="170" />
|
|
|
+ <el-table-column label="审核时间" prop="auditTime" width="170" />
|
|
|
+ <el-table-column label="打款时间" prop="transferTime" width="170" />
|
|
|
+ <el-table-column label="操作" align="center" width="180" fixed="right">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-button
|
|
|
+ v-if="scope.row.withdrawStatus === 0"
|
|
|
+ link
|
|
|
+ type="success"
|
|
|
+ @click="openAuditDialog(scope.row, 'pass')"
|
|
|
+ >
|
|
|
+ 通过
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ v-if="scope.row.withdrawStatus === 0"
|
|
|
+ link
|
|
|
+ type="danger"
|
|
|
+ @click="openAuditDialog(scope.row, 'reject')"
|
|
|
+ >
|
|
|
+ 驳回
|
|
|
+ </el-button>
|
|
|
+ <span v-else>-</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <pagination
|
|
|
+ v-show="total > 0"
|
|
|
+ :total="total"
|
|
|
+ v-model:page="queryParams.pageNum"
|
|
|
+ v-model:limit="queryParams.pageSize"
|
|
|
+ @pagination="getList"
|
|
|
+ />
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <el-dialog v-model="auditDialog.visible" :title="auditDialog.mode === 'pass' ? '通过审核' : '驳回审核'" width="520px">
|
|
|
+ <el-form label-width="80px">
|
|
|
+ <el-form-item label="提现单号">
|
|
|
+ <span>{{ auditDialog.row?.withdrawNo }}</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="提现金额">
|
|
|
+ <span>¥ {{ Number(auditDialog.row?.withdrawAmount || 0).toFixed(2) }}</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item :label="auditDialog.mode === 'pass' ? '备注' : '驳回原因'" required>
|
|
|
+ <el-input
|
|
|
+ v-model="auditDialog.remark"
|
|
|
+ type="textarea"
|
|
|
+ :rows="4"
|
|
|
+ :placeholder="auditDialog.mode === 'pass' ? '请输入审核备注,选填' : '请输入驳回原因'"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="auditDialog.visible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="submitAudit">确定</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { ref, reactive } from 'vue';
|
|
|
+import { ElMessage } from 'element-plus';
|
|
|
+import { listWithdraw, auditPassWithdraw, auditRejectWithdraw } from '@/api/system/withdraw';
|
|
|
+import type { WithdrawQuery, WithdrawVO } from '@/api/system/withdraw/types';
|
|
|
+
|
|
|
+const loading = ref(false);
|
|
|
+const total = ref(0);
|
|
|
+const withdrawList = ref<WithdrawVO[]>([]);
|
|
|
+const queryRef = ref();
|
|
|
+const dateRange = ref<string[]>([]);
|
|
|
+
|
|
|
+const queryParams = reactive<WithdrawQuery>({
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ withdrawNo: undefined,
|
|
|
+ withdrawStatus: undefined,
|
|
|
+ params: {}
|
|
|
+});
|
|
|
+
|
|
|
+const statusOptions = [
|
|
|
+ { label: '待审核', value: 0 },
|
|
|
+ { label: '审核通过', value: 1 },
|
|
|
+ { label: '打款中', value: 2 },
|
|
|
+ { label: '已完成', value: 3 },
|
|
|
+ { label: '失败', value: 4 },
|
|
|
+ { label: '已拒绝', value: 5 }
|
|
|
+];
|
|
|
+
|
|
|
+const auditDialog = reactive<{
|
|
|
+ visible: boolean;
|
|
|
+ mode: 'pass' | 'reject';
|
|
|
+ row: WithdrawVO | null;
|
|
|
+ remark: string;
|
|
|
+}>({
|
|
|
+ visible: false,
|
|
|
+ mode: 'pass',
|
|
|
+ row: null,
|
|
|
+ remark: ''
|
|
|
+});
|
|
|
+
|
|
|
+const getList = async () => {
|
|
|
+ loading.value = true;
|
|
|
+ try {
|
|
|
+ queryParams.params = {
|
|
|
+ beginTime: dateRange.value?.[0],
|
|
|
+ endTime: dateRange.value?.[1]
|
|
|
+ };
|
|
|
+ const res = await listWithdraw(queryParams);
|
|
|
+ withdrawList.value = res.rows || [];
|
|
|
+ total.value = res.total || 0;
|
|
|
+ } finally {
|
|
|
+ loading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const handleQuery = () => {
|
|
|
+ queryParams.pageNum = 1;
|
|
|
+ getList();
|
|
|
+};
|
|
|
+
|
|
|
+const resetQuery = () => {
|
|
|
+ queryRef.value?.resetFields();
|
|
|
+ dateRange.value = [];
|
|
|
+ queryParams.params = {};
|
|
|
+ handleQuery();
|
|
|
+};
|
|
|
+
|
|
|
+const openAuditDialog = (row: WithdrawVO, mode: 'pass' | 'reject') => {
|
|
|
+ auditDialog.visible = true;
|
|
|
+ auditDialog.mode = mode;
|
|
|
+ auditDialog.row = row;
|
|
|
+ auditDialog.remark = '';
|
|
|
+};
|
|
|
+
|
|
|
+const submitAudit = async () => {
|
|
|
+ if (!auditDialog.row) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (auditDialog.mode === 'reject' && !auditDialog.remark.trim()) {
|
|
|
+ ElMessage.warning('请输入驳回原因');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (auditDialog.mode === 'pass') {
|
|
|
+ await auditPassWithdraw(auditDialog.row.id, auditDialog.remark);
|
|
|
+ ElMessage.success('审核通过成功');
|
|
|
+ } else {
|
|
|
+ await auditRejectWithdraw(auditDialog.row.id, auditDialog.remark);
|
|
|
+ ElMessage.success('驳回成功');
|
|
|
+ }
|
|
|
+
|
|
|
+ auditDialog.visible = false;
|
|
|
+ await getList();
|
|
|
+};
|
|
|
+
|
|
|
+const getStatusLabel = (status?: number) => {
|
|
|
+ return statusOptions.find((item) => item.value === status)?.label || '未知';
|
|
|
+};
|
|
|
+
|
|
|
+const getStatusTagType = (status?: number) => {
|
|
|
+ const map: Record<number, string> = {
|
|
|
+ 0: 'warning',
|
|
|
+ 1: 'primary',
|
|
|
+ 2: 'info',
|
|
|
+ 3: 'success',
|
|
|
+ 4: 'danger',
|
|
|
+ 5: 'danger'
|
|
|
+ };
|
|
|
+ return map[status || 0] || 'info';
|
|
|
+};
|
|
|
+
|
|
|
+const getAccountTypeLabel = (type?: number) => {
|
|
|
+ if (type === 2) return '微信';
|
|
|
+ if (type === 1) return '支付宝';
|
|
|
+ return '-';
|
|
|
+};
|
|
|
+
|
|
|
+getList();
|
|
|
+</script>
|