$groupId]; !$group && $group = $this->objTable->getRow($where); if (!$group) { throw new Exception('group not exists', CODE_PARAM_ERROR); } $objUserGroup = new TableHelper('user_group', 'dw_chat'); $row = $objUserGroup->getRow(['user_id' => $userId, 'group_id' => $groupId, 'state' => UserGroup::STATE_IN_GROUP]); if (!$row) { $data = [ 'user_id' => $userId, 'group_id' => $groupId, 'join_time' => NOW, 'state' => UserGroup::STATE_IN_GROUP, ]; if (!$objUserGroup->replaceObject($data)) { throw new Exception('join fail', CODE_DB_ERROR); } $memberNum = $group['member_num'] + 1; $where['member_num'] = $group['member_num']; if (!$this->objTable->updateObject(['member_num' => $memberNum], $where)) { throw new Exception('update group info fail', CODE_DB_ERROR); } // 给自己发消息订阅新群组 ThirdApi::pushPersonEvent($userId, [ 'type' => 'join_group', 'group_id' => $groupId, ]); $user_info = User::getUserInfoById($userId); // 给群组发消息有人加入了 ThirdApi::pushGroupEvent($groupId, [ 'type' => 'join', 'group_id' => $groupId, 'user_info' => $user_info, ]); } $objSession = new Session(); $where = [ 'user_id' => $userId, 'session_id' => $groupId, ]; // 有可能删除了会话 if (!$objSession->objTable->getCount($where)) { $sessData = $where; $sessData['is_group'] = 1; $objSession->objTable->replaceObject($sessData); } return true; } /** * 加入群组 * @author solu * @param $userId * @param $groupId * @param $group * @param $memberNum * @return bool * @throws Exception */ public function appendToGroup($userIds, $groupId, $memberNum = 0) { $userGroupDatas = []; $sessDatas = []; foreach ($userIds as $userId) { $userGroupDatas[] = [ 'user_id' => $userId, 'group_id' => $groupId, 'join_time' => NOW, 'state' => UserGroup::STATE_IN_GROUP, ]; $sessDatas[] = [ 'user_id' => $userId, 'session_id' => $groupId, 'is_group' => 1, ]; } $objUserGroup = new UserGroup(); $objUserGroup->objTable->replaceObjects2($userGroupDatas); $objSession = new Session(); $objSession->objTable->replaceObjects2($sessDatas); $where = ['group_id' => $groupId]; $newData = [ 'member_num' => count($userIds) + $memberNum, 'group_name' => $groupId, ]; $this->objTable->updateObject($newData, $where); } /** * 离开群组 * @author solu * @param $userId * @param $groupId * @param $group * @return bool * @throws Exception */ public function leaveGroup($userId, $groupId, $group = []) { $groupId = (int) $groupId; $where = ['group_id' => $groupId]; !$group && $group = $this->objTable->getRow($where); if (!$group) { throw new Exception('group not exists', CODE_PARAM_ERROR); } $objUserGroup = new UserGroup(); if (!$objUserGroup->inGroup($groupId, $userId)) { throw new Exception('not in group', CODE_PARAM_ERROR); } $groupUserIds = $objUserGroup->getUserIdListSortByAdminAndJoinTime($groupId); $isCreator = $this->isCreator($groupId, $userId); $objSession = new Session(); $objUserGroup->objTable->autoCommit(false); $ugWhere = [ 'user_id' => $userId, 'group_id' => $groupId, ]; if (!$objUserGroup->objTable->updateObject(['state' => UserGroup::STATE_LEAVE, 'is_admin' => 0], $ugWhere)) { throw new Exception('leave fail', CODE_DB_ERROR); } $creatorField = ''; if (count($groupUserIds) == 1) { // 最后一个人离开,去掉群主,群解散 $creatorField = ' , creator=0'; } elseif ($isCreator) { // 群主离开, 群主顺移给下一位 $newCreator = 0; for ($i = 0; $i < count($groupUserIds); $i++) { if ($groupUserIds[$i] == $userId) { continue; } $newCreator = $groupUserIds[$i]; break; } $creatorField = " , creator={$newCreator}"; // 新群主设置成管理员 $objUserGroup->setData($groupId, $newCreator, ['is_admin' => 1]); } $sql = "UPDATE group_info SET member_num = member_num - 1 {$creatorField} WHERE group_id = {$groupId}"; $this->objDb->update($sql); $sessWhere = [ 'user_id' => $userId, 'session_id' => $groupId, ]; if (!$objSession->objTable->delObject($sessWhere)) { throw new Exception('delete session error', CODE_DB_ERROR); } $objUserGroup->objTable->commit(); // 给自己发消息订阅新群组 ThirdApi::pushPersonEvent($userId, [ 'type' => 'leave_group', 'group_id' => $groupId, ]); $user_info = User::getUserInfoById($userId); // 给群组发消息有人离开了 ThirdApi::pushGroupEvent($groupId, [ 'type' => 'leave', 'group_id' => $groupId, 'user_id' => $userId, 'user_info' => $user_info, ]); return true; } /** * 更新信息 * @author solu * @param $userId * @param $groupId * @param array $data * @return bool|int * @throws Exception */ public function setData($userId, $groupId, array $data) { if (!(new UserGroup())->isAdmin($groupId, $userId)) { throw new Exception('no permission', CODE_NO_PERMITION); } $data['update_time'] = NOW; return $this->objTable->updateObject($data, ['group_id' => $groupId]); } /** * 分享连接 * @author solu * @param string $name * @return string */ public static function genInviteUrl($name) { if (!$name) { return ''; } return sprintf('%s/s/%s', URL_SELF, $name); } /** * 是否群主 * @author solu * @param $groupId * @param $userId * @return bool */ public function isCreator($groupId, $userId) { $creator = $this->objTable->getOne(['group_id' => $groupId], ['_field' => 'creator']); return intval($creator) == $userId; } /** * 设置群管理 * @author solu * @param $groupId * @param $creator * @param $userIds * @return bool * @throws Exception */ public function addAdmin($groupId, $creator, $userIds) { if (!$this->isCreator($groupId, $creator)) { throw new Exception('no permission', CODE_NO_PERMITION); } $objUserGroup = new UserGroup(); $c = $objUserGroup->objTable->getCount(['group_id' => $groupId, 'is_admin' => 1]); $c += count($userIds); if ($c > self::MAX_ADMIN_COUNT) { throw new Exception('too many admins', CODE_NORMAL_ERROR); } if (!$objUserGroup->setData($groupId, $userIds, ['is_admin' => 1])) { throw new Exception('set admin fail', CODE_NORMAL_ERROR); } return true; } /** * 移除管理员 * @author solu * @param $groupId * @param $creator * @param $userId * @return bool * @throws Exception */ public function removeAdmin($groupId, $creator, $userId) { if (!$this->isCreator($groupId, $creator)) { throw new Exception('no permission', CODE_NO_PERMITION); } if ($userId == $creator) { throw new Exception('can not remove creator', CODE_NORMAL_ERROR); } $objUserGroup = new UserGroup(); if (!$objUserGroup->setData($groupId, $userId, ['is_admin' => 0])) { throw new Exception('set admin fail', CODE_NORMAL_ERROR); } return true; } /** * 搜索群用户信息 * @author solu * @param $groupId * @param $keyword * @return array */ public function memberSearch($groupId, $keyword) { $objUserGroup = new UserGroup(); $userIds = $objUserGroup->objTable->getCol(['group_id' => $groupId], ['_field' => 'user_id']); if (!$userIds) { return []; } $objUserInfo = new TableHelper('user_info', 'dw_chat'); // $keyword 是外部传来的参数,会有注入攻击 $keyword = $objUserInfo->escape($keyword); $userInfo = $objUserInfo->getAll(['user_id' => $userIds], [ '_where' => "(user_name like '{$keyword}%' || nick_name like '{$keyword}%')", '_field' => 'user_id, user_name, nick_name, cover_photo', '_sortKey' => 'last_login_time DESC', // '_debug' => true, ]); coverReplaceArrImage($userInfo, 'cover_photo'); return $userInfo; } /** * 获取用户名 * @author solu * @param $groupId * @return string */ public static function getGroupNameById($groupId) { $objRedis = dwRedis::init(); $userName = $objRedis->hGet(self::REDIS_GROUP_ID_HASH, $groupId); if (!$userName) { $obj = new GroupInfo(); $userName = $obj->objTable->getOne(['group_id' => $groupId], ['_field' => 'group_title']); if ($userName) { self::setGroupNameById($groupId, $userName, $objRedis); } } return $userName; } public static function setGroupNameById($groupId, $user_name, $objRedis = null) { !$objRedis && $objRedis = dwRedis::init(); $objRedis->hSet(self::REDIS_GROUP_ID_HASH, $groupId, $user_name); } /** * 转移群主 * @author solu * @param $groupId * @param $old * @param $new * @return bool * @throws Exception */ public function changeCreator($groupId, $old, $new) { if (!$this->isCreator($groupId, $old)) { throw new Exception('no permission', CODE_NO_PERMITION); } if ($old == $new) { throw new Exception('same creator', CODE_NORMAL_ERROR); } $this->objTable->updateObject(['creator' => $new], ['group_id' => $groupId]); (new UserGroup())->setData($groupId, $old, ['is_admin' => 0]); return true; } /** * 获取客服id * @author solu * @param $userIds * @return array */ public function getGroupServerFromUserIds($userIds) { $items = $this->objTable->getAll(['server_id' => $userIds], ['_field' => 'group_id, server_id']); return arrayFormatKey($items, 'server_id', 'group_id'); } public function checkPermission($group_id, $user_id) { $_field = 'is_public'; $objGroupInfo = new GroupInfo(); $is_public = (int) $objGroupInfo->objTable->getOne(['group_id' => $group_id], compact('_field')); if (!$is_public) { // 私有群要判断用户是否存在 if ($user_id) { $objUserGroup = new UserGroup(); $state = 1; $count = $objUserGroup->objTable->getCount(compact('group_id', 'user_id', 'state')); if (!$count) { Response::error(CODE_NO_PERMITION, 'the group is private'); } } else { Response::error(CODE_NO_PERMITION, 'the group is private'); } } } public function getGroupIdFromTgGroupId($tgGroupId) { $groupId = $this->objTable->getOne(['tg_group_id' => $tgGroupId], ['_field' => 'group_id']); return intval($groupId); } }