package app import ( "context" "database/sql" "egg-im/internal/logic/domain/group/model" "egg-im/internal/logic/domain/group/repo" "egg-im/pkg/db" "egg-im/pkg/grpclib" "egg-im/pkg/pb" "errors" "strings" ) type groupApp struct{} var GroupApp = new(groupApp) // CreateGroup 创建群组 func (*groupApp) CreateGroup(ctx context.Context, userId int64, in *pb.CreateGroupReq) (int64, error) { group := model.CreateGroup(userId, in) err := repo.GroupRepo.Save(group) if err != nil { return 0, err } in.MemberIds = append(in.MemberIds, userId) err = group.PushAddMember(ctx, userId, in.MemberIds, false) return group.Id, nil } // GetGroup 获取群组信息 func (*groupApp) GetGroup(ctx context.Context, groupId int64) (*pb.Group, pb.MemberType, pb.GroupUserStatusType, error) { group, err := repo.GroupRepo.Get(groupId) memberType := pb.MemberType_GMT_UNKNOWN userStatusType := pb.GroupUserStatusType_GROUP_USER_STATUS_NORMAL if err != nil { return nil, memberType, userStatusType, err } if err != nil { return nil, memberType, userStatusType, err } userId, _, err := grpclib.GetCtxData(ctx) if err != nil { return nil, memberType, userStatusType, err } if !strings.Contains(group.Name, "官方") && !strings.Contains(group.Name, "运营中心") { for _, member := range group.Members { if member.UserId == userId && member.MemberType != int(pb.MemberType_GMT_ADMIN) { group.Name = "我的推荐人群" } } } for _, member := range group.Members { if member.UserId == userId { memberType = pb.MemberType(member.MemberType) userStatusType = pb.GroupUserStatusType(member.Status) } } return group.ToProto(), memberType, userStatusType, nil } // GetUserGroups 获取用户加入的群组列表 func (*groupApp) GetUserGroups(ctx context.Context, userId int64) ([]*pb.Group, error) { groups, err := repo.GroupUserRepo.ListByUserId(userId) if err != nil { return nil, err } pbGroups := make([]*pb.Group, len(groups)) for i := range groups { pbGroups[i] = groups[i].ToProto() groupUser, err := repo.GroupUserRepo.Get(pbGroups[i].GroupId, userId) if err != nil { return nil, err } if !strings.Contains(pbGroups[i].Name, "官方") && !strings.Contains(pbGroups[i].Name, "运营中心") { if groupUser.MemberType != int(pb.MemberType_GMT_ADMIN) { pbGroups[i].Name = "我的推荐人群" } } } return pbGroups, nil } // Update 更新群组 func (*groupApp) Update(ctx context.Context, userId int64, update *pb.UpdateGroupReq) error { group, err := repo.GroupRepo.Get(update.GroupId) if err != nil { return err } var isUpdateIntroduction = false if group.Introduction != update.Introduction { isUpdateIntroduction = true } err = group.Update(ctx, update) if err != nil { return err } err = repo.GroupRepo.Save(group) if err != nil { return err } err = group.PushUpdate(ctx, userId, isUpdateIntroduction) if err != nil { return err } return nil } // AddMembers 添加群组成员 func (*groupApp) AddMembers(ctx context.Context, userId, groupId int64, userIds []int64) ([]int64, error) { group, err := repo.GroupRepo.Get(groupId) if err != nil { return nil, err } if int64(group.UserNum)+int64(len(userIds)) <= 500 { return nil, errors.New("群人员数量已满!") } existIds, addedIds, err := group.AddMembers(ctx, userIds) if err != nil { return nil, err } err = repo.GroupRepo.Save(group) if err != nil { return nil, err } err = group.PushAddMember(ctx, userId, addedIds, true) if err != nil { return nil, err } return existIds, nil } // UpdateMember 更新群组用户 func (*groupApp) UpdateMember(ctx context.Context, in *pb.UpdateGroupMemberReq, optId int64) error { group, err := repo.GroupRepo.Get(in.GroupId) if err != nil { return err } err = group.UpdateMember(ctx, in) if err != nil { return err } err = repo.GroupRepo.Save(group) if err != nil { return err } err = group.PushUpdateMember(ctx, optId, in.UserId, int32(in.MemberType)) if err != nil { return err } return nil } // DeleteMember 删除群组成员 func (*groupApp) DeleteMember(ctx context.Context, groupId int64, userId int64, optId int64) error { group, err := repo.GroupRepo.Get(groupId) if err != nil { return err } err = group.DeleteMember(ctx, userId) if err != nil { return err } group.UserNum-- //群组人数减一 err = repo.GroupRepo.Save(group) if err != nil { return err } if userId == optId { //自己退出群聊,无需发送消息 return nil } err = group.PushDeleteMember(ctx, optId, userId) if err != nil { return err } return nil } // GetMembers 获取群组成员 func (*groupApp) GetMembers(ctx context.Context, groupId, limit int64) ([]*pb.GroupMember, error) { if limit == 0 { group, err := repo.GroupRepo.Get(groupId) if err != nil { return nil, err } return group.GetMembers(ctx) } else { group, err := repo.GroupRepo.GetLimit(groupId, limit) if err != nil { return nil, err } return group.GetMembers(ctx) } } // SendMessage 发送群组消息 func (*groupApp) SendMessage(ctx context.Context, sender *pb.Sender, req *pb.SendMessageReq) (int64, error) { group, err := repo.GroupRepo.Get(req.ReceiverId) if err != nil { return 0, err } return group.SendMessage(ctx, sender, req) } // GetBannedMembers 获取群组禁言成员 func (*groupApp) GetBannedMembers(ctx context.Context, groupId int64) ([]*pb.GroupMember, error) { // 查询被禁言的成员列表 group, err := repo.GroupRepo.GetForBanned(groupId) if err != nil { return nil, err } return group.GetMembers(ctx) } // SetGroupMemberBanned 设置禁言 func (*groupApp) SetGroupMemberBanned(ctx context.Context, optId, groupId int64, userIds []int64, isAllMemberBanned bool) ([]*pb.GroupMember, error) { groupUser, err := repo.GroupUserRepo.Get(groupId, optId) if err != nil { return nil, err } if groupUser == nil { return nil, errors.New("未查询到群组用户信息") } if groupUser.MemberType != int(pb.MemberType_GMT_ADMIN) && groupUser.MemberType != int(pb.MemberType_GMT_MANAGE) { return nil, errors.New("非管理员操作") } group, err := repo.GroupRepo.Get(groupId) if err != nil { return nil, err } if isAllMemberBanned { //设置全员禁言 //1、更新 `group` 的 is_all_member_banned 状态 group.IsAllMemberBanned = int32(pb.AllMemberBannedType_YES_All_Member_Banned) err := repo.GroupRepo.Save(group) if err != nil { return nil, err } //2、发送推送消息 err = group.PushGroupMemberBanned(ctx, optId, 0, isAllMemberBanned) if err != nil { return nil, err } } else { //设置成员禁言 //1、更新 `group` 的 is_all_member_banned 状态 if group.IsAllMemberBanned != int32(pb.AllMemberBannedType_NOT_All_Member_Banned) { group.IsAllMemberBanned = int32(pb.AllMemberBannedType_NOT_All_Member_Banned) err := repo.GroupRepo.Save(group) if err != nil { return nil, err } //TODO::推送消息 err = group.PushGroupMemberBanned(ctx, optId, -1, isAllMemberBanned) if err != nil { return nil, err } } //2、更新 `group_user` 的 status 状态 if len(userIds) == 0 { db.DB.Model(model.GroupUser{}).Where("group_id = ?", groupId).Updates(model.GroupUserV2{Status: sql.NullInt32{Int32: int32(pb.GroupUserStatusType_GROUP_USER_STATUS_NORMAL), Valid: true}}) } else { db.DB.Model(model.GroupUser{}).Where("user_id in (?) and group_id = ?", userIds, groupId).Updates(model.GroupUserV2{Status: sql.NullInt32{Int32: int32(pb.GroupUserStatusType_GROUP_USER_STATUS_Banned), Valid: true}}) db.DB.Model(model.GroupUser{}).Where("(user_id) not in (?) and group_id = ?", userIds, groupId).Updates(model.GroupUserV2{Status: sql.NullInt32{Int32: int32(pb.GroupUserStatusType_GROUP_USER_STATUS_NORMAL), Valid: true}}) } //3、删除缓存 err := repo.GroupCache.Del(groupId) if err != nil { return nil, err } //4、发送推送消息 for _, u := range userIds { err = group.PushGroupMemberBanned(ctx, optId, u, isAllMemberBanned) if err != nil { return nil, err } } } // 查询被禁言的成员列表 group, err = repo.GroupRepo.GetForBanned(groupId) if err != nil { return nil, err } return group.GetMembers(ctx) } // SetGroupMemberRemoveBanned 设置取消禁言 func (*groupApp) SetGroupMemberRemoveBanned(ctx context.Context, optId, groupId int64, removeUserIds []int64) error { groupUser, err := repo.GroupUserRepo.Get(groupId, optId) if err != nil { return err } if groupUser == nil { return errors.New("未查询到群组用户信息") } if groupUser.MemberType != int(pb.MemberType_GMT_ADMIN) && groupUser.MemberType != int(pb.MemberType_GMT_MANAGE) { return errors.New("非管理员操作") } group, err := repo.GroupRepo.Get(groupId) if err != nil { return err } if len(removeUserIds) > 0 { //1、更新 `group_user` 的 status 状态 db.DB.Model(model.GroupUser{}).Where("user_id in (?) and group_id = ?", removeUserIds, groupId).Updates(model.GroupUserV2{Status: sql.NullInt32{Int32: int32(pb.GroupUserStatusType_GROUP_USER_STATUS_NORMAL), Valid: true}}) //2、删除缓存 err := repo.GroupCache.Del(groupId) if err != nil { return err } //3、给取消禁言用户推送消息 for _, u := range removeUserIds { err = group.PushGroupMemberRemoveBanned(ctx, optId, u) if err != nil { return err } } } return nil } // RecallSendMessage 撤回发送消息 func (*groupApp) RecallSendMessage(ctx context.Context, sender *pb.Sender, req *pb.RecallMessageReq) (int64, error) { group, err := repo.GroupRepo.Get(req.ReceiverId) if err != nil { return 0, err } return group.RecallSendMessage(ctx, sender, req) } // SendRedPackage 发送红包消息 func (*groupApp) SendRedPackage(ctx context.Context, sender *pb.Sender, req *pb.SendRedPacketReq) (int64, error) { group, err := repo.GroupRepo.Get(req.ReceiverId) if err != nil { return 0, err } return group.SendRedPackage(ctx, sender, req) } // SetGroupAddFriend 设置是否加好友 func (*groupApp) SetGroupAddFriend(ctx context.Context, optId int64, req *pb.SetGroupAddFriendReq) error { //1、判断是否为管理员操作 groupUser, err := repo.GroupUserRepo.Get(req.GroupId, optId) if err != nil { return err } if groupUser == nil { return errors.New("未查询到群组用户信息") } if groupUser.MemberType != int(pb.MemberType_GMT_ADMIN) && groupUser.MemberType != int(pb.MemberType_GMT_MANAGE) { return errors.New("非管理员操作") } //group, err := repo.GroupRepo.Get(req.GroupId) //if err != nil { // return err //} //2、更改群组信息 db.DB.Model(model.Group{}).Where("id = ?", req.GroupId).Updates(model.Group{IsAllAddFriend: int32(req.IsAllAddFriend)}) //3、删除缓存 err = repo.GroupCache.Del(req.GroupId) if err != nil { return err } ////4、发送推送消息 //for _, u := range userIds { // err = group.PushGroupMemberBanned(ctx, optId, u, isAllMemberBanned) // if err != nil { // return nil, err // } //} return nil }