123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- <?php
- /**
- * 群组相关
- * @author solu
- */
- class GroupInfo extends Model {
- protected $tableName = 'group_info';
- protected $dbKey = 'dw_chat';
- const OFFICIAL_ID = 10000; // 官方群id
- const MAX_ADMIN_COUNT = 6; // 最多管理员数量
- const REDIS_GROUP_ID_HASH = 'globals:group_id_hash';
- /**
- * 加入群组
- * @author solu
- * @param $userId
- * @param $groupId
- * @param $group
- * @return bool
- * @throws Exception
- */
- public function joinGroup($userId, $groupId, $group = []) {
- $where = ['group_id' => $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');
- if ($objUserGroup->getRow(['user_id' => $userId, 'group_id' => $groupId, 'state' => UserGroup::STATE_IN_GROUP])) {
- throw new Exception('already joined this group', CODE_PARAM_ERROR);
- }
- $objSession = new Session();
- $objUserGroup->autoCommit(false);
- $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);
- }
- $sessData = [
- 'user_id' => $userId,
- 'session_id' => $groupId,
- 'is_group' => 1,
- ];
- if (!$objSession->objTable->replaceObject($sessData)) {
- throw new Exception('create session error', CODE_DB_ERROR);
- }
- $objUserGroup->commit();
- // 给自己发消息订阅新群组
- 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,
- ]);
- return true;
- }
- /**
- * 加入群组
- * @author solu
- * @param $userId
- * @param $groupId
- * @param $group
- * @return bool
- * @throws Exception
- */
- public function appendToGroup($userIds, $groupId) {
- $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),
- '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');
- $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;
- }
- }
|