diff --git a/internal/rpc/group/copy.go b/internal/rpc/group/copy.go index 4fbabec7b..259e2999f 100644 --- a/internal/rpc/group/copy.go +++ b/internal/rpc/group/copy.go @@ -81,10 +81,10 @@ func DbToPbGroupRequest(m *relation.GroupRequestModel, user *open_im_sdk.PublicU } } -func DbToPbGroupAbstractInfo(groupID string, groupMemberNumber int32, groupMemberListHash uint64) *pbGroup.GroupAbstractInfo { +func DbToPbGroupAbstractInfo(groupID string, groupMemberNumber uint32, groupMemberListHash uint64) *pbGroup.GroupAbstractInfo { return &pbGroup.GroupAbstractInfo{ GroupID: groupID, - GroupMemberNumber: uint32(groupMemberNumber), + GroupMemberNumber: groupMemberNumber, GroupMemberListHash: groupMemberListHash, } } diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index caf3866d2..08a32bc35 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -22,7 +22,6 @@ import ( "context" "fmt" grpcPrometheus "github.com/grpc-ecosystem/go-grpc-prometheus" - "math/big" "net" "strconv" "strings" @@ -977,7 +976,9 @@ func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbGroup.SetGr delete(duplicateMap, [...]string{member.GroupID, member.UserID}) } if len(duplicateMap) > 0 { - return nil, constant.ErrArgs.Wrap("group not found or user not in group") + return nil, constant.ErrArgs.Wrap("group not found" + strings.Join(utils.Slice(utils.Keys(duplicateMap), func(e [2]string) string { + return fmt.Sprintf("[group: %s user: %s]", e[0], e[1]) + }), ",")) } memberMap := utils.SliceToMap(members, func(e *relationTb.GroupMemberModel) [2]string { return [...]string{e.GroupID, e.UserID} @@ -1038,16 +1039,21 @@ func (s *groupServer) GetGroupAbstractInfo(ctx context.Context, req *pbGroup.Get if err != nil { return nil, err } + if ids := utils.Single(req.GroupIDs, utils.Slice(groups, func(group *relationTb.GroupModel) string { + return group.GroupID + })); len(ids) > 0 { + return nil, constant.ErrGroupIDNotFound.Wrap("not found group " + strings.Join(ids, ",")) + } groupUserMap, err := s.GroupInterface.MapGroupMemberUserID(ctx, req.GroupIDs) if err != nil { return nil, err } - resp.GroupAbstractInfos = utils.Slice(groups, func(e *relationTb.GroupModel) *pbGroup.GroupAbstractInfo { - userIDs := groupUserMap[e.GroupID] - utils.Sort(userIDs, true) - bi := big.NewInt(0) - bi.SetString(utils.Md5(strings.Join(userIDs, ";;"))[0:8], 16) - return DbToPbGroupAbstractInfo(e.GroupID, int32(len(userIDs)), bi.Uint64()) + if ids := utils.Single(req.GroupIDs, utils.Keys(groupUserMap)); len(ids) > 0 { + return nil, constant.ErrGroupIDNotFound.Wrap(fmt.Sprintf("group %s not found member", strings.Join(ids, ","))) + } + resp.GroupAbstractInfos = utils.Slice(groups, func(group *relationTb.GroupModel) *pbGroup.GroupAbstractInfo { + users := groupUserMap[group.GroupID] + return DbToPbGroupAbstractInfo(group.GroupID, uint32(len(users.UserIDs)), users.Hash) }) return resp, nil } diff --git a/pkg/common/db/cache/group.go b/pkg/common/db/cache/group.go index 2b9c2c04e..c5a9ef51b 100644 --- a/pkg/common/db/cache/group.go +++ b/pkg/common/db/cache/group.go @@ -106,7 +106,7 @@ func (g *GroupCacheRedis) getGroupMemberNumKey(groupID string) string { // / groupInfo func (g *GroupCacheRedis) GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*relationTb.GroupModel, err error) { - return GetCacheFor(ctx, g.rcClient, groupIDs, func(ctx context.Context, groupID string) (*relationTb.GroupModel, error) { + return GetCacheFor(ctx, groupIDs, func(ctx context.Context, groupID string) (*relationTb.GroupModel, error) { return g.GetGroupInfo(ctx, groupID) }) } @@ -151,28 +151,20 @@ func (g *GroupCacheRedis) DelJoinedSuperGroupIDs(ctx context.Context, userID str } func (g *GroupCacheRedis) GetJoinedSuperGroupIDs(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error) { - getJoinedSuperGroupIDList := func() (string, error) { - userToSuperGroup, err := g.mongoDB.GetSuperGroupByUserID(ctx, userID) + return GetCache(ctx, g.rcClient, g.getJoinedSuperGroupsIDKey(userID), g.expireTime, func(ctx context.Context) ([]string, error) { + userGroup, err := g.mongoDB.GetSuperGroupByUserID(ctx, userID) if err != nil { - return "", err + return nil, err } - bytes, err := json.Marshal(userToSuperGroup.GroupIDList) - if err != nil { - return "", utils.Wrap(err, "") - } - return string(bytes), nil - } - defer func() { - tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID, "joinedSuperGroupIDs", joinedSuperGroupIDs) - }() - joinedSuperGroupListStr, err := g.rcClient.Fetch(g.getJoinedSuperGroupsIDKey(userID), time.Second*30*60, getJoinedSuperGroupIDList) - if err != nil { - return nil, err - } - err = json.Unmarshal([]byte(joinedSuperGroupListStr), &joinedSuperGroupIDs) - return joinedSuperGroupIDs, utils.Wrap(err, "") + return userGroup.GroupIDs, nil + }) } +//// groupMembersHash +//func (g *GroupCacheRedis) GetGroupsMembersHash(ctx context.Context, groupIDs []string) (map[string]uint64, error) { +// return GetCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, "") +//} + // groupMembersHash func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCodeUint64 uint64, err error) { generateHash := func() (string, error) { diff --git a/pkg/common/db/cache/utils.go b/pkg/common/db/cache/utils.go index 237ee07f8..d007ff58a 100644 --- a/pkg/common/db/cache/utils.go +++ b/pkg/common/db/cache/utils.go @@ -36,7 +36,7 @@ func GetCache[T any](ctx context.Context, rcClient *rockscache.Client, key strin return t, nil } -func GetCacheFor[E any, T any](ctx context.Context, rcClient *rockscache.Client, list []E, fn func(ctx context.Context, item E) (T, error)) ([]T, error) { +func GetCacheFor[E any, T any](ctx context.Context, list []E, fn func(ctx context.Context, item E) (T, error)) ([]T, error) { rs := make([]T, 0, len(list)) for _, e := range list { r, err := fn(ctx, e) diff --git a/pkg/common/db/controller/group.go b/pkg/common/db/controller/group.go index 4edb6e4fa..96085d128 100644 --- a/pkg/common/db/controller/group.go +++ b/pkg/common/db/controller/group.go @@ -15,6 +15,8 @@ import ( "github.com/go-redis/redis/v8" "go.mongodb.org/mongo-driver/mongo" "gorm.io/gorm" + "math/big" + "strings" ) //type GroupInterface GroupDataBaseInterface @@ -25,6 +27,11 @@ type BatchUpdateGroupMember struct { Map map[string]any } +type GroupSimpleUserID struct { + Hash uint64 + UserIDs []string +} + type GroupInterface interface { CreateGroup(ctx context.Context, groups []*relationTb.GroupModel, groupMembers []*relationTb.GroupMemberModel) error TakeGroup(ctx context.Context, groupID string) (group *relationTb.GroupModel, err error) @@ -41,7 +48,7 @@ type GroupInterface interface { SearchGroupMember(ctx context.Context, keyword string, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (uint32, []*relationTb.GroupMemberModel, error) HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationTb.GroupMemberModel) error DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error - MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string][]string, error) + MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*GroupSimpleUserID, error) MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string, roleLevel int32) error // 转让群 UpdateGroupMember(ctx context.Context, groupID string, userID string, data map[string]any) error @@ -125,7 +132,7 @@ func (g *GroupController) DeleteGroupMember(ctx context.Context, groupID string, return g.database.DeleteGroupMember(ctx, groupID, userIDs) } -func (g *GroupController) MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string][]string, error) { +func (g *GroupController) MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*GroupSimpleUserID, error) { return g.database.MapGroupMemberUserID(ctx, groupIDs) } @@ -197,7 +204,7 @@ type GroupDataBaseInterface interface { SearchGroupMember(ctx context.Context, keyword string, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (uint32, []*relationTb.GroupMemberModel, error) HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationTb.GroupMemberModel) error DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error - MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string][]string, error) + MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*GroupSimpleUserID, error) MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string, roleLevel int32) error // 转让群 UpdateGroupMember(ctx context.Context, groupID string, userID string, data map[string]any) error @@ -386,8 +393,24 @@ func (g *GroupDataBase) DeleteGroupMember(ctx context.Context, groupID string, u }) } -func (g *GroupDataBase) MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string][]string, error) { - return g.groupMemberDB.FindJoinUserID(ctx, groupIDs) +func (g *GroupDataBase) MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*GroupSimpleUserID, error) { + mapGroupUserIDs, err := g.groupMemberDB.FindJoinUserID(ctx, groupIDs) + if err != nil { + return nil, err + } + res := make(map[string]*GroupSimpleUserID) + for _, groupID := range groupIDs { + users := &GroupSimpleUserID{ + UserIDs: mapGroupUserIDs[groupID], + } + if len(users.UserIDs) > 0 { + utils.Sort(users.UserIDs, true) + bi := big.NewInt(0) + bi.SetString(utils.Md5(strings.Join(users.UserIDs, ";"))[0:8], 16) + } + res[groupID] = users + } + return res, nil } func (g *GroupDataBase) MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) {