['int', 'desc' => '群id'], ]; Param::checkParam2($rules, $args); $user_id = User::getUserId(); $objGroupInfo = new GroupInfo(); $_field = 'group_id, group_name, group_title, group_notice, cover_photo, member_num, creator, url, server_id, is_public'; $group = $objGroupInfo->objTable->getRow($args, compact('_field')); $group && $group['invite_url'] = GroupInfo::genInviteUrl($group['group_name']); $group['increase_num'] = 0; $_field = 'user_id, is_admin, is_block, join_time'; $objUserGroup = new UserGroup(); $groupUsers = $objUserGroup->objTable->getAll(['group_id' => $args['group_id'], 'state' => 1], ['_field' => $_field, '_sortKey' => 'join_time ASC', '_limit' => 100]); $joinMap = arrayFormatKey($groupUsers, 'user_id', 'join_time'); $user_ids = []; $blockList = []; $adminList = []; // 把自己加进去 if ($user_id && !in_array($user_id, array_keys($joinMap))) { $_row = $objUserGroup->objTable->getRow(['user_id' => $user_id, 'group_id' => $args['group_id'], 'state' => 1], ['_field' => $_field]); if ($_row) { $groupUsers[] = $_row; $joinMap[$user_id] = $_row['join_time']; } } if (!$group['is_public'] && !$joinMap[$user_id]) { // 私有群,没加入的人不能看到 Response::error(CODE_NO_PERMITION, 'the group is private.'); } foreach ($groupUsers as $_u) { $_uid = intval($_u['user_id']); $user_ids[] = $_uid; $_u['is_block'] && $blockList[] = $_uid; $_u['is_admin'] && $adminList[] = $_uid; } // 获取pin的消息 $objGroupMsg = new TableHelper('group_msg', 'dw_chat'); $where2 = [ 'group_id' => $args['group_id'], 'is_pin' => 1, '_field' => '`from`, hash, msg, msg_type' ]; $pinMsg = $objGroupMsg->getRow($where2); // $inList = in_array($pinMsg['from'], $user_ids); $user_ids[] = $pinMsg['from']; $objUserInfo = new TableHelper('user_info', 'dw_chat'); $_field = 'user_id, user_name, nick_name, cover_photo'; $members = $objUserInfo->getAll(['user_id' => $user_ids], compact('_field')); coverReplaceArrImage($members, 'cover_photo'); $members = arrayFormatKey($members, 'user_id'); $joinTimes = []; $adminNum = 0; $newMembers = []; foreach ($groupUsers as $_u) { $_uid = intval($_u['user_id']); if ($members[$_uid]) { $joinTime = strtotime($joinMap[$_uid]); $joinTime < 0 && $joinTime = time(); if ($_u['is_block']) { $members[$_uid]['is_block'] = (int) $_u['is_block']; } if ($_u['is_admin']) { $members[$_uid]['is_admin'] = (int) $_u['is_admin']; $joinTime = $adminNum++; if ($group['creator'] == $_uid) { $members[$_uid]['is_admin'] = 2; $joinTime = -1; } } $newMembers[] = $members[$_uid]; $joinTimes[$_uid] = $joinTime; } } // 置顶消息用户信息 $pinMsg = array_merge($pinMsg, arrayFilter($members[$pinMsg['from']], ['user_name', 'nick_name', 'cover_photo'])); $members = $newMembers; array_multisort($joinTimes, SORT_ASC, $members); $sessionInfo = null; if ($user_id) { $objSession = new Session(); $sessionInfo = $objSession->objTable->getRow(['user_id' => $user_id, 'session_id' => $args['group_id']], ['_field' => 'is_pin, pin_time_int, is_mute']); } $objGroupEos = new TableHelper('group_eos', 'dw_chat'); $eosInfo = $objGroupEos->getRow($args); return compact('group', 'eosInfo', 'members', 'pinMsg', 'sessionInfo', 'blockList', 'adminList'); } /** * 群聊 获取最新消息【不需要登录】 * @author benzhan */ public function actionNewMsg($args) { $rules = [ 'group_id' => ['string', 'desc' => '群id'], 'client_hash' => ['string', 'nullable' => true, 'desc' => '客户端上的最新消息的hash'], ]; Param::checkParam2($rules, $args); $load_type = 0; return $this->_msg($args['group_id'], $load_type, $args['client_hash']); } /** * 群聊 获取历史消息【不需要登录】 * @author benzhan */ public function actionHistoryMsg($args) { $rules = [ 'group_id' => ['string', 'desc' => '群id'], 'client_hash' => ['string', 'desc' => '客户端上的最旧消息的hash'], ]; Param::checkParam2($rules, $args); $load_type = -1; return $this->_msg($args['group_id'], $load_type, $args['client_hash']); } /** * 获取消息列表 * @param $session_id string 会话id * @param $load_type int 加载方式:-1:历史消息, 0:最新消息 * @param $client_hash string 客户端的hash * * @return array */ private function _msg($session_id, $load_type, $client_hash) { $userId = User::getUserId(); $where = compact('session_id'); if ($userId) { $where['user_id'] = $userId; } $keyWord = [ '_field' => 'is_group, read_hash, read_num', // '_debug' => 1 ]; $objSession = new Session(); $row = $objSession->objTable->getRow($where, $keyWord); // if (!$row) { // Response::error(CODE_NO_PERMITION, 'session is not found'); // } else if (!$row['is_group']) { // Response::error(CODE_NO_PERMITION, 'session is not group'); // } if (is_numeric($session_id)) { $objGroupInfo = new GroupInfo(); $objGroupInfo->checkPermission($session_id, $userId); } $data = $objSession->getMsgList($session_id, $client_hash, $load_type, 1); if ($userId && $row) { $end = end($data['list']); $lastNum = $end['msg_num']; // var_dump($lastNum, $row);exit; if ($lastNum > $row['read_num']) { $objSession->updateState($session_id, ['read_num' => $lastNum], ['user_id' => $userId]); } } $data['list'] = array_filter($data['list'], function ($v) { return $v['state'] == 1; }); $data['list'] = array_values($data['list']); return $data; } /** * 发送群聊消息 * @author solu * @param $args * @return array */ public function actionSendMsg($args) { $rules = [ 'group_id' => ['string', 'desc' => '群id'], 'msg_type' => ['int', 'nullable' => true, 'default' => 0, 'desc' => '消息类型:0:文本,1:图片,2:视频'], 'msg' => ['string', 'desc' => '内容'], ]; Param::checkParam2($rules, $args); $userId = User::getUserId(); $objSession = new Session(); $data = []; try { $data = $objSession->sendGroupMsg($userId, $args['group_id'], $args['msg_type'], $args['msg']); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } return $data; } public function actionSendImageMsg($args) { return $this->actionSendFile($args); } /** * 群聊 发送多媒体消息 * @author solu * @param $args * @return array */ public function actionSendFile($args) { $args = array_merge($args, $_FILES); $rules = [ 'group_id' => ['string', 'desc' => '群id'], 'res' => ['array', 'desc' => '资源文件'], ]; Param::checkParam2($rules, $args); $data = null; try { $msgType = FileUrl::getType($args['res']['type']); $maxSize = 1000 * 1000; // 默认最大1MB switch ($msgType) { case FileUrl::TYPE_IMAGE: $maxSize = 3000 * 1000; // 图片最大1MB break; case FileUrl::TYPE_VIDEO: $maxSize = 10000 * 1000; // 视频最大3MB break; case FileUrl::TYPE_AUDIO: $maxSize = 5000 * 1000; // 音频最大2MB break; default: Response::error(CODE_PARAM_ERROR, 'unknown type:' . $args['res']['type']); } $size = filesize($args['res']['tmp_name']); if ($size > $maxSize) { Response::error(CODE_PARAM_ERROR, "file is too big. size:{$size}"); } $objFile = new FileUrl(); $url = $objFile->getFileUrl($args['res']['tmp_name'], $args['res']['name'], $args['res']['type']); // 只有图片才需要用ips处理 if ($msgType == FileUrl::TYPE_IMAGE) { $url = awsReplaceImg($url); } $msg = Utils::encodeRC4($url); $userId = User::getUserId(); $extInfo = []; // 处理封面图 if ($msgType == FileUrl::TYPE_VIDEO) { $cover_url = $objFile->getVideoCover($args['res']['tmp_name'], $args['res']['name']); $cover_url && $extInfo['cover_url'] = awsReplaceImg($cover_url); } $objSession = new Session(); $data = $objSession->sendGroupMsg($userId, $args['group_id'], $msgType, $msg, false, false, $extInfo); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } return $data; } /** * 群聊 置顶消息 * @author solu * @param $args */ public function actionPinMsg($args) { $rules = [ 'group_id' => ['string', 'desc' => '群id'], 'hash' => ['string', 'desc' => '消息hash'], ]; Param::checkParam2($rules, $args); $group_id = (int) $args['group_id']; $this->_checkGroupAdmin($group_id); $objGroupMsg = new TableHelper('group_msg', 'dw_chat'); $_field = '`from`, hash, msg, msg_type'; $row = $objGroupMsg->getRow($args, compact('_field')); if (!$row) { Response::error(CODE_NORMAL_ERROR, 'can not find the msg'); } $where2 = [ 'group_id' => $group_id, 'is_pin' => 1, ]; // 取消老的pin $objGroupMsg->updateObject(['is_pin' => 0], $where2); $objGroupMsg->updateObject(['is_pin' => 1], $args); $objUser = new TableHelper('user_info', 'dw_chat'); $user = $objUser->getRow(['user_id' => $row['from']]); $row = array_merge($row, arrayFilter($user, ['user_name', 'nick_name', 'cover_photo'])); // 给群组发消息有pinMsg ThirdApi::pushGroupEvent($group_id, [ 'type' => 'pin_msg', 'group_id' => $group_id, 'pinMsg' => $row, ]); return $row; } /** * 群聊 取消置顶消息 * @author solu * @param $args */ public function actionUnpinMsg($args) { $rules = [ 'group_id' => ['string', 'desc' => '群id'], 'hash' => ['string', 'desc' => '消息hash'], ]; Param::checkParam2($rules, $args); $group_id = (int) $args['group_id']; $this->_checkGroupAdmin($group_id); $objGroupMsg = new TableHelper('group_msg', 'dw_chat'); $count = $objGroupMsg->getCount($args); if (!$count) { Response::error(CODE_NORMAL_ERROR, 'can not find the msg'); } // 取消老的pin $objGroupMsg->updateObject(['is_pin' => 0], $args); // 给群组发消息有人加入了 ThirdApi::pushGroupEvent($group_id, [ 'type' => 'unpin_msg', 'group_id' => $group_id, 'hash' => $args['hash'], ]); return $args['hash']; } /** * 获取朋友 * @author benzhan */ public function actionGetFriends($args) { Param::checkParam2([], $args); $user_id = User::getUserId(); $is_group = 0; $where = compact('user_id', 'is_group'); $keyWord = [ '_field' => 'session_id', '_sort' => 'update_time_int DESC', '_limit' => 500, // 最多加载500个会话 ]; $objSession = new Session(); $session_ids = $objSession->objTable->getCol($where, $keyWord); $friend_ids = array_map(function($session_id) use ($user_id) { return str_replace(['-', $user_id], ['', ''], $session_id); }, $session_ids); $objUserInfo = new TableHelper('user_info', 'dw_chat'); $_field = 'user_id, user_name, nick_name, cover_photo'; $users = $objUserInfo->getAll(['user_id' => $friend_ids], compact('_field')); return $users; } /** * 创建群组 * @author benzhan */ public function actionCreate($args) { $rules = [ 'group_title' => ['string', 'desc' => '群名称'], 'cover_photo' => ['string', 'nullable' => true, 'desc' => '群logo'], 'user_id_list' => ['string', 'nullable' => true, 'desc' => '好友id列表用,隔开'], ]; Param::checkParam2($rules, $args); $creator = User::getUserId(); $objGroupInfo = new GroupInfo(); $args['creator'] = $creator; $sess = []; try { $sess = $objGroupInfo->create($args); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } return $sess; } /** * 加入群组 * @author solu */ public function actionJoin($args) { $rules = [ 'group_id' => ['int', 'desc' => '群组id'], ]; Param::checkParam2($rules, $args); $userId = User::getUserId(); try { (new GroupInfo())->joinGroup($userId, $args['group_id']); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } } /** * 离开群组 * @author solu */ public function actionLeave($args) { $rules = [ 'group_id' => ['int', 'desc' => '群组id'], ]; Param::checkParam2($rules, $args); $userId = User::getUserId(); try { (new GroupInfo())->leaveGroup($userId, $args['group_id']); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } } /** * 封禁用户 * @author benzhan */ public function actionBlockUser($args) { $rules = [ 'group_id' => ['int', 'desc' => '群组id'], 'block_id' => ['int', 'desc' => '用户id'], ]; Param::checkParam2($rules, $args); $group_id = (int) $args['group_id']; $user_id = (int) $args['block_id']; $this->_checkGroupAdmin($group_id); $objUserGroup = new UserGroup(); $objUserGroup->setBlock($group_id, $user_id, 1); $eventData = [ 'type' => 'block', 'group_id' => $group_id, 'from' => User::getUserId(), 'to' => $user_id, 'timestamp' => Session::getMS(), ]; ThirdApi::pushGroupEvent($group_id, $eventData); } /** * 解禁用户 * @author solu */ public function actionUnblockUser($args) { $rules = [ 'group_id' => ['int', 'desc' => '群组id'], 'block_id' => ['int', 'desc' => '用户id'], ]; Param::checkParam2($rules, $args); $group_id = (int) $args['group_id']; $user_id = (int) $args['block_id']; $this->_checkGroupAdmin($group_id); $objUserGroup = new UserGroup(); $objUserGroup->setBlock($group_id, $user_id, 0); $eventData = [ 'type' => 'unblock', 'group_id' => $group_id, 'from' => User::getUserId(), 'to' => $user_id, 'timestamp' => Session::getMS(), ]; ThirdApi::pushGroupEvent($group_id, $eventData); } private function _checkGroupAdmin($group_id) { $owner = User::getUserId(); $objUserGroup = new UserGroup(); if (!$objUserGroup->isAdmin($group_id, $owner)) { Response::error(CODE_NO_PERMITION); } } /** * 更新群名称(只能一次 * @author solu * @param $args */ public function actionChangeName($args) { $rules = [ 'group_id' => ['int', 'desc' => '群id'], 'name' => ['string', 'reg' => '/^[a-z0-9\.]+/i', 'desc' => '新群名'], ]; Param::checkParam2($rules, $args); $objGroup = new GroupInfo(); $userId = User::getUserId(); $groupId = (int)$args['group_id']; if (is_numeric($args['name'])) { Response::error(CODE_PARAM_ERROR, 'name can not be pure numbers'); } $groupInfo = $objGroup->objTable->getRow(['group_id' => $groupId]); if (!$groupInfo) { Response::error(CODE_PARAM_ERROR, 'group not exists'); } // 已修改过群名称 if ($groupInfo['group_id'] != $groupInfo['group_name']) { Response::error(CODE_PARAM_ERROR, 'only one change group name'); } if ($objGroup->objTable->getRow(['group_name' => $args['name']])) { Response::error(CODE_PARAM_ERROR, 'group name exists'); } $data = [ 'group_name' => htmlentities($args['name']), ]; try { $objGroup->setData($userId, $args['group_id'], $data); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } ThirdApi::pushGroupEvent($args['group_id'], [ 'type' => 'update', 'from' => $userId, ]); } /** * 更新群公告 * @author solu * @param $args */ public function actionChangeNotice($args) { $rules = [ 'group_id' => ['int', 'desc' => '群id'], 'notice' => ['string', 'desc' => '新公告'], ]; Param::checkParam2($rules, $args); $objGroup = new GroupInfo(); $userId = User::getUserId(); $data = [ 'group_notice' => htmlentities($args['notice']), ]; try { $objGroup->setData($userId, $args['group_id'], $data); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } ThirdApi::pushGroupEvent($args['group_id'], [ 'type' => 'update', 'from' => $userId, ]); } /** * 更新群图标 * @author solu * @param $args */ public function actionChangeCover($args) { $args = array_merge($args, $_FILES); $rules = [ 'group_id' => ['int', 'desc' => '群id'], 'cover_photo' => ['array', 'desc' => '头像文件'], ]; Param::checkParam2($rules, $args); $file = $args['cover_photo']; $cover_photo = ''; try { $cover_photo = (new FileUrl())->getFileUrl($file['tmp_name'], $file['name'], $file['type'], true); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } $objGroup = new GroupInfo(); $userId = User::getUserId(); $data = [ 'cover_photo' => $cover_photo, ]; try { $objGroup->setData($userId, $args['group_id'], $data); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } ThirdApi::pushGroupEvent($args['group_id'], [ 'type' => 'update', 'from' => $userId, ]); } /** * 更新群标题 * @author solu * @param $args */ public function actionChangeTitle($args) { $rules = [ 'group_id' => ['int', 'desc' => '群id'], 'title' => ['string', 'desc' => '新标题'], ]; Param::checkParam2($rules, $args); $objGroup = new GroupInfo(); $userId = User::getUserId(); $data = [ 'group_title' => htmlentities($args['title']), ]; try { $objGroup->setData($userId, $args['group_id'], $data); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } ThirdApi::pushGroupEvent($args['group_id'], [ 'type' => 'update', 'from' => $userId, ]); GroupInfo::setGroupNameById($args['group_id'], $data['group_title']); } /** * 批量邀请用户加入群 * @author solu * @param $args * @return array */ public function actionInvites($args) { $rules = [ 'group_id' => ['int', 'desc' => '群id'], 'user_ids' => ['string', 'desc' => '用户id 多人,分割'], ]; Param::checkParam2($rules, $args); $groupId = (int)$args['group_id']; $userIds = array_filter(explode(',', $args['user_ids']), function ($v) { return intval($v) > 0; }); $adminId = User::getUserId(); if (!(new UserGroup())->isAdmin($groupId, $adminId)) { Response::error(CODE_NO_PERMITION, 'no permission'); } $count = count($userIds); $success = 0; $objGroupInfo = new GroupInfo(); foreach ($userIds as $userId) { try { $objGroupInfo->joinGroup($userId, $groupId); $success += 1; } catch (Exception $e) {} } return compact('count', 'success'); } /** * 批量移除群用户 * @author solu * @param $args * @return array */ public function actionRemoves($args) { $rules = [ 'group_id' => ['int', 'desc' => '群id'], 'user_ids' => ['string', 'desc' => '用户id 多人,分割'], ]; Param::checkParam2($rules, $args); $groupId = (int)$args['group_id']; $userIds = array_filter(explode(',', $args['user_ids']), function ($v) { return intval($v) > 0; }); $adminId = User::getUserId(); if (!(new UserGroup())->isAdmin($groupId, $adminId)) { Response::error(CODE_NO_PERMITION, 'no permission'); } $count = count($userIds); $success = 0; $objGroupInfo = new GroupInfo(); $group = $objGroupInfo->objTable->getRow(['group_id' => $groupId]); if (!$group) { Response::error(CODE_PARAM_ERROR, 'group not exists'); } foreach ($userIds as $userId) { try { $objGroupInfo->leaveGroup($userId, $groupId, $group); $success += 1; } catch (Exception $e) {} } return compact('count', 'success'); } /** * 撤销消息 * @author solu * @param $args */ public function actionRepealMsg($args) { $rules = [ 'group_id' => ['string', 'desc' => '群id'], 'hash' => ['string', 'desc' => '消息hash'], ]; Param::checkParam2($rules, $args); $userId = User::getUserId(); $objMsg = new GroupMsg(); try { $objMsg->repeal($userId, $args['group_id'], $args['hash']); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } } /** * 添加管理员 * @author solu * @param $args */ public function actionAddAdmin($args) { $rules = [ 'group_id' => ['int', 'desc' => '群id'], 'user_ids' => ['string', 'desc' => '用户id , 分割'], ]; Param::checkParam2($rules, $args); $creator = User::getUserId(); $userIds = array_map('intval', explode(',', $args['user_ids'])); try { (new GroupInfo())->addAdmin($args['group_id'], $creator, $userIds); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } } /** * 移除管理员 * @author solu * @param $args */ public function actionRemoveAdmin($args) { $rules = [ 'group_id' => ['int', 'desc' => '群id'], 'admin_id' => ['int', 'desc' => '管理员id'], ]; Param::checkParam2($rules, $args); $creator = User::getUserId(); try { (new GroupInfo())->removeAdmin($args['group_id'], $creator, $args['admin_id']); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } } /** * 搜索群成员信息 * @author solu * @param $args * @return array */ public function actionMemberSearch($args) { $rules = [ 'keyword' => ['string', 'desc' => '关键字'], 'group_id' => ['int', 'desc' => '群id'], ]; Param::checkParam2($rules, $args); return (new GroupInfo())->memberSearch($args['group_id'], $args['keyword']); } /** * 转移群主 * @author solu * @param $args */ public function actionChangeCreator($args) { $rules = [ 'group_id' => ['int', 'desc' => '群id'], 'new_creator' => ['int', 'desc' => '新群主id'], ]; Param::checkParam2($rules, $args); $userId = User::getUserId(); try { (new GroupInfo())->changeCreator($args['group_id'], $userId, $args['new_creator']); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } } /** * 热门群推荐 * @author benzhan */ public function actionHotList($args) { $rules = []; Param::checkParam2($rules, $args); $objGroup = new GroupInfo(); return $objGroup->getHotList(); } }