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

553 行
19 KiB
PHP

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?php
namespace Retail\Controller;
use Think\Controller;
/**
* 骑手系统消息管理控制器
*/
class RiderMessageController extends Controller {
/**
* 消息管理首页
*/
public function index() {
$this->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] : '未知';
}
}
?>