'type/operate_type/shop_id/token参数必传'])); return; } // 发送消息 if($message['operate_type'] == 'sendMsg') { if ( empty($message['to_id']) || empty($message['to_user_type']) || empty($message['chat_type']) || empty($message['msg_type']) ) { Gateway::sendToClient($client_id, json_encode(['msg' => 'to_id/to_user_type/chat_type/msg_type参数必传'])); return; } // 文本消息 if($message['msg_type'] == 1 && empty($message['content'])) { Gateway::sendToClient($client_id, json_encode(['msg' => 'content参数必传'])); return; } // 图片消息 if($message['msg_type'] == 2 && empty($message['image_url'])) { Gateway::sendToClient($client_id, json_encode(['msg' => 'image_url参数必传'])); return; } // 订单消息 if($message['msg_type'] == 3 && empty($message['order_id'])) { Gateway::sendToClient($client_id, json_encode(['msg' => 'order_id参数必传'])); return; } } call_user_func_array(['extend\chat\model\\' . $message['type'], $message['operate_type']], [$client_id, $message]); } public static function getUser($token) { $uid = Redis::get('token:client:token:' . $token); if($uid) { // 用户 $user_type = 1; }else{ $uid = Redis::get('token:admin:token:' . $token); if(!$uid) { throw new MyBusinessException('请登录', 3000); } // 商家 $user_type = 2; } return ['uid' => $uid, 'user_type' => $user_type]; } public static function insertChatUser() { // 存入chat_user // 如果是用户 if(self::$user_info['user_type'] == 1) { $chat_user = Db::name('chat_user')->where(['user_id' => self::$user_info['uid'], 'type' => 1])->find(); if(!$chat_user) { $user_info = Db::name('tb_user_info')->where(['id' => self::$user_info['uid']])->find(); if($user_info) { Db::name('chat_user')->insert([ 'user_id' => self::$user_info['uid'], 'nick_name' => $user_info['nick_name'], 'avatar' => $user_info['head_img'], 'type' => 1, 'created_time' => d(), ]); } } }elseif (self::$user_info['user_type'] == 2) { // 如果是商家 $chat_user = Db::name('chat_user')->where(['user_id' => self::$user_info['uid'], 'type' => 2])->find(); if(!$chat_user) { $sys_user_info = Db::name('sys_user')->where(['id' => self::$user_info['uid']])->find(); if($sys_user_info) { Db::name('chat_user')->insert([ 'user_id' => self::$user_info['uid'], 'nick_name' => $sys_user_info['nick_name'], 'avatar' => $sys_user_info['avatar'], 'type' => 2, 'created_time' => d(), ]); } } } } public static function init(string $client_id, array $message) { self::$user_info = self::getUser($message['token']); // 存入chat_user self::insertChatUser(); $list_arr = []; // 绑定自己的UID Gateway::bindUid($client_id, self::getUid(self::$user_info['uid'], self::$user_info['user_type'])); // 先拿到会话列表 $list_json = Redis::get('usermsg:list:' . self::$user_info['user_type'] . ':' . self::$user_info['uid']); if($list_json) { $list_arr = json_decode($list_json, true); } // 回馈 Gateway::sendToClient($client_id, self::sendGormat($message, $list_arr)); // 上线后立马发送没有发送的消息 $send_data = Business::getRedisMessage(self::$user_info['uid'], self::$user_info['user_type']); if($send_data) { foreach ($send_data as $k => $v) { Gateway::sendToClient($client_id, $v); } } } // 发送消息 public static function sendMsg(string $client_id, array $message) { $group_id = null; if($message['chat_type'] == 2) { $group_id = $message['to_id']; // 查询此人是否再群里 $is_member = Db::name('chat_group_member')->where(['group_id' => $group_id, 'user_id' => self::$user_info['uid']])->find(); if(!$is_member) { Gateway::sendToClient($client_id, json_encode(['msg' => '你不在群内无法发言'])); return; }else { // 被踢或者退出 if($is_member['quit_time'] || $is_member['is_kicked'] == 1) { Gateway::sendToClient($client_id, json_encode(['msg' => '你不在群内无法发言'])); return; } } // 查询此人是否被禁言 $chat_group_mute = ChatGroupMute::getUserMuteStatus(self::$user_info['uid'], $group_id); if($chat_group_mute['is_mute'] == 1) { Gateway::sendToClient($client_id, json_encode(['msg' => '你已经被禁言,' . $chat_group_mute['ex_mute_time'] . '解除'])); return; } if($chat_group_mute['is_mute'] == 2) { Gateway::sendToClient($client_id, json_encode(['msg' => '你已被永久禁言'])); return; } } $session_id = $message['session_id']; if(empty($session_id)) { // 单聊 if($message['chat_type'] == 1) { // 他是否给我发过消息 $to_message_one = Db::name('chat_message')->where(['to_id' => self::$user_info['uid'], 'from_id' => $message['to_id'] , 'chat_type' => 1])->find(); // 我是否给他发过消息 $from_message_one = Db::name('chat_message')->where(['from_id' => self::$user_info['uid'], 'to_id' => $message['to_id'], 'chat_type' => 1])->find(); // 如果都没发过消息 if(!$to_message_one && !$from_message_one) { $session_id = Random::build('alnum', 32); } // 如果他给我发过消息并且我没给他发过消息 if($to_message_one && !$from_message_one) { $session_id = $to_message_one['session_id']; } // 加入未读计数 if(!Db::name('chat_unread_count')->where(['user_id' => $message['to_id']])->find()) { Db::name('chat_unread_count')->where(['user_id' => $message['to_id'], 'session_id' => $session_id])->update(['count' => 1, 'updated_time' => d()]); }else { Db::name('chat_unread_count')->where(['user_id' => $message['to_id'], 'session_id' => $session_id])->inc('count')->update(['updated_time' => d()]); } }elseif ($message['chat_type'] == 2) { // 群聊 // 如果发过群聊消息 $to_message_one = Db::name('chat_message')->where(['from_id' => self::$user_info['uid'], 'to_id' => $message['to_id'], 'chat_type' => 2])->find(); if($to_message_one) { $session_id = $to_message_one['session_id']; }else { $session_id = Random::build('alnum', 32); } } } $time = d(); // 通知数据 $notice_data = [ 'from_id' => self::$user_info['uid'], 'to_id' => $message['to_id'], 'operate_type' => $message['operate_type'], 'group_id' => $group_id, 'chat_type' => $message['chat_type'], 'msg_type' => $message['msg_type'], 'content' => $message['content'], 'image_url' => $message['image_url'], 'order_id' => $message['order_id'], 'send_time' => $time, 'session_id' => $session_id, ]; $res = Db::name('chat_message')->insert($notice_data); if(!$res) { // 插入失败 Gateway::sendToClient($client_id, self::sendGormat($message, [], 0)); return; } // 如果是单聊推给对方 if($message['chat_type'] == 1) { if($message['to_user_type'] == 1) { $chat_user = Db::name('chat_user')->where(['user_id' => $message['to_id'], 'type' => 1])->find(); }else { $chat_user = Db::name('chat_user')->where(['user_id' => $message['to_id'], 'type' => 2])->find(); } // 通知数据中加入会话信息 $notice_data['avatar'] = $chat_user['avatar']; $notice_data['nick_name'] = $chat_user['nick_name']; $str_uid = self::getUid($message['to_id'], $message['to_user_type']); // 更新对方会话列表 ChatMessage::getconverlist($message['to_id'], $message['to_user_type']); // 对方是否在线,在线发 不在线存起来等上线了发 if(Gateway::isUidOnline($str_uid)) { Gateway::sendToUid($str_uid, self::sendReceive($notice_data)); return; }else { // 存消息 Business::setRedisMessage($message['to_id'], $message['to_user_type'], $notice_data); } }elseif ($message['chat_type'] == 2) { // 群聊 $group = Db::name('chat_group')->where(['id' => $message['to_id']])->find(); // 通知数据中加入会话信息 $notice_data['avatar'] = $group['avatar']; $notice_data['nick_name'] = $group['name']; // 找到群组中的人,挨个通知,退群的不通知,自己不通知 $group_user = Db::name('chat_group_member')->where(['group_id' => $group_id, 'quit_time' => null, 'is_kicked' => 0])->select()->toArray(); foreach ($group_user as $k => $grep) { if($grep['user_id'] != self::$user_info['uid']) { $user_type = $grep['role']==1?2:1; $str_uid = self::getUid($grep['user_id'], $user_type); // 群成员是否在线,在线发 不在线存起来等上线了发 免打扰也不发消息 if($grep['is_dist'] == 0) { if(Gateway::isUidOnline($str_uid)) { Gateway::sendToUid($str_uid, self::sendReceive($notice_data)); return; }else { // 存消息 Business::setRedisMessage($grep['user_id'], $user_type, $notice_data); } // 加入未读计数 if(!Db::name('chat_unread_count')->where(['user_id' => $grep['user_id']])->find()) { Db::name('chat_unread_count')->where(['user_id' => $grep['user_id'], 'session_id' => $session_id])->update(['count' => 1, 'updated_time' => d()]); }else { Db::name('chat_unread_count')->where(['user_id' => $grep['user_id'], 'session_id' => $session_id])->inc('count')->update(['updated_time' => d()]); } } } } } // 给发送者反馈 Gateway::sendToClient($client_id, self::sendGormat($message)); } // uid public static function getUid($uid, $user_type) { return $user_type . '_' . $uid; } // 发送者反馈 public static function sendGormat($message, $data = [], $status = 1):string { $data = [ 'type' => $message['type'], 'operate_type' => $message['operate_type'], 'status' => $status, 'data' => $data ]; $json = json_encode($data); return $json; } // 接收消息 public static function sendReceive($data = [], $status = 1):string { $data = [ 'type' => 'chat', 'operate_type' => 'receive_msg', 'status' => $status, 'data' => $data ]; $json = json_encode($data); return $json; } }