391 行
13 KiB
PHP
391 行
13 KiB
PHP
<?php
|
||
|
||
namespace Retail\Controller;
|
||
|
||
use Think\Controller;
|
||
|
||
/**
|
||
* 骑手提现管理控制器
|
||
* Class RiderWithdrawController
|
||
* @package Retail\Controller
|
||
*/
|
||
class RiderWithdrawController extends BaseController
|
||
{
|
||
|
||
/**
|
||
* 提现管理主页
|
||
*/
|
||
public function index()
|
||
{
|
||
$this->display();
|
||
}
|
||
|
||
/**
|
||
* 提现详情页面
|
||
*/
|
||
public function detail()
|
||
{
|
||
$this->display();
|
||
}
|
||
|
||
/**
|
||
* 审核页面
|
||
*/
|
||
public function audit()
|
||
{
|
||
$this->display();
|
||
}
|
||
|
||
/**
|
||
* 获取提现申请列表
|
||
*/
|
||
public function getWithdrawList()
|
||
{
|
||
try {
|
||
$page = I('get.page', 1, 'intval');
|
||
$pageSize = I('get.pageSize', 20, 'intval');
|
||
$keyword = I('get.keyword', '', 'trim');
|
||
$status = I('get.status', '', 'trim');
|
||
$startTime = I('get.start_time', '', 'trim');
|
||
$endTime = I('get.end_time', '', 'trim');
|
||
|
||
$where = array();
|
||
|
||
// 关键词搜索(骑手姓名或手机号)
|
||
if (!empty($keyword)) {
|
||
$riderIds = M('RiderInfo')->where("rider_name LIKE '%{$keyword}%' OR rider_phone LIKE '%{$keyword}%'")->getField('id', true);
|
||
if ($riderIds) {
|
||
$where['rider_id'] = array('in', $riderIds);
|
||
} else {
|
||
$where['rider_id'] = 0; // 没有匹配的骑手
|
||
}
|
||
}
|
||
|
||
// 状态筛选
|
||
if (!empty($status)) {
|
||
$where['status'] = $status;
|
||
}
|
||
|
||
// 时间筛选
|
||
if (!empty($startTime)) {
|
||
$where['add_time'][] = array('egt', $startTime);
|
||
}
|
||
if (!empty($endTime)) {
|
||
$where['add_time'][] = array('elt', $endTime . ' 23:59:59');
|
||
}
|
||
|
||
$RiderWithdraw = M('RiderWithdraw');
|
||
|
||
// 获取总数
|
||
$total = $RiderWithdraw->where($where)->count();
|
||
|
||
// 获取列表数据
|
||
$list = $RiderWithdraw->alias('w')
|
||
->join('LEFT JOIN ls_rider_info r ON w.rider_id = r.id')
|
||
->field('w.*, r.rider_name, r.rider_phone, r.rider_avatar')
|
||
->where($where)
|
||
->order('w.add_time DESC')
|
||
->page($page, $pageSize)
|
||
->select();
|
||
|
||
// 格式化数据
|
||
foreach ($list as &$item) {
|
||
$item['create_time_format'] = $item['add_time'];
|
||
$item['update_time_format'] = $item['process_time'] ? $item['process_time'] : '';
|
||
$item['status_text'] = $this->getStatusText($item['status']);
|
||
$item['amount_format'] = number_format($item['amount'], 2);
|
||
}
|
||
|
||
$result = array(
|
||
'code' => 0,
|
||
'msg' => 'success',
|
||
'data' => array(
|
||
'list' => $list,
|
||
'total' => $total,
|
||
'page' => $page,
|
||
'pageSize' => $pageSize
|
||
)
|
||
);
|
||
|
||
$this->ajaxReturn($result);
|
||
} catch (\Exception $e) {
|
||
$this->ajaxReturn(array('code' => 1, 'msg' => $e->getMessage()));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 审核提现申请
|
||
*/
|
||
public function auditWithdraw()
|
||
{
|
||
$id = I('post.id', 0, 'intval');
|
||
$status = I('post.status', 0, 'intval'); // 前端传递:1=通过, 2=拒绝
|
||
$remark = I('post.remark', '', 'trim');
|
||
|
||
if (empty($id)) {
|
||
$this->ajaxReturn(array('code' => 1, 'msg' => '参数错误'));
|
||
}
|
||
|
||
if (!in_array($status, [1, 2])) {
|
||
$this->ajaxReturn(array('code' => 1, 'msg' => '审核状态错误'));
|
||
}
|
||
|
||
$RiderWithdraw = M('RiderWithdraw');
|
||
$withdraw = $RiderWithdraw->where(array('id' => $id))->find();
|
||
|
||
if (!$withdraw) {
|
||
$this->ajaxReturn(array('code' => 1, 'msg' => '提现记录不存在'));
|
||
}
|
||
|
||
if ($withdraw['status'] != 0) {
|
||
$this->ajaxReturn(array('code' => 1, 'msg' => '该申请已处理'));
|
||
}
|
||
|
||
// 开始事务
|
||
$RiderWithdraw->startTrans();
|
||
|
||
try {
|
||
// 更新提现记录
|
||
$updateData = array(
|
||
'status' => $status,
|
||
'reject_reason' => $remark,
|
||
'process_time' => date('Y-m-d H:i:s'),
|
||
'complete_time' => $status == 1 ? date('Y-m-d H:i:s') : ''
|
||
);
|
||
|
||
$result = $RiderWithdraw->where(array('id' => $id))->save($updateData);
|
||
|
||
if (!$result) {
|
||
throw new \Exception('更新提现记录失败');
|
||
}
|
||
|
||
// 处理余额变动
|
||
$RiderInfo = M('RiderInfo');
|
||
$rider = $RiderInfo->where(array('id' => $withdraw['rider_id']))->find();
|
||
|
||
if ($rider) {
|
||
if ($status == 1) {
|
||
// 通过:从冻结余额中扣除
|
||
$newFrozenBalance = $rider['frozen_balance'] - $withdraw['amount'];
|
||
$updateResult = $RiderInfo->where(array('id' => $withdraw['rider_id']))->save(array(
|
||
'frozen_balance' => $newFrozenBalance
|
||
));
|
||
|
||
if (!$updateResult) {
|
||
throw new \Exception('更新冻结余额失败');
|
||
}
|
||
} else if ($status == 2) {
|
||
// 拒绝:从冻结余额退回到可用余额
|
||
$newBalance = $rider['balance'] + $withdraw['amount'];
|
||
$newFrozenBalance = $rider['frozen_balance'] - $withdraw['amount'];
|
||
$updateResult = $RiderInfo->where(array('id' => $withdraw['rider_id']))->save(array(
|
||
'balance' => $newBalance,
|
||
'frozen_balance' => $newFrozenBalance
|
||
));
|
||
|
||
if (!$updateResult) {
|
||
throw new \Exception('退还金额失败');
|
||
}
|
||
|
||
// 记录余额变动
|
||
$balanceLog = array(
|
||
'rider_id' => $withdraw['rider_id'],
|
||
'type' => 'withdraw_reject',
|
||
'amount' => $withdraw['amount'],
|
||
'balance_before' => $rider['balance'],
|
||
'balance_after' => $newBalance,
|
||
'description' => '提现申请被拒绝,退还金额',
|
||
'add_time' => date('Y-m-d H:i:s')
|
||
);
|
||
M('RiderBalanceLog')->add($balanceLog);
|
||
}
|
||
}
|
||
|
||
$RiderWithdraw->commit();
|
||
|
||
$this->ajaxReturn(array('code' => 0, 'msg' => '操作成功'));
|
||
} catch (\Exception $e) {
|
||
$RiderWithdraw->rollback();
|
||
$this->ajaxReturn(array('code' => 1, 'msg' => $e->getMessage()));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取提现详情
|
||
*/
|
||
public function getWithdrawDetail()
|
||
{
|
||
try {
|
||
$id = I('get.id', 0, 'intval');
|
||
|
||
if (empty($id)) {
|
||
$this->ajaxReturn(array('code' => 1, 'msg' => '参数错误'));
|
||
}
|
||
|
||
$detail = M('RiderWithdraw')->alias('w')
|
||
->join('LEFT JOIN ls_rider_info r ON w.rider_id = r.id')
|
||
->field('w.*, r.rider_name, r.rider_phone, r.rider_avatar, r.id_card')
|
||
->where(array('w.id' => $id))
|
||
->find();
|
||
|
||
if (!$detail) {
|
||
$this->ajaxReturn(array('code' => 1, 'msg' => '记录不存在'));
|
||
}
|
||
|
||
// 格式化数据
|
||
$detail['create_time_format'] = $detail['add_time'];
|
||
$detail['update_time_format'] = $detail['process_time'] ? $detail['process_time'] : '';
|
||
$detail['audit_time_format'] = $detail['complete_time'] ? $detail['complete_time'] : '';
|
||
$detail['status_text'] = $this->getStatusText($detail['status']);
|
||
$detail['amount_format'] = number_format($detail['amount'], 2);
|
||
|
||
$this->ajaxReturn(array('code' => 0, 'msg' => 'success', 'data' => $detail));
|
||
} catch (\Exception $e) {
|
||
$this->ajaxReturn(array('code' => 1, 'msg' => $e->getMessage()));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 导出提现记录
|
||
*/
|
||
public function exportWithdraw()
|
||
{
|
||
$keyword = I('get.keyword', '', 'trim');
|
||
$status = I('get.status', '', 'trim');
|
||
$startTime = I('get.start_time', '', 'trim');
|
||
$endTime = I('get.end_time', '', 'trim');
|
||
|
||
$where = array();
|
||
|
||
// 构建查询条件(与列表查询相同)
|
||
if (!empty($keyword)) {
|
||
$riderIds = M('RiderInfo')->where("rider_name LIKE '%{$keyword}%' OR rider_phone LIKE '%{$keyword}%'")->getField('id', true);
|
||
if ($riderIds) {
|
||
$where['rider_id'] = array('in', $riderIds);
|
||
} else {
|
||
$where['rider_id'] = 0;
|
||
}
|
||
}
|
||
|
||
if (!empty($status)) {
|
||
$where['status'] = $status;
|
||
}
|
||
|
||
if (!empty($startTime)) {
|
||
$where['add_time'][] = array('egt', $startTime);
|
||
}
|
||
if (!empty($endTime)) {
|
||
$where['add_time'][] = array('elt', $endTime . ' 23:59:59');
|
||
}
|
||
|
||
// 获取数据
|
||
$list = M('RiderWithdraw')->alias('w')
|
||
->join('LEFT JOIN ls_rider_info r ON w.rider_id = r.id')
|
||
->field('w.*, r.rider_name, r.rider_phone')
|
||
->where($where)
|
||
->order('w.add_time DESC')
|
||
->select();
|
||
|
||
// 设置Excel头部
|
||
header('Content-Type: application/vnd.ms-excel');
|
||
header('Content-Disposition: attachment;filename="rider_withdraw_' . date('YmdHis') . '.xls"');
|
||
header('Cache-Control: max-age=0');
|
||
|
||
// 输出Excel内容
|
||
echo '<table border="1">';
|
||
echo '<tr>';
|
||
echo '<th>提现ID</th>';
|
||
echo '<th>骑手姓名</th>';
|
||
echo '<th>手机号</th>';
|
||
echo '<th>真实姓名</th>';
|
||
echo '<th>提现金额</th>';
|
||
echo '<th>银行卡号</th>';
|
||
echo '<th>开户行</th>';
|
||
echo '<th>状态</th>';
|
||
echo '<th>申请时间</th>';
|
||
echo '<th>审核时间</th>';
|
||
echo '<th>备注</th>';
|
||
echo '</tr>';
|
||
|
||
foreach ($list as $item) {
|
||
echo '<tr>';
|
||
echo '<td>' . $item['id'] . '</td>';
|
||
echo '<td>' . $item['rider_name'] . '</td>';
|
||
echo '<td>' . $item['rider_phone'] . '</td>';
|
||
echo '<td>' . $item['rider_name'] . '</td>';
|
||
echo '<td>' . number_format($item['amount'], 2) . '</td>';
|
||
echo '<td>' . $item['account_number'] . '</td>';
|
||
echo '<td>' . $item['bank_name'] . '</td>';
|
||
echo '<td>' . $this->getStatusText($item['status']) . '</td>';
|
||
echo '<td>' . $item['add_time'] . '</td>';
|
||
echo '<td>' . ($item['complete_time'] ? $item['complete_time'] : '') . '</td>';
|
||
echo '<td>' . $item['reject_reason'] . '</td>';
|
||
echo '</tr>';
|
||
}
|
||
|
||
echo '</table>';
|
||
exit;
|
||
}
|
||
|
||
/**
|
||
* 获取状态文本
|
||
*/
|
||
private function getStatusText($status)
|
||
{
|
||
$statusMap = array(
|
||
0 => '申请中',
|
||
1 => '已完成',
|
||
2 => '已拒绝',
|
||
);
|
||
|
||
return isset($statusMap[$status]) ? $statusMap[$status] : '未知';
|
||
}
|
||
|
||
/**
|
||
* 获取提现统计数据
|
||
*/
|
||
public function getWithdrawStats()
|
||
{
|
||
$startTime = I('get.start_time', date('Y-m-01'), 'trim');
|
||
$endTime = I('get.end_time', date('Y-m-d'), 'trim');
|
||
|
||
$where = array();
|
||
$where['add_time'][] = array('egt', $startTime);
|
||
$where['add_time'][] = array('elt', $endTime . ' 23:59:59');
|
||
|
||
$RiderWithdraw = M('RiderWithdraw');
|
||
|
||
// 总申请数
|
||
$totalCount = $RiderWithdraw->where($where)->count();
|
||
|
||
// 申请中数
|
||
$pendingCount = $RiderWithdraw->where(array_merge($where, array('status' => 0)))->count();
|
||
|
||
// 处理中数
|
||
$processingCount = $RiderWithdraw->where(array_merge($where, array('status' => 1)))->count();
|
||
|
||
// 已完成数
|
||
$completedCount = $RiderWithdraw->where(array_merge($where, array('status' => 2)))->count();
|
||
|
||
// 已拒绝数
|
||
$rejectedCount = $RiderWithdraw->where(array_merge($where, array('status' => 3)))->count();
|
||
|
||
// 总金额
|
||
$totalAmount = $RiderWithdraw->where($where)->sum('amount') ?: 0;
|
||
|
||
// 已完成金额
|
||
$completedAmount = $RiderWithdraw->where(array_merge($where, array('status' => 2)))->sum('amount') ?: 0;
|
||
|
||
$stats = array(
|
||
'total_count' => $totalCount,
|
||
'pending_count' => $pendingCount,
|
||
'approved_count' => $completedCount, // 前端期望的字段名
|
||
'rejected_count' => $rejectedCount,
|
||
'total_amount' => number_format($totalAmount, 2),
|
||
'approved_amount' => number_format($completedAmount, 2) // 前端期望的字段名
|
||
);
|
||
|
||
$this->ajaxReturn(array('code' => 0, 'msg' => 'success', 'data' => $stats));
|
||
}
|
||
}
|