display(); } /** * 获取消息列表 */ public function getMessageList() { $page = I('page', 1, 'intval'); $pageSize = I('pageSize', 20, 'intval'); $keyword = I('keyword', '', 'trim'); $type = I('type', '', 'trim'); $status = I('status', '', 'trim'); $start_time = I('start_time', '', 'trim'); $end_time = I('end_time', '', 'trim'); $where = array(); // 关键词搜索 if (!empty($keyword)) { $where['title|content'] = array('like', '%' . $keyword . '%'); } // 消息类型筛选 if ($type !== '') { $where['message_type'] = $type; } // 状态筛选 if ($status !== '') { $where['status'] = $status; } // 时间范围筛选 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_message'); $total = $model->where($where)->count(); $list = $model->where($where) ->order('create_time desc') ->page($page, $pageSize) ->select(); // 格式化数据 foreach ($list as &$item) { $item['message_type_text'] = $this->getMessageTypeText($item['message_type']); $item['status_text'] = $this->getStatusText($item['status']); $item['create_time_format'] = date('Y-m-d H:i:s', $item['create_time']); $item['send_time_format'] = $item['send_time'] ? date('Y-m-d H:i:s', $item['send_time']) : ''; // 统计接收人数和已读人数 if ($item['target_type'] == 'all') { $item['target_count'] = M('users')->where(array('user_type' => 'rider', 'status' => 1))->count(); } elseif ($item['target_type'] == 'specific') { $item['target_count'] = M('rider_message_receiver')->where(array('message_id' => $item['id']))->count(); } else { $item['target_count'] = 0; } $item['read_count'] = M('rider_message_read')->where(array('message_id' => $item['id']))->count(); } $this->ajaxReturn(array( 'code' => 0, 'msg' => 'success', 'data' => array( 'list' => $list, 'total' => $total ) )); } /** * 获取消息详情 */ public function getMessageDetail() { $id = I('id', 0, 'intval'); if (empty($id)) { $this->ajaxReturn(array('code' => 1, 'msg' => '参数错误')); } $detail = M('rider_message')->where(array('id' => $id))->find(); if (empty($detail)) { $this->ajaxReturn(array('code' => 1, 'msg' => '消息不存在')); } // 格式化数据 $detail['message_type_text'] = $this->getMessageTypeText($detail['message_type']); $detail['status_text'] = $this->getStatusText($detail['status']); $detail['create_time_format'] = date('Y-m-d H:i:s', $detail['create_time']); $detail['send_time_format'] = $detail['send_time'] ? date('Y-m-d H:i:s', $detail['send_time']) : ''; // 获取接收人列表 if ($detail['target_type'] == 'specific') { $receivers = M('rider_message_receiver')->alias('r') ->field('r.*, u.nickname, u.phone') ->join('ls_users u ON r.rider_id = u.id') ->where(array('r.message_id' => $id)) ->select(); $detail['receivers'] = $receivers; } // 获取已读统计 $read_stats = M('rider_message_read')->alias('r') ->field('r.*, u.nickname, u.phone') ->join('ls_users u ON r.rider_id = u.id') ->where(array('r.message_id' => $id)) ->order('r.read_time desc') ->select(); foreach ($read_stats as &$read) { $read['read_time_format'] = date('Y-m-d H:i:s', $read['read_time']); } $detail['read_stats'] = $read_stats; $this->ajaxReturn(array( 'code' => 0, 'msg' => 'success', 'data' => $detail )); } /** * 添加/编辑消息 */ public function saveMessage() { $id = I('id', 0, 'intval'); $data = array( 'title' => I('title', '', 'trim'), 'content' => I('content', '', 'trim'), 'message_type' => I('message_type', '', 'trim'), 'target_type' => I('target_type', '', 'trim'), 'send_immediately' => I('send_immediately', 0, 'intval'), 'scheduled_time' => I('scheduled_time', '', 'trim'), 'image_url' => I('image_url', '', 'trim'), 'link_url' => I('link_url', '', 'trim'), 'status' => I('status', 0, 'intval') ); $target_riders = I('target_riders', '', 'trim'); // 数据验证 if (empty($data['title'])) { $this->ajaxReturn(array('code' => 1, 'msg' => '消息标题不能为空')); } if (empty($data['content'])) { $this->ajaxReturn(array('code' => 1, 'msg' => '消息内容不能为空')); } if (empty($data['message_type'])) { $this->ajaxReturn(array('code' => 1, 'msg' => '请选择消息类型')); } if (empty($data['target_type'])) { $this->ajaxReturn(array('code' => 1, 'msg' => '请选择发送对象')); } if ($data['target_type'] == 'specific' && empty($target_riders)) { $this->ajaxReturn(array('code' => 1, 'msg' => '请选择接收骑手')); } if (!$data['send_immediately'] && empty($data['scheduled_time'])) { $this->ajaxReturn(array('code' => 1, 'msg' => '请设置发送时间')); } // 处理发送时间 if ($data['send_immediately']) { $data['send_time'] = time(); $data['status'] = 1; // 已发送 } else { $data['send_time'] = strtotime($data['scheduled_time']); $data['status'] = 0; // 待发送 } unset($data['send_immediately'], $data['scheduled_time']); $model = M('rider_message'); // 开启事务 M()->startTrans(); try { if ($id > 0) { // 编辑 $data['update_time'] = time(); $result = $model->where(array('id' => $id))->save($data); $message_id = $id; } else { // 添加 $data['create_time'] = time(); $data['update_time'] = time(); $message_id = $model->add($data); $result = $message_id; } if (!$result) { throw new \Exception('保存消息失败'); } // 处理接收人 if ($data['target_type'] == 'specific') { // 先删除原有接收人 M('rider_message_receiver')->where(array('message_id' => $message_id))->delete(); // 添加新的接收人 $rider_ids = explode(',', $target_riders); foreach ($rider_ids as $rider_id) { $rider_id = intval($rider_id); if ($rider_id <= 0) continue; M('rider_message_receiver')->add(array( 'message_id' => $message_id, 'rider_id' => $rider_id, 'create_time' => time() )); } } // 如果是立即发送,执行发送逻辑 if ($data['status'] == 1) { $this->sendMessage($message_id); } M()->commit(); $this->ajaxReturn(array('code' => 0, 'msg' => '操作成功')); } catch (\Exception $e) { M()->rollback(); $this->ajaxReturn(array('code' => 1, 'msg' => $e->getMessage())); } } /** * 发送消息 */ public function sendMessage($message_id = 0) { if ($message_id == 0) { $message_id = I('id', 0, 'intval'); } if (empty($message_id)) { $this->ajaxReturn(array('code' => 1, 'msg' => '参数错误')); } $message = M('rider_message')->where(array('id' => $message_id))->find(); if (empty($message)) { $this->ajaxReturn(array('code' => 1, 'msg' => '消息不存在')); } if ($message['status'] == 1) { $this->ajaxReturn(array('code' => 1, 'msg' => '消息已发送')); } // 获取目标骑手 $target_riders = array(); if ($message['target_type'] == 'all') { $target_riders = M('users')->where(array('user_type' => 'rider', 'status' => 1))->getField('id', true); } elseif ($message['target_type'] == 'specific') { $target_riders = M('rider_message_receiver')->where(array('message_id' => $message_id))->getField('rider_id', true); } if (empty($target_riders)) { $this->ajaxReturn(array('code' => 1, 'msg' => '没有找到目标骑手')); } // 这里可以集成推送服务,如极光推送、友盟推送等 // 示例:调用推送接口 $push_result = $this->pushToRiders($target_riders, $message); // 更新消息状态 M('rider_message')->where(array('id' => $message_id))->save(array( 'status' => 1, 'send_time' => time(), 'update_time' => time() )); if ($message_id == I('id', 0, 'intval')) { $this->ajaxReturn(array('code' => 0, 'msg' => '发送成功')); } return true; } /** * 删除消息 */ public function deleteMessage() { $id = I('id', 0, 'intval'); if (empty($id)) { $this->ajaxReturn(array('code' => 1, 'msg' => '参数错误')); } // 开启事务 M()->startTrans(); try { // 删除消息 $result = M('rider_message')->where(array('id' => $id))->delete(); if (!$result) { throw new \Exception('删除消息失败'); } // 删除相关数据 M('rider_message_receiver')->where(array('message_id' => $id))->delete(); M('rider_message_read')->where(array('message_id' => $id))->delete(); M()->commit(); $this->ajaxReturn(array('code' => 0, 'msg' => '删除成功')); } catch (\Exception $e) { M()->rollback(); $this->ajaxReturn(array('code' => 1, 'msg' => $e->getMessage())); } } /** * 批量发送消息 */ public function batchSend() { $ids = I('ids', '', 'trim'); if (empty($ids)) { $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; $message = M('rider_message')->where(array('id' => $id))->find(); if (empty($message) || $message['status'] == 1) { continue; } try { $this->sendMessage($id); $success_count++; } catch (\Exception $e) { continue; } } $this->ajaxReturn(array( 'code' => 0, 'msg' => "批量发送完成,成功发送{$success_count}条消息" )); } /** * 导出消息数据 */ public function exportMessage() { $keyword = I('keyword', '', 'trim'); $type = I('type', '', 'trim'); $status = I('status', '', 'trim'); $start_time = I('start_time', '', 'trim'); $end_time = I('end_time', '', 'trim'); $where = array(); if (!empty($keyword)) { $where['title|content'] = array('like', '%' . $keyword . '%'); } if ($type !== '') { $where['message_type'] = $type; } if ($status !== '') { $where['status'] = $status; } 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')); } $list = M('rider_message')->where($where)->order('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', '发送时间'); // 填充数据 $row = 2; foreach ($list as $item) { // 统计接收人数和已读人数 if ($item['target_type'] == 'all') { $target_count = M('users')->where(array('user_type' => 'rider', 'status' => 1))->count(); } elseif ($item['target_type'] == 'specific') { $target_count = M('rider_message_receiver')->where(array('message_id' => $item['id']))->count(); } else { $target_count = 0; } $read_count = M('rider_message_read')->where(array('message_id' => $item['id']))->count(); $objActSheet->setCellValue('A' . $row, $item['id']); $objActSheet->setCellValue('B' . $row, $item['title']); $objActSheet->setCellValue('C' . $row, $this->getMessageTypeText($item['message_type'])); $objActSheet->setCellValue('D' . $row, $item['target_type'] == 'all' ? '全部骑手' : '指定骑手'); $objActSheet->setCellValue('E' . $row, $target_count); $objActSheet->setCellValue('F' . $row, $read_count); $objActSheet->setCellValue('G' . $row, $this->getStatusText($item['status'])); $objActSheet->setCellValue('H' . $row, date('Y-m-d H:i:s', $item['create_time'])); $objActSheet->setCellValue('I' . $row, $item['send_time'] ? date('Y-m-d H:i:s', $item['send_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 getMessageStats() { $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_message'); $stats = array( 'total_count' => $model->where($where)->count(), 'sent_count' => $model->where(array_merge($where, array('status' => 1)))->count(), 'pending_count' => $model->where(array_merge($where, array('status' => 0)))->count(), 'announcement_count' => $model->where(array_merge($where, array('message_type' => 'announcement')))->count(), 'policy_count' => $model->where(array_merge($where, array('message_type' => 'policy')))->count(), 'activity_count' => $model->where(array_merge($where, array('message_type' => 'activity')))->count(), 'system_count' => $model->where(array_merge($where, array('message_type' => 'system')))->count() ); // 计算总阅读率 $total_sent = $stats['sent_count']; if ($total_sent > 0) { $total_reads = M('rider_message_read')->alias('r') ->join('ls_rider_message m ON r.message_id = m.id') ->where(array_merge($where, array('m.status' => 1))) ->count(); $stats['read_rate'] = number_format(($total_reads / $total_sent) * 100, 2); } else { $stats['read_rate'] = '0.00'; } $this->ajaxReturn(array( 'code' => 0, 'msg' => 'success', 'data' => $stats )); } /** * 推送消息到骑手 */ private function pushToRiders($rider_ids, $message) { // 这里集成具体的推送服务 // 例如:极光推送、友盟推送、Firebase等 // 示例代码(需要根据实际推送服务调整) /* $push_data = array( 'title' => $message['title'], 'content' => $message['content'], 'extras' => array( 'message_id' => $message['id'], 'message_type' => $message['message_type'], 'link_url' => $message['link_url'] ) ); // 调用推送接口 $push_service = new PushService(); $result = $push_service->pushToUsers($rider_ids, $push_data); return $result; */ // 临时返回成功 return true; } /** * 获取消息类型文本 */ private function getMessageTypeText($type) { $typeMap = array( 'announcement' => '平台公告', 'policy' => '政策变更', 'activity' => '活动提醒', 'system' => '系统通知', 'order' => '订单通知', 'reward' => '奖励通知' ); return isset($typeMap[$type]) ? $typeMap[$type] : '其他'; } /** * 获取状态文本 */ private function getStatusText($status) { $statusMap = array( 0 => '待发送', 1 => '已发送' ); return isset($statusMap[$status]) ? $statusMap[$status] : '未知'; } } ?>