478 行
18 KiB
HTML
478 行
18 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8"/>
|
|
<title>骑手提现管理</title>
|
|
<link rel="stylesheet" type="text/css" href="__PUBLIC__/css/menu.css?v=1.0.5"/>
|
|
<link rel="stylesheet" type="text/css" href="__PUBLIC__/css/minimal-admin.css?v=1.0.0"/>
|
|
<link rel="stylesheet" type="text/css" href="__PUBLIC__/Retail/css/myscroll.css?v=1.0.2"/>
|
|
<link rel="stylesheet" type="text/css" href="__PUBLIC__/layui-v2.4.3/layui/css/layui.css"/>
|
|
<link rel="stylesheet" type="text/css" href="__PUBLIC__/Retail/css/home.css"/>
|
|
<link rel="stylesheet" type="text/css" href="__PUBLIC__/Retail/css/goodsList.css?v=1.0.2"/>
|
|
<link rel="stylesheet" type="text/css" href="__PUBLIC__/vue/element-ui.css?v=2.13.2">
|
|
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
<script type="text/javascript" charset="utf-8" src="__PUBLIC__/vue/js/vue2.5.16.js"></script>
|
|
<script type="text/javascript" charset="utf-8" src="__PUBLIC__/vue/element-ui.js?v=2.13.2"></script>
|
|
<script type="text/javascript" charset="utf-8" src="__PUBLIC__/js/common.js?v=1.0.2"></script>
|
|
<script type="text/javascript" charset="utf-8" src="__PUBLIC__/jquery/js/jquery-3.2.1.min.js"></script>
|
|
<script type="text/javascript" charset="utf-8" src="__PUBLIC__/layui-v2.4.3/layui/layui.js"></script>
|
|
</head>
|
|
<body>
|
|
<div id="RiderWithdrawManagement" v-cloak>
|
|
<div class="goodsBox">
|
|
<div class="goods_title">
|
|
<div class="goods_title_inner">
|
|
<i class="fas fa-money-bill-wave" style="margin-right: 8px; color: #409EFF;"></i>
|
|
骑手提现管理
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 统计卡片区域 -->
|
|
<div class="withdraw-stats-container" style="padding: 20px; background: #f5f7fa;">
|
|
<el-row :gutter="20">
|
|
<el-col :span="4">
|
|
<div class="stat-card">
|
|
<div class="stat-icon" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);">
|
|
<i class="fas fa-list"></i>
|
|
</div>
|
|
<div class="stat-content">
|
|
<div class="stat-number">{{ statistics.total_count }}</div>
|
|
<div class="stat-label">总申请数</div>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="stat-card">
|
|
<div class="stat-icon" style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);">
|
|
<i class="fas fa-clock"></i>
|
|
</div>
|
|
<div class="stat-content">
|
|
<div class="stat-number">{{ statistics.pending_count }}</div>
|
|
<div class="stat-label">待审核</div>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="stat-card">
|
|
<div class="stat-icon" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);">
|
|
<i class="fas fa-check-circle"></i>
|
|
</div>
|
|
<div class="stat-content">
|
|
<div class="stat-number">{{ statistics.approved_count }}</div>
|
|
<div class="stat-label">已通过</div>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="stat-card">
|
|
<div class="stat-icon" style="background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);">
|
|
<i class="fas fa-times-circle"></i>
|
|
</div>
|
|
<div class="stat-content">
|
|
<div class="stat-number">{{ statistics.rejected_count }}</div>
|
|
<div class="stat-label">已拒绝</div>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="stat-card">
|
|
<div class="stat-icon" style="background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);">
|
|
<i class="fas fa-dollar-sign"></i>
|
|
</div>
|
|
<div class="stat-content">
|
|
<div class="stat-number">¥{{ statistics.total_amount }}</div>
|
|
<div class="stat-label">总金额</div>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="stat-card">
|
|
<div class="stat-icon" style="background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);">
|
|
<i class="fas fa-hand-holding-usd"></i>
|
|
</div>
|
|
<div class="stat-content">
|
|
<div class="stat-number">¥{{ statistics.approved_amount }}</div>
|
|
<div class="stat-label">已通过金额</div>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
|
|
<!-- 搜索筛选区域 -->
|
|
<div class="search-container" style="padding: 20px; background: white; margin: 20px; border-radius: 8px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);">
|
|
<el-form :inline="true" :model="searchForm" class="search-form">
|
|
<el-form-item>
|
|
<el-input v-model="searchForm.keyword" placeholder="骑手姓名/手机号" clearable style="width: 200px;"></el-input>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-select v-model="searchForm.status" placeholder="请选择状态" clearable style="width: 150px;">
|
|
<el-option label="待审核" value="0"></el-option>
|
|
<el-option label="已通过" value="1"></el-option>
|
|
<el-option label="已拒绝" value="2"></el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-date-picker
|
|
v-model="searchForm.dateRange"
|
|
type="daterange"
|
|
range-separator="至"
|
|
start-placeholder="开始日期"
|
|
end-placeholder="结束日期"
|
|
format="yyyy-MM-dd"
|
|
value-format="yyyy-MM-dd"
|
|
style="width: 240px;">
|
|
</el-date-picker>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button type="primary" @click="searchWithdraw" icon="el-icon-search">搜索</el-button>
|
|
<el-button @click="resetSearch" icon="el-icon-refresh">重置</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
</div>
|
|
|
|
<!-- 提现列表 -->
|
|
<div class="table-container" style="margin: 20px; background: white; border-radius: 8px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);">
|
|
<el-table :data="withdrawList" v-loading="loading" style="width: 100%;" stripe>
|
|
<el-table-column prop="id" label="提现ID" width="80" align="center"></el-table-column>
|
|
<el-table-column label="骑手信息" width="200">
|
|
<template slot-scope="scope">
|
|
<div style="display: flex; align-items: center;">
|
|
<el-avatar :src="scope.row.rider_avatar" size="small" style="margin-right: 10px;">
|
|
<i class="el-icon-user-solid"></i>
|
|
</el-avatar>
|
|
<div>
|
|
<div style="font-weight: bold;">{{ scope.row.rider_name }}</div>
|
|
<div style="color: #999; font-size: 12px;">{{ scope.row.rider_phone }}</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="amount_format" label="提现金额" width="120" align="center">
|
|
<template slot-scope="scope">
|
|
<span style="color: #f56c6c; font-weight: bold;">¥{{ scope.row.amount_format }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="fee" label="手续费" width="120" align="center">
|
|
<template slot-scope="scope">
|
|
<span style="color: #f56c6c; font-weight: bold;">¥{{ scope.row.fee }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="actual_amount" label="实际到账金额" width="120" align="center">
|
|
<template slot-scope="scope">
|
|
<span style="color: #f56c6c; font-weight: bold;">¥{{ scope.row.actual_amount }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="打款账号" width="200">
|
|
<template slot-scope="scope">
|
|
<div>
|
|
<div style="display: flex; align-items: center; margin-bottom: 4px;">
|
|
<i :class="getWithdrawTypeIcon(scope.row.withdraw_type)" style="margin-right: 5px; color: #409EFF;"></i>
|
|
<span style="font-weight: bold;">{{ getWithdrawTypeName(scope.row.withdraw_type) }}</span>
|
|
</div>
|
|
<div style="color: #666; font-size: 12px;">{{ scope.row.account_name }}</div>
|
|
<div style="color: #999; font-size: 12px;">{{ scope.row.account_number }}</div>
|
|
<div v-if="scope.row.withdraw_type == 1 && scope.row.bank_name" style="color: #999; font-size: 11px;">{{ scope.row.bank_name }}</div>
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="status_text" label="状态" width="100" align="center">
|
|
<template slot-scope="scope">
|
|
<el-tag :type="getStatusType(scope.row.status)">{{ scope.row.status_text }}</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="create_time_format" label="申请时间" width="160" align="center"></el-table-column>
|
|
<el-table-column prop="update_time_format" label="处理时间" width="160" align="center"></el-table-column>
|
|
<el-table-column label="操作" width="200" align="center">
|
|
<template slot-scope="scope">
|
|
<el-link size="mini" @click="viewDetail(scope.row)" icon="el-icon-view">详情</el-link>
|
|
<el-link v-if="scope.row.status == 0" size="mini" type="success" @click="auditWithdraw(scope.row, 1)" icon="el-icon-check">通过</el-link>
|
|
<el-link v-if="scope.row.status == 0" size="mini" type="danger" @click="auditWithdraw(scope.row, 2)" icon="el-icon-close">拒绝</el-link>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
|
|
<!-- 分页 -->
|
|
<div style="padding: 20px; text-align: center;">
|
|
<el-pagination
|
|
@size-change="handleSizeChange"
|
|
@current-change="handleCurrentChange"
|
|
:current-page="pagination.page"
|
|
:page-sizes="[10, 20, 50, 100]"
|
|
:page-size="pagination.pageSize"
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
:total="+pagination.total">
|
|
</el-pagination>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<style>
|
|
.stat-card {
|
|
background: white;
|
|
border-radius: 12px;
|
|
padding: 20px;
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
display: flex;
|
|
align-items: center;
|
|
transition: transform 0.3s ease;
|
|
}
|
|
|
|
.stat-card:hover {
|
|
transform: translateY(-5px);
|
|
}
|
|
|
|
.stat-icon {
|
|
width: 60px;
|
|
height: 60px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 15px;
|
|
}
|
|
|
|
.stat-icon i {
|
|
font-size: 24px;
|
|
color: white;
|
|
}
|
|
|
|
.stat-content {
|
|
flex: 1;
|
|
}
|
|
|
|
.stat-number {
|
|
font-size: 24px;
|
|
font-weight: bold;
|
|
color: #303133;
|
|
margin-bottom: 5px;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 14px;
|
|
color: #909399;
|
|
}
|
|
|
|
.search-form .el-form-item {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
[v-cloak] {
|
|
display: none;
|
|
}
|
|
.el-date-editor .el-range__icon, .el-date-editor .el-range__close-icon {
|
|
line-height: 14px !important;
|
|
}
|
|
.el-date-editor .el-range-separator {
|
|
line-height: 16px !important;
|
|
width: 13% !important;
|
|
}
|
|
.el-input--prefix .el-input__inner {
|
|
padding-left: 30px !important;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
new Vue({
|
|
el: '#RiderWithdrawManagement',
|
|
data() {
|
|
return {
|
|
loading: false,
|
|
withdrawList: [],
|
|
statistics: {
|
|
total_count: 0,
|
|
pending_count: 0,
|
|
approved_count: 0,
|
|
rejected_count: 0,
|
|
total_amount: '0.00',
|
|
approved_amount: '0.00'
|
|
},
|
|
searchForm: {
|
|
keyword: '',
|
|
status: '',
|
|
dateRange: []
|
|
},
|
|
pagination: {
|
|
page: 1,
|
|
pageSize: 20,
|
|
total: 0
|
|
},
|
|
}
|
|
},
|
|
mounted() {
|
|
this.loadWithdrawList();
|
|
this.loadStatistics();
|
|
},
|
|
methods: {
|
|
// 加载提现列表
|
|
loadWithdrawList() {
|
|
this.loading = true;
|
|
let params = {
|
|
page: this.pagination.page,
|
|
pageSize: this.pagination.pageSize,
|
|
keyword: this.searchForm.keyword,
|
|
status: this.searchForm.status
|
|
};
|
|
|
|
if (this.searchForm.dateRange && this.searchForm.dateRange.length === 2) {
|
|
params.start_time = this.searchForm.dateRange[0];
|
|
params.end_time = this.searchForm.dateRange[1];
|
|
}
|
|
|
|
$.get('/index.php/Retail/RiderWithdraw/getWithdrawList', params, (res) => {
|
|
this.loading = false;
|
|
if (res.code === 0) {
|
|
this.withdrawList = res.data.list;
|
|
this.pagination.total = res.data.total;
|
|
} else {
|
|
this.$message.error(res.msg);
|
|
}
|
|
});
|
|
},
|
|
|
|
// 加载统计数据
|
|
loadStatistics() {
|
|
let params = {};
|
|
if (this.searchForm.dateRange && this.searchForm.dateRange.length === 2) {
|
|
params.start_time = this.searchForm.dateRange[0];
|
|
params.end_time = this.searchForm.dateRange[1];
|
|
}
|
|
|
|
$.get('/index.php/Retail/RiderWithdraw/getWithdrawStats', params, (res) => {
|
|
if (res.code === 0) {
|
|
this.statistics = res.data;
|
|
}
|
|
});
|
|
},
|
|
|
|
// 搜索
|
|
searchWithdraw() {
|
|
this.pagination.page = 1;
|
|
this.loadWithdrawList();
|
|
this.loadStatistics();
|
|
},
|
|
|
|
// 重置搜索
|
|
resetSearch() {
|
|
this.searchForm = {
|
|
keyword: '',
|
|
status: '',
|
|
dateRange: []
|
|
};
|
|
this.pagination.page = 1;
|
|
this.loadWithdrawList();
|
|
this.loadStatistics();
|
|
},
|
|
|
|
|
|
// 查看详情
|
|
viewDetail(row) {
|
|
layer.open({
|
|
type: 2,
|
|
title: '提现详情',
|
|
content: '/index.php/Retail/RiderWithdraw/detail?id=' + row.id,
|
|
area: ['800px', '600px'],
|
|
offset: 'auto'
|
|
});
|
|
},
|
|
|
|
// 审核提现
|
|
auditWithdraw(row, status) {
|
|
const that = this;
|
|
|
|
if (status === 1) {
|
|
// 通过:直接询问确认
|
|
layer.confirm('确定要通过这个提现申请吗?', {
|
|
icon: 3,
|
|
title: '确认通过'
|
|
}, function(index) {
|
|
// 确认通过,直接调用接口
|
|
that.confirmAudit(row.id, status, '');
|
|
layer.close(index);
|
|
});
|
|
} else {
|
|
// 拒绝:弹出填写拒绝原因的弹窗
|
|
const url = '/index.php/Retail/RiderWithdraw/audit?id=' + row.id + '&status=' + status;
|
|
|
|
layer.open({
|
|
type: 2,
|
|
title: '拒绝提现申请',
|
|
content: url,
|
|
area: ['500px', '270px'],
|
|
offset: 'auto',
|
|
end: function() {
|
|
// 关闭弹窗时刷新列表
|
|
that.loadWithdrawList();
|
|
that.loadStatistics();
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
// 确认审核(新增方法)
|
|
confirmAudit(withdrawId, status, remark) {
|
|
$.post('/index.php/Retail/RiderWithdraw/auditWithdraw', {
|
|
id: withdrawId,
|
|
status: status,
|
|
remark: remark
|
|
}, (res) => {
|
|
if (res.code === 0) {
|
|
this.$message.success('操作成功');
|
|
this.loadWithdrawList();
|
|
this.loadStatistics();
|
|
} else {
|
|
this.$message.error(res.msg);
|
|
}
|
|
});
|
|
},
|
|
|
|
// 获取状态类型
|
|
getStatusType(status) {
|
|
const typeMap = {
|
|
0: 'warning',
|
|
1: 'success',
|
|
2: 'danger'
|
|
};
|
|
return typeMap[+status] || 'info';
|
|
},
|
|
|
|
// 获取提现方式名称
|
|
getWithdrawTypeName(type) {
|
|
const typeMap = {
|
|
1: '银行卡',
|
|
2: '支付宝',
|
|
3: '微信'
|
|
};
|
|
return typeMap[type] || '未知';
|
|
},
|
|
|
|
// 获取提现方式图标
|
|
getWithdrawTypeIcon(type) {
|
|
const iconMap = {
|
|
1: 'el-icon-bank-card',
|
|
2: 'el-icon-wallet',
|
|
3: 'el-icon-chat-dot-round'
|
|
};
|
|
return iconMap[type] || 'el-icon-question';
|
|
},
|
|
|
|
|
|
// 分页大小改变
|
|
handleSizeChange(val) {
|
|
this.pagination.pageSize = val;
|
|
this.pagination.page = 1;
|
|
this.loadWithdrawList();
|
|
},
|
|
|
|
// 当前页改变
|
|
handleCurrentChange(val) {
|
|
this.pagination.page = val;
|
|
this.loadWithdrawList();
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |