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 ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; foreach ($list as $item) { echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; } echo '
提现ID骑手姓名手机号真实姓名提现金额银行卡号开户行状态申请时间审核时间备注
' . $item['id'] . '' . $item['rider_name'] . '' . $item['rider_phone'] . '' . $item['rider_name'] . '' . number_format($item['amount'], 2) . '' . $item['account_number'] . '' . $item['bank_name'] . '' . $this->getStatusText($item['status']) . '' . $item['add_time'] . '' . ($item['complete_time'] ? $item['complete_time'] : '') . '' . $item['reject_reason'] . '
'; 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)); } }