文件
mashangyoujiu/Application/Retail/Controller/RiderAppealController.class.php

449 行
16 KiB
PHP

<?php
namespace Retail\Controller;
use Think\Controller;
/**
* 骑手申诉处理管理控制器
*/
class RiderAppealController extends Controller {
/**
* 申诉管理首页
*/
public function index() {
$this->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] : '其他';
}
}
?>