display(); } /** * 获取申诉列表 */ public function getAppealList() { $page = I('page', 1, 'intval'); $pageSize = I('pageSize', 20, 'intval'); $keyword = I('keyword', '', 'trim'); $status = I('status', '', 'trim'); $type = I('type', '', 'trim'); $start_time = I('start_time', '', 'trim'); $end_time = I('end_time', '', 'trim'); $where = array(); // 关键词搜索(骑手姓名、手机号、订单号) if (!empty($keyword)) { $where['_string'] = "(u.nickname LIKE '%{$keyword}%' OR u.phone LIKE '%{$keyword}%' OR a.order_no LIKE '%{$keyword}%')"; } // 状态筛选 if ($status !== '') { $where['a.status'] = $status; } // 申诉类型筛选 if ($type !== '') { $where['a.appeal_type'] = $type; } // 时间范围筛选 if (!empty($start_time)) { $where['a.create_time'] = array('egt', strtotime($start_time . ' 00:00:00')); } if (!empty($end_time)) { $where['a.create_time'] = array('elt', strtotime($end_time . ' 23:59:59')); } $model = M('rider_appeal'); $total = $model->alias('a') ->join('ls_users u ON a.rider_id = u.id') ->where($where) ->count(); $list = $model->alias('a') ->field('a.*, u.nickname, u.phone, u.avatar') ->join('ls_users u ON a.rider_id = u.id') ->where($where) ->order('a.create_time desc') ->page($page, $pageSize) ->select(); // 格式化数据 foreach ($list as &$item) { $item['status_text'] = $this->getStatusText($item['status']); $item['appeal_type_text'] = $this->getAppealTypeText($item['appeal_type']); $item['create_time_format'] = date('Y-m-d H:i:s', $item['create_time']); $item['handle_time_format'] = $item['handle_time'] ? date('Y-m-d H:i:s', $item['handle_time']) : ''; // 获取订单信息 if (!empty($item['order_no'])) { $order = M('order')->where(array('order_no' => $item['order_no']))->find(); $item['order_info'] = $order; } } $this->ajaxReturn(array( 'code' => 0, 'msg' => 'success', 'data' => array( 'list' => $list, 'total' => $total ) )); } /** * 获取申诉详情 */ public function getAppealDetail() { $id = I('id', 0, 'intval'); if (empty($id)) { $this->ajaxReturn(array('code' => 1, 'msg' => '参数错误')); } $detail = M('rider_appeal')->alias('a') ->field('a.*, u.nickname, u.phone, u.avatar') ->join('ls_users u ON a.rider_id = u.id') ->where(array('a.id' => $id)) ->find(); if (empty($detail)) { $this->ajaxReturn(array('code' => 1, 'msg' => '申诉不存在')); } // 格式化数据 $detail['status_text'] = $this->getStatusText($detail['status']); $detail['appeal_type_text'] = $this->getAppealTypeText($detail['appeal_type']); $detail['create_time_format'] = date('Y-m-d H:i:s', $detail['create_time']); $detail['handle_time_format'] = $detail['handle_time'] ? date('Y-m-d H:i:s', $detail['handle_time']) : ''; // 获取订单详情 if (!empty($detail['order_no'])) { $order = M('order')->where(array('order_no' => $detail['order_no']))->find(); $detail['order_info'] = $order; } // 获取申诉图片 if (!empty($detail['images'])) { $detail['image_list'] = explode(',', $detail['images']); } else { $detail['image_list'] = array(); } // 获取处理记录 $handle_logs = M('rider_appeal_log') ->where(array('appeal_id' => $id)) ->order('create_time desc') ->select(); $detail['handle_logs'] = $handle_logs; $this->ajaxReturn(array( 'code' => 0, 'msg' => 'success', 'data' => $detail )); } /** * 处理申诉 */ public function handleAppeal() { $id = I('id', 0, 'intval'); $status = I('status', 0, 'intval'); // 1:通过 2:驳回 $handle_remark = I('handle_remark', '', 'trim'); $compensation_amount = I('compensation_amount', 0, 'floatval'); if (empty($id)) { $this->ajaxReturn(array('code' => 1, 'msg' => '参数错误')); } if (!in_array($status, array(1, 2))) { $this->ajaxReturn(array('code' => 1, 'msg' => '处理状态错误')); } if (empty($handle_remark)) { $this->ajaxReturn(array('code' => 1, 'msg' => '处理说明不能为空')); } // 获取申诉信息 $appeal = M('rider_appeal')->where(array('id' => $id))->find(); if (empty($appeal)) { $this->ajaxReturn(array('code' => 1, 'msg' => '申诉不存在')); } if ($appeal['status'] != 0) { $this->ajaxReturn(array('code' => 1, 'msg' => '该申诉已处理')); } // 开启事务 M()->startTrans(); try { // 更新申诉状态 $update_data = array( 'status' => $status, 'handle_remark' => $handle_remark, 'handle_time' => time(), 'handler_id' => session('admin_id') ); if ($status == 1 && $compensation_amount > 0) { $update_data['compensation_amount'] = $compensation_amount; } $result = M('rider_appeal')->where(array('id' => $id))->save($update_data); if (!$result) { throw new \Exception('更新申诉状态失败'); } // 记录处理日志 $log_data = array( 'appeal_id' => $id, 'handler_id' => session('admin_id'), 'action' => $status == 1 ? 'approve' : 'reject', 'remark' => $handle_remark, 'create_time' => time() ); M('rider_appeal_log')->add($log_data); // 如果申诉通过且有补偿金额,增加骑手余额 if ($status == 1 && $compensation_amount > 0) { $rider_id = $appeal['rider_id']; // 更新骑手余额 $balance_result = M('users')->where(array('id' => $rider_id)) ->setInc('balance', $compensation_amount); if (!$balance_result) { throw new \Exception('更新骑手余额失败'); } // 记录余额变动 $balance_log = array( 'user_id' => $rider_id, 'type' => 'appeal_compensation', 'amount' => $compensation_amount, 'balance_before' => M('users')->where(array('id' => $rider_id))->getField('balance') - $compensation_amount, 'balance_after' => M('users')->where(array('id' => $rider_id))->getField('balance'), 'remark' => '申诉补偿:' . $appeal['appeal_reason'], 'create_time' => time() ); M('balance_log')->add($balance_log); } M()->commit(); $this->ajaxReturn(array('code' => 0, 'msg' => '处理成功')); } catch (\Exception $e) { M()->rollback(); $this->ajaxReturn(array('code' => 1, 'msg' => $e->getMessage())); } } /** * 批量处理申诉 */ public function batchHandle() { $ids = I('ids', '', 'trim'); $status = I('status', 0, 'intval'); $handle_remark = I('handle_remark', '', 'trim'); if (empty($ids)) { $this->ajaxReturn(array('code' => 1, 'msg' => '请选择要处理的申诉')); } if (!in_array($status, array(1, 2))) { $this->ajaxReturn(array('code' => 1, 'msg' => '处理状态错误')); } if (empty($handle_remark)) { $this->ajaxReturn(array('code' => 1, 'msg' => '处理说明不能为空')); } $id_array = explode(',', $ids); $success_count = 0; foreach ($id_array as $id) { $id = intval($id); if ($id <= 0) continue; // 检查申诉状态 $appeal = M('rider_appeal')->where(array('id' => $id))->find(); if (empty($appeal) || $appeal['status'] != 0) { continue; } // 更新申诉状态 $update_data = array( 'status' => $status, 'handle_remark' => $handle_remark, 'handle_time' => time(), 'handler_id' => session('admin_id') ); $result = M('rider_appeal')->where(array('id' => $id))->save($update_data); if ($result) { // 记录处理日志 $log_data = array( 'appeal_id' => $id, 'handler_id' => session('admin_id'), 'action' => $status == 1 ? 'approve' : 'reject', 'remark' => $handle_remark, 'create_time' => time() ); M('rider_appeal_log')->add($log_data); $success_count++; } } $this->ajaxReturn(array( 'code' => 0, 'msg' => "批量处理完成,成功处理{$success_count}条申诉" )); } /** * 导出申诉数据 */ public function exportAppeal() { $keyword = I('keyword', '', 'trim'); $status = I('status', '', 'trim'); $type = I('type', '', 'trim'); $start_time = I('start_time', '', 'trim'); $end_time = I('end_time', '', 'trim'); $where = array(); if (!empty($keyword)) { $where['_string'] = "(u.nickname LIKE '%{$keyword}%' OR u.phone LIKE '%{$keyword}%' OR a.order_no LIKE '%{$keyword}%')"; } if ($status !== '') { $where['a.status'] = $status; } if ($type !== '') { $where['a.appeal_type'] = $type; } if (!empty($start_time)) { $where['a.create_time'] = array('egt', strtotime($start_time . ' 00:00:00')); } if (!empty($end_time)) { $where['a.create_time'] = array('elt', strtotime($end_time . ' 23:59:59')); } $list = M('rider_appeal')->alias('a') ->field('a.*, u.nickname, u.phone') ->join('ls_users u ON a.rider_id = u.id') ->where($where) ->order('a.create_time desc') ->select(); // 导出Excel vendor('PHPExcel.PHPExcel'); $objPHPExcel = new \PHPExcel(); $objPHPExcel->setActiveSheetIndex(0); $objActSheet = $objPHPExcel->getActiveSheet(); // 设置表头 $objActSheet->setCellValue('A1', '申诉ID'); $objActSheet->setCellValue('B1', '骑手姓名'); $objActSheet->setCellValue('C1', '手机号'); $objActSheet->setCellValue('D1', '申诉类型'); $objActSheet->setCellValue('E1', '订单号'); $objActSheet->setCellValue('F1', '申诉原因'); $objActSheet->setCellValue('G1', '申诉描述'); $objActSheet->setCellValue('H1', '状态'); $objActSheet->setCellValue('I1', '处理说明'); $objActSheet->setCellValue('J1', '补偿金额'); $objActSheet->setCellValue('K1', '申诉时间'); $objActSheet->setCellValue('L1', '处理时间'); // 填充数据 $row = 2; foreach ($list as $item) { $objActSheet->setCellValue('A' . $row, $item['id']); $objActSheet->setCellValue('B' . $row, $item['nickname']); $objActSheet->setCellValue('C' . $row, $item['phone']); $objActSheet->setCellValue('D' . $row, $this->getAppealTypeText($item['appeal_type'])); $objActSheet->setCellValue('E' . $row, $item['order_no']); $objActSheet->setCellValue('F' . $row, $item['appeal_reason']); $objActSheet->setCellValue('G' . $row, $item['appeal_content']); $objActSheet->setCellValue('H' . $row, $this->getStatusText($item['status'])); $objActSheet->setCellValue('I' . $row, $item['handle_remark']); $objActSheet->setCellValue('J' . $row, $item['compensation_amount']); $objActSheet->setCellValue('K' . $row, date('Y-m-d H:i:s', $item['create_time'])); $objActSheet->setCellValue('L' . $row, $item['handle_time'] ? date('Y-m-d H:i:s', $item['handle_time']) : ''); $row++; } $filename = '骑手申诉记录_' . date('YmdHis') . '.xlsx'; header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header('Content-Disposition: attachment;filename="' . $filename . '"'); header('Cache-Control: max-age=0'); $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save('php://output'); exit; } /** * 获取申诉统计 */ public function getAppealStats() { $start_time = I('start_time', '', 'trim'); $end_time = I('end_time', '', 'trim'); $where = array(); if (!empty($start_time)) { $where['create_time'] = array('egt', strtotime($start_time . ' 00:00:00')); } if (!empty($end_time)) { $where['create_time'] = array('elt', strtotime($end_time . ' 23:59:59')); } $model = M('rider_appeal'); $stats = array( 'total_count' => $model->where($where)->count(), 'pending_count' => $model->where(array_merge($where, array('status' => 0)))->count(), 'approved_count' => $model->where(array_merge($where, array('status' => 1)))->count(), 'rejected_count' => $model->where(array_merge($where, array('status' => 2)))->count(), 'order_appeal_count' => $model->where(array_merge($where, array('appeal_type' => 'order')))->count(), 'rating_appeal_count' => $model->where(array_merge($where, array('appeal_type' => 'rating')))->count(), 'penalty_appeal_count' => $model->where(array_merge($where, array('appeal_type' => 'penalty')))->count() ); // 计算总补偿金额 $total_compensation = $model->where(array_merge($where, array('status' => 1))) ->sum('compensation_amount'); $stats['total_compensation'] = number_format($total_compensation ?: 0, 2); $this->ajaxReturn(array( 'code' => 0, 'msg' => 'success', 'data' => $stats )); } /** * 获取状态文本 */ private function getStatusText($status) { $statusMap = array( 0 => '待处理', 1 => '已通过', 2 => '已驳回' ); return isset($statusMap[$status]) ? $statusMap[$status] : '未知'; } /** * 获取申诉类型文本 */ private function getAppealTypeText($type) { $typeMap = array( 'order' => '订单异常申诉', 'rating' => '差评申诉', 'penalty' => '违规处罚申诉', 'payment' => '收入异常申诉', 'other' => '其他申诉' ); return isset($typeMap[$type]) ? $typeMap[$type] : '其他'; } } ?>