// +---------------------------------------------------------------------- namespace app\webscoket\handler; use app\services\chat\ChatGroupMemberServices; use app\services\chat\ChatGroupServices; use app\services\chat\ChatLogServices; use app\services\user\UserAuthServices; use app\webscoket\BaseHandler; use app\webscoket\Response; use Psr\SimpleCache\InvalidArgumentException; use qiniu\exceptions\AuthException; use think\db\exception\DataNotFoundException; use think\db\exception\DbException; use think\db\exception\ModelNotFoundException; use think\response\Json; /** * Class UserHandler * @package app\webscoket\handler */ class UserHandler extends BaseHandler { /** * 用户登陆 * @param array $data * @param Response $response * @return Json * @throws InvalidArgumentException */ public function login(array $data, Response $response) { if (!isset($data['token']) || !$token = $data['token']) { return $response->fail('授权失败!'); } try { /** @var UserAuthServices $services */ $services = app()->make(UserAuthServices::class); $authInfo = $services->parseToken($token); } catch (AuthException $e) { return $response->fail($e->getMessage()); } $user = $authInfo['user']; return $response->success('login', $user->toArray()); } /** * 聊天事件 * @param array $data * @param Response $response * @return Json * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function chat(array $data, Response $response) { $user = $this->room->get($this->fd); if (!$user) { return $response->fail('聊天用户已下线'); } $to_uid = $data['to_uid'] ?? 0; $msn_type = $data['type'] ?? 'text'; $msn = $data['msn'] ?? ''; $uid = $user['uid']; if (!$to_uid) { return $response->message('err_tip', ['msg' => '请选择聊天对象']); } if ($to_uid == $uid) { return $response->message('err_tip', ['msg' => '不能和自己聊天']); } /** @var ChatLogServices $logServices */ $logServices = app()->make(ChatLogServices::class); if (!in_array($msn_type, ChatLogServices::MSN_TYPE)) { return $response->message('err_tip', ['msg' => '格式错误']); } $msn = trim(strip_tags(str_replace(["\n", "\t", "\r", " "], '', htmlspecialchars_decode($msn)))); $data = compact('to_uid', 'msn_type', 'msn', 'uid'); $data['add_time'] = time(); //获取收消息人的所有fd信息 $toUserFd = $this->manager->userFd(0, $to_uid); $toUser = ['to_uid' => -1]; $fremaData = []; $on = []; foreach ($toUserFd as $value) { if ($frem = $this->room->get($value)) { $fremaData[] = $frem; //如果当收消息人在和当前发消息人对话中 if ($frem['to_uid'] == $user['uid']) { $toUser = $frem; $on = $value; } } } //是否在线 //是否和当前用户对话 $online = $toUserFd && $toUser && $toUser['to_uid'] !== -1; $data['status'] = $online ? 1 : 0; $data = $logServices->create($data); $data = $data->toArray(); $data['_add_time'] = $data['add_time']; $data['add_time'] = strtotime($data['add_time']); $_userInfo = $logServices->getInfo(0, $uid); //是否在线 $unMessagesCount = $logServices->getCount(['uid' => $uid, 'to_uid' => $to_uid, 'status' => 0]); if ($online) { $this->manager->pushing($on, $response->message('reply', $data)->getData()); } else { //用户在线,可是没有和当前用户进行聊天,给当前用户发送未读条数 if ($toUserFd && $toUser) { $data['record']['nickname'] = $_userInfo['info']['name'] ?? ''; $data['record']['avatar'] = $_userInfo['info']['avatar'] ?? $_userInfo['info']['logo'] ?? ''; $data['record']['type'] = $_userInfo['type']; $this->manager->pushing($toUserFd, $response->message('message_num', [ 'uid' => $uid, 'num' => $unMessagesCount, 'record' => $data['record'] ])->getData()); } } return $response->message('chat', $data); } /** * 聊天事件 * @param array $data * @param Response $response * @return Json * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function group_chat(array $data, Response $response) { $user = $this->room->get($this->fd); if (!$user) { return $response->fail('聊天用户已下线'); } $at = $data['at'] ?? 0; $group_id = $data['group_id'] ?? 0; $msn_type = $data['type'] ?? 'text'; $msn = $data['msn'] ?? ''; $uid = $user['uid']; if (!$group_id) { return $response->message('err_tip', ['msg' => '请选择聊天群聊']); } /** @var ChatGroupMemberServices $memberService */ $memberService = app()->make(ChatGroupMemberServices::class); if (!$user = $memberService->search()->where('uid', $uid)->where('chat_group_id', $group_id)->find()) { return $response->message('err_tip', ['msg' => '未在群内']); } $members = $memberService->search(['chat_group_id' => $group_id])->where('uid', '<>', $uid)->select(); /** @var ChatGroupServices $groupServices */ $groupServices = app()->make(ChatGroupServices::class); $group = $groupServices->search()->where('id', $group_id)->find(); if (!$group) return $response->message('err_tip', ['msg' => '群不存在']); /** @var ChatLogServices $logServices */ $logServices = app()->make(ChatLogServices::class); if (!in_array($msn_type, ChatLogServices::MSN_TYPE)) { return $response->message('err_tip', ['msg' => '格式错误']); } $msn = trim(strip_tags(str_replace(["\n", "\t", "\r", " "], '', htmlspecialchars_decode($msn)))); $data = compact('group_id', 'msn_type', 'msn', 'uid', 'at'); $data['add_time'] = time(); $online = [$uid]; $on = []; //获取收消息人的所有fd信息 foreach ($members as $v) { $toUserFd = $this->manager->userFd(0, $v['uid']); $fremaData = []; foreach ($toUserFd as $value) { if ($frem = $this->room->get($value)) { $fremaData[] = $frem; //如果当收消息人在和当前发消息人对话中 if (($frem['to_group'] ?? 0) == $group_id) { $online[] = $v['uid']; $on[] = $value; } } } } $data['group_see'] = implode(',', array_unique($online)); $data['status'] = 1; $data = $logServices->create($data); $data = $data->toArray(); $data['_add_time'] = $data['add_time']; $data['add_time'] = strtotime($data['add_time']); $_userInfo = $logServices->getInfo($user['identity'], $uid); $data['record']['nickname'] = $user['nickname'] ?: ($_userInfo['info']['name'] ?? ''); $data['record']['avatar'] = $_userInfo['info']['avatar'] ?? $_userInfo['info']['logo'] ?? ''; $data['record']['type'] = $_userInfo['type']; $data['record']['identity'] = $user['identity']; $data['record']['ext_identity'] = $user['ext_identity']; $this->manager->pushing($on, $response->message('group_reply', $data)->getData()); $record = $data['record']; foreach ($members as $v) { if (!in_array($v['uid'], $online)) { $toUserFd = $this->manager->userFd(0, $v['uid']); if ($toUserFd) { $unMessagesCount = $logServices->search()->where('group_id', $group_id) ->where('!find_in_set(' . $v['uid'] . ',group_see)')->where('add_time', '>=', $v['add_time']) ->count(); $this->manager->pushing($toUserFd, $response->message('group_message_num', [ 'uid' => $uid, 'group_id' => $group_id, 'group_name' => $group['name'], 'num' => $unMessagesCount, 'record' => $record ])->getData()); } } } return $response->message('group_chat', $data); } /** * 切换用户聊天 * @param array $data * @param Response $response * @return Json * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function to_chat(array $data, Response $response) { $toUid = $data['id'] ?? 0; $toGroup = $data['to_group'] ?? 0; $toUserType = $data['to_user_type'] ?? 0; $userType = $data['user_type'] ?? 0; $res = $this->room->get($this->fd); if ($res && $toUid) { $uid = $res['uid']; $this->manager->updateTableField((int)$res['type'], (int)$uid, 0, 'to_group'); $this->manager->updateTableField((int)$res['type'], (int)$uid, (int)$toUid); $this->manager->updateTableField((int)$res['type'], (int)$uid, (int)$toUserType, 'to_user_type'); $this->manager->updateTableField((int)$res['type'], (int)$uid, (int)$userType, 'user_type'); /** @var ChatLogServices $logServices */ $logServices = app()->make(ChatLogServices::class); $logServices->update(['uid' => $toUid, 'to_uid' => $uid, 'to_uid_type' => $toUserType, 'uid_type' => $userType], ['status' => 1]); return $response->message('message_num', ['uid' => $toUid, 'to_user_type' => $toUserType, 'user_type' => $userType, 'num' => 0, 'recored' => (object)[]]); } else if ($res && $toGroup) { $uid = $res['uid']; /** @var ChatGroupMemberServices $memberService */ $memberService = app()->make(ChatGroupMemberServices::class); if (!$user = $memberService->search()->where('uid', $uid)->where('chat_group_id', $toGroup)->find()) { return $response->message('err_tip', ['msg' => '未在群内']); } $this->manager->updateTableField((int)$res['type'], (int)$uid, (int)0); $this->manager->updateTableField((int)$res['type'], (int)$uid, (int)$toGroup, 'to_group'); // //debug // { // $toUserFd = $this->manager->userFd(0, $uid); // foreach ($toUserFd as $value){ // if ($frem = $this->room->get($value)) { // Log::debug($uid.'|'.json_encode($frem)); // } // } // } /** @var ChatLogServices $logServices */ $logServices = app()->make(ChatLogServices::class); /** @var ChatGroupServices $groupServices */ $groupServices = app()->make(ChatGroupServices::class); $group = $groupServices->search()->where('id', $toGroup)->find(); if (!$group) return $response->message('err_tip', ['msg' => '群不存在']); $logServices->search()->where('group_id', $toGroup) ->where('!find_in_set(' . $uid . ',group_see)') ->exp('group_see', 'CONCAT(group_see,",' . $uid . '")') ->update(); return $response->message('group_message_num', ['uid' => $toUid, 'to_group' => $toGroup, 'num' => 0, 'record' => (object)[]]); } else { return $response->message('err_tip', ['msg' => '请登录']); } } }