diff --git a/pkg/common/db/cache/group.go b/pkg/common/db/cache/group.go index 505e7785e..6a31fd377 100644 --- a/pkg/common/db/cache/group.go +++ b/pkg/common/db/cache/group.go @@ -16,6 +16,10 @@ package cache import ( "context" + "fmt" + "github.com/OpenIMSDK/protocol/constant" + "github.com/OpenIMSDK/tools/errs" + "strconv" "time" "github.com/OpenIMSDK/tools/log" @@ -34,8 +38,10 @@ const ( groupMemberIDsKey = "GROUP_MEMBER_IDS:" groupMembersHashKey = "GROUP_MEMBERS_HASH2:" groupMemberInfoKey = "GROUP_MEMBER_INFO:" - joinedGroupsKey = "JOIN_GROUPS_KEY:" - groupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:" + //groupOwnerInfoKey = "GROUP_OWNER_INFO:" + joinedGroupsKey = "JOIN_GROUPS_KEY:" + groupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:" + groupRoleLevelMemberIDsKey = "GROUP_ROLE_LEVEL_MEMBER_IDS:" ) type GroupCache interface { @@ -61,9 +67,15 @@ type GroupCache interface { GetGroupMembersInfo(ctx context.Context, groupID string, userID []string) (groupMembers []*relationtb.GroupMemberModel, err error) GetAllGroupMembersInfo(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error) GetGroupMembersPage(ctx context.Context, groupID string, userID []string, showNumber, pageNumber int32) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error) + FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) ([]*relationtb.GroupMemberModel, error) + GetGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) + GetGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) + DelGroupRoleLevel(groupID string, roleLevel []int32) GroupCache + DelGroupAllRoleLevel(groupID string) GroupCache DelGroupMembersInfo(groupID string, userID ...string) GroupCache - + GetGroupRoleLevelMemberInfo(ctx context.Context, groupID string, roleLevel int32) ([]*relationtb.GroupMemberModel, error) + GetGroupRolesLevelMemberInfo(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) GetGroupMemberNum(ctx context.Context, groupID string) (memberNum int64, err error) DelGroupsMemberNum(groupID ...string) GroupCache } @@ -131,6 +143,10 @@ func (g *GroupCacheRedis) getGroupMemberNumKey(groupID string) string { return groupMemberNumKey + groupID } +func (g *GroupCacheRedis) getGroupRoleLevelMemberIDsKey(groupID string, roleLevel int32) string { + return groupRoleLevelMemberIDsKey + groupID + "-" + strconv.Itoa(int(roleLevel)) +} + func (g *GroupCacheRedis) GetGroupIndex(group *relationtb.GroupModel, keys []string) (int, error) { key := g.getGroupInfoKey(group.GroupID) for i, _key := range keys { @@ -153,7 +169,7 @@ func (g *GroupCacheRedis) GetGroupMemberIndex(groupMember *relationtb.GroupMembe return 0, errIndex } -// / groupInfo. +// groupInfo. func (g *GroupCacheRedis) GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) { return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string { return g.getGroupInfoKey(groupID) @@ -179,6 +195,31 @@ func (g *GroupCacheRedis) DelGroupsInfo(groupIDs ...string) GroupCache { return newGroupCache } +func (g *GroupCacheRedis) DelGroupsOwner(groupIDs ...string) GroupCache { + newGroupCache := g.NewCache() + keys := make([]string, 0, len(groupIDs)) + for _, groupID := range groupIDs { + keys = append(keys, g.getGroupRoleLevelMemberIDsKey(groupID, constant.GroupOwner)) + } + newGroupCache.AddKeys(keys...) + + return newGroupCache +} + +func (g *GroupCacheRedis) DelGroupRoleLevel(groupID string, roleLevels []int32) GroupCache { + newGroupCache := g.NewCache() + keys := make([]string, 0, len(roleLevels)) + for _, roleLevel := range roleLevels { + keys = append(keys, g.getGroupRoleLevelMemberIDsKey(groupID, roleLevel)) + } + newGroupCache.AddKeys(keys...) + return newGroupCache +} + +func (g *GroupCacheRedis) DelGroupAllRoleLevel(groupID string) GroupCache { + return g.DelGroupRoleLevel(groupID, []int32{constant.GroupOwner, constant.GroupAdmin, constant.GroupOrdinaryUsers}) +} + // groupMembersHash. func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) { return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, func(ctx context.Context) (uint64, error) { @@ -211,7 +252,6 @@ func (g *GroupCacheRedis) DelGroupMembersHash(groupID string) GroupCache { return cache } -// groupMemberIDs. func (g *GroupCacheRedis) GetGroupMemberIDs(ctx context.Context, groupID string) (groupMemberIDs []string, err error) { return getCache(ctx, g.rcClient, g.getGroupMemberIDsKey(groupID), g.expireTime, func(ctx context.Context) ([]string, error) { return g.groupMemberDB.FindMemberUserID(ctx, groupID) @@ -269,12 +309,7 @@ func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, groupID strin }) } -func (g *GroupCacheRedis) GetGroupMembersPage( - ctx context.Context, - groupID string, - userIDs []string, - showNumber, pageNumber int32, -) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error) { +func (g *GroupCacheRedis) GetGroupMembersPage(ctx context.Context, groupID string, userIDs []string, showNumber, pageNumber int32) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error) { groupMemberIDs, err := g.GetGroupMemberIDs(ctx, groupID) if err != nil { return 0, nil, err @@ -333,3 +368,68 @@ func (g *GroupCacheRedis) DelGroupsMemberNum(groupID ...string) GroupCache { return cache } + +func (g *GroupCacheRedis) GetGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) { + members, err := g.GetGroupRoleLevelMemberInfo(ctx, groupID, constant.GroupOwner) + if err != nil { + return nil, err + } + if len(members) == 0 { + return nil, errs.ErrRecordNotFound.Wrap(fmt.Sprintf("group %s owner not found", groupID)) + } + return members[0], nil +} + +func (g *GroupCacheRedis) GetGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) { + members := make([]*relationtb.GroupMemberModel, 0, len(groupIDs)) + for _, groupID := range groupIDs { + items, err := g.GetGroupRoleLevelMemberInfo(ctx, groupID, constant.GroupOwner) + if err != nil { + return nil, err + } + if len(items) > 0 { + members = append(members, items[0]) + } + } + return members, nil +} + +func (g *GroupCacheRedis) GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) { + return getCache(ctx, g.rcClient, g.getGroupRoleLevelMemberIDsKey(groupID, roleLevel), g.expireTime, func(ctx context.Context) ([]string, error) { + return g.groupMemberDB.FindRoleLevelUserIDs(ctx, groupID, roleLevel) + }) +} + +func (g *GroupCacheRedis) GetGroupRoleLevelMemberInfo(ctx context.Context, groupID string, roleLevel int32) ([]*relationtb.GroupMemberModel, error) { + userIDs, err := g.GetGroupRoleLevelMemberIDs(ctx, groupID, roleLevel) + if err != nil { + return nil, err + } + return g.GetGroupMembersInfo(ctx, groupID, userIDs) +} + +func (g *GroupCacheRedis) GetGroupRolesLevelMemberInfo(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) { + var userIDs []string + for _, roleLevel := range roleLevels { + ids, err := g.GetGroupRoleLevelMemberIDs(ctx, groupID, roleLevel) + if err != nil { + return nil, err + } + userIDs = append(userIDs, ids...) + } + return g.GetGroupMembersInfo(ctx, groupID, userIDs) +} + +func (g *GroupCacheRedis) FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) (_ []*relationtb.GroupMemberModel, err error) { + if len(groupIDs) == 0 { + groupIDs, err = g.GetJoinedGroupIDs(ctx, userID) + if err != nil { + return nil, err + } + } + return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string { + return g.getGroupMemberInfoKey(groupID, userID) + }, func(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) { + return g.groupMemberDB.Take(ctx, groupID, userID) + }) +} diff --git a/pkg/common/db/cache/meta_cache.go b/pkg/common/db/cache/meta_cache.go index ccac88d68..4bc2a046a 100644 --- a/pkg/common/db/cache/meta_cache.go +++ b/pkg/common/db/cache/meta_cache.go @@ -38,7 +38,7 @@ const ( var errIndex = errors.New("err index") type metaCache interface { - ExecDel(ctx context.Context) error + ExecDel(ctx context.Context, distinct ...bool) error // delete key rapid DelKey(ctx context.Context, key string) error AddKeys(keys ...string) @@ -57,7 +57,10 @@ type metaCacheRedis struct { retryInterval time.Duration } -func (m *metaCacheRedis) ExecDel(ctx context.Context) error { +func (m *metaCacheRedis) ExecDel(ctx context.Context, distinct ...bool) error { + if len(distinct) > 0 && distinct[0] { + m.keys = utils.Distinct(m.keys) + } if len(m.keys) > 0 { log.ZDebug(ctx, "delete cache", "keys", m.keys) for _, key := range m.keys { diff --git a/pkg/common/db/controller/group.go b/pkg/common/db/controller/group.go index 041a04967..5060ed9c3 100644 --- a/pkg/common/db/controller/group.go +++ b/pkg/common/db/controller/group.go @@ -16,7 +16,6 @@ package controller import ( "context" - "fmt" "github.com/dtm-labs/rockscache" "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" @@ -95,16 +94,24 @@ type groupDatabase struct { cache cache.GroupCache } -func (g *groupDatabase) FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error) { - return g.cache.GetGroupMemberIDs(ctx, groupID) +func (g *groupDatabase) FindGroupMembers(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupMemberModel, error) { + return g.cache.GetGroupMembersInfo(ctx, groupID, userIDs) } -func (g *groupDatabase) FindGroupMemberNum(ctx context.Context, groupID string) (uint32, error) { - num, err := g.cache.GetGroupMemberNum(ctx, groupID) - if err != nil { - return 0, err - } - return uint32(num), nil +func (g *groupDatabase) FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) ([]*relationtb.GroupMemberModel, error) { + return g.cache.FindGroupMemberUser(ctx, groupIDs, userID) +} + +func (g *groupDatabase) FindGroupMemberRoleLevels(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) { + return g.cache.GetGroupRolesLevelMemberInfo(ctx, groupID, roleLevels) +} + +func (g *groupDatabase) FindGroupMemberAll(ctx context.Context, groupID string) ([]*relationtb.GroupMemberModel, error) { + return g.cache.GetAllGroupMembersInfo(ctx, groupID) +} + +func (g *groupDatabase) FindGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) { + return g.cache.GetGroupsOwner(ctx, groupIDs) } func (g *groupDatabase) CreateGroup(ctx context.Context, groups []*relationtb.GroupModel, groupMembers []*relationtb.GroupMemberModel) error { @@ -118,37 +125,48 @@ func (g *groupDatabase) CreateGroup(ctx context.Context, groups []*relationtb.Gr return err } for _, group := range groups { - c = c.DelGroupsInfo(group.GroupID) - c = c.DelGroupMembersHash(group.GroupID) - c = c.DelGroupsMemberNum(group.GroupID) - c = c.DelGroupMemberIDs(group.GroupID) + c = c.DelGroupsInfo(group.GroupID). + DelGroupMembersHash(group.GroupID). + DelGroupMembersHash(group.GroupID). + DelGroupsMemberNum(group.GroupID). + DelGroupMemberIDs(group.GroupID). + DelGroupAllRoleLevel(group.GroupID) } } if len(groupMembers) > 0 { if err := g.groupMemberDB.Create(ctx, groupMembers); err != nil { return err } - temp := make(map[string]struct{}) for _, groupMember := range groupMembers { - if _, ok := temp[groupMember.GroupID]; !ok { - temp[groupMember.GroupID] = struct{}{} - c = c.DelGroupMembersHash(groupMember.GroupID) - c = c.DelGroupsMemberNum(groupMember.GroupID) - c = c.DelGroupMemberIDs(groupMember.GroupID) - } - c = c.DelJoinedGroupID(groupMember.UserID) - c = c.DelGroupMembersInfo(groupMember.GroupID, groupMember.UserID) + c = c.DelGroupMembersHash(groupMember.GroupID). + DelGroupsMemberNum(groupMember.GroupID). + DelGroupMemberIDs(groupMember.GroupID). + DelJoinedGroupID(groupMember.UserID). + DelGroupMembersInfo(groupMember.GroupID, groupMember.UserID). + DelGroupAllRoleLevel(groupMember.GroupID) } } - return c.ExecDel(ctx) + return c.ExecDel(ctx, true) }) } -func (g *groupDatabase) TakeGroup(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error) { +func (g *groupDatabase) FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error) { + return g.cache.GetGroupMemberIDs(ctx, groupID) +} + +func (g *groupDatabase) FindGroupMemberNum(ctx context.Context, groupID string) (uint32, error) { + num, err := g.cache.GetGroupMemberNum(ctx, groupID) + if err != nil { + return 0, err + } + return uint32(num), nil +} + +func (g *groupDatabase) TakeGroup(ctx context.Context, groupID string) (*relationtb.GroupModel, error) { return g.cache.GetGroupInfo(ctx, groupID) } -func (g *groupDatabase) FindGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) { +func (g *groupDatabase) FindGroup(ctx context.Context, groupIDs []string) ([]*relationtb.GroupModel, error) { return g.cache.GetGroupsInfo(ctx, groupIDs) } @@ -164,39 +182,36 @@ func (g *groupDatabase) UpdateGroup(ctx context.Context, groupID string, data ma } func (g *groupDatabase) DismissGroup(ctx context.Context, groupID string, deleteMember bool) error { - cache := g.cache.NewCache() - if err := g.tx.Transaction(func(tx any) error { - if err := g.groupDB.NewTx(tx).UpdateStatus(ctx, groupID, constant.GroupStatusDismissed); err != nil { + return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { + c := g.cache.NewCache() + if err := g.groupDB.UpdateState(ctx, groupID, constant.GroupStatusDismissed); err != nil { return err } if deleteMember { - if err := g.groupMemberDB.NewTx(tx).DeleteGroup(ctx, []string{groupID}); err != nil { - return err - } userIDs, err := g.cache.GetGroupMemberIDs(ctx, groupID) if err != nil { return err } - cache = cache.DelJoinedGroupID(userIDs...).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelGroupMembersHash(groupID) + if err := g.groupMemberDB.Delete(ctx, groupID, nil); err != nil { + return err + } + c = c.DelJoinedGroupID(userIDs...). + DelGroupMemberIDs(groupID). + DelGroupsMemberNum(groupID). + DelGroupMembersHash(groupID). + DelGroupAllRoleLevel(groupID). + DelGroupMembersInfo(groupID, userIDs...) } - cache = cache.DelGroupsInfo(groupID) - return nil - }); err != nil { - return err - } - return cache.ExecDel(ctx) + return c.DelGroupsInfo(groupID).ExecDel(ctx) + }) } -func (g *groupDatabase) TakeGroupMember( - ctx context.Context, - groupID string, - userID string, -) (groupMember *relationtb.GroupMemberModel, err error) { +func (g *groupDatabase) TakeGroupMember(ctx context.Context, groupID string, userID string) (*relationtb.GroupMemberModel, error) { return g.cache.GetGroupMemberInfo(ctx, groupID, userID) } func (g *groupDatabase) TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) { - return g.groupMemberDB.TakeOwner(ctx, groupID) // todo cache group owner + return g.cache.GetGroupOwner(ctx, groupID) } func (g *groupDatabase) FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) { @@ -207,112 +222,57 @@ func (g *groupDatabase) PageGroupRequest(ctx context.Context, groupIDs []string, return g.groupRequestDB.PageGroup(ctx, groupIDs, pagination) } -func (g *groupDatabase) FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) (totalGroupMembers []*relationtb.GroupMemberModel, err error) { - if len(groupIDs) == 0 && len(roleLevels) == 0 && len(userIDs) == 1 { - gIDs, err := g.cache.GetJoinedGroupIDs(ctx, userIDs[0]) - if err != nil { - return nil, err - } - var res []*relationtb.GroupMemberModel - for _, groupID := range gIDs { - v, err := g.cache.GetGroupMemberInfo(ctx, groupID, userIDs[0]) - if err != nil { - return nil, err - } - res = append(res, v) - } - return res, nil - } - if len(roleLevels) == 0 { - for _, groupID := range groupIDs { - groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, userIDs) - if err != nil { - return nil, err - } - totalGroupMembers = append(totalGroupMembers, groupMembers...) - } - return totalGroupMembers, nil - } - return g.groupMemberDB.Find(ctx, groupIDs, userIDs, roleLevels) -} - -func (g *groupDatabase) PageGetJoinGroup( - ctx context.Context, - userID string, - pagination pagination.Pagination, -) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) { +func (g *groupDatabase) PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) { groupIDs, err := g.cache.GetJoinedGroupIDs(ctx, userID) if err != nil { return 0, nil, err } - for _, groupID := range utils.Paginate(groupIDs, int(pageNumber), int(showNumber)) { + for _, groupID := range utils.Paginate(groupIDs, int(pagination.GetPageNumber()), int(pagination.GetShowNumber())) { groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, []string{userID}) if err != nil { return 0, nil, err } totalGroupMembers = append(totalGroupMembers, groupMembers...) } - return uint32(len(groupIDs)), totalGroupMembers, nil + return int64(len(groupIDs)), totalGroupMembers, nil } -func (g *groupDatabase) PageGetGroupMember( - ctx context.Context, - groupID string, - pagination pagination.Pagination, -) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) { +func (g *groupDatabase) PageGetGroupMember(ctx context.Context, groupID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) { groupMemberIDs, err := g.cache.GetGroupMemberIDs(ctx, groupID) if err != nil { return 0, nil, err } - pageIDs := utils.Paginate(groupMemberIDs, int(pageNumber), int(showNumber)) + pageIDs := utils.Paginate(groupMemberIDs, int(pagination.GetPageNumber()), int(pagination.GetShowNumber())) if len(pageIDs) == 0 { - return uint32(len(groupMemberIDs)), nil, nil + return int64(len(groupMemberIDs)), nil, nil } members, err := g.cache.GetGroupMembersInfo(ctx, groupID, pageIDs) if err != nil { return 0, nil, err } - return uint32(len(groupMemberIDs)), members, nil + return int64(len(groupMemberIDs)), members, nil } func (g *groupDatabase) SearchGroupMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (int64, []*relationtb.GroupMemberModel, error) { - return g.groupMemberDB.SearchMember(ctx, keyword, groupIDs, userIDs, roleLevels, pagination) + return g.groupMemberDB.SearchMember(ctx, keyword, groupID, pagination) } -func (g *groupDatabase) HandlerGroupRequest( - ctx context.Context, - groupID string, - userID string, - handledMsg string, - handleResult int32, - member *relationtb.GroupMemberModel, -) error { - //cache := g.cache.NewCache() - //if err := g.tx.Transaction(func(tx any) error { - // if err := g.groupRequestDB.NewTx(tx).UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil { - // return err - // } - // if member != nil { - // if err := g.groupMemberDB.NewTx(tx).Create(ctx, []*relationtb.GroupMemberModel{member}); err != nil { - // return err - // } - // cache = cache.DelGroupMembersHash(groupID).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelJoinedGroupID(member.UserID) - // } - // return nil - //}); err != nil { - // return err - //} - //return cache.ExecDel(ctx) - - return g.tx.Transaction(func(tx any) error { - if err := g.groupRequestDB.NewTx(tx).UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil { +func (g *groupDatabase) HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationtb.GroupMemberModel) error { + return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { + if err := g.groupRequestDB.UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil { return err } if member != nil { - if err := g.groupMemberDB.NewTx(tx).Create(ctx, []*relationtb.GroupMemberModel{member}); err != nil { + if err := g.groupMemberDB.Create(ctx, []*relationtb.GroupMemberModel{member}); err != nil { return err } - if err := g.cache.NewCache().DelGroupMembersHash(groupID).DelGroupMembersInfo(groupID, member.UserID).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelJoinedGroupID(member.UserID).ExecDel(ctx); err != nil { + c := g.cache.DelGroupMembersHash(groupID). + DelGroupMembersInfo(groupID, member.UserID). + DelGroupMemberIDs(groupID). + DelGroupsMemberNum(groupID). + DelJoinedGroupID(member.UserID). + DelGroupRoleLevel(groupID, []int32{member.RoleLevel}) + if err := c.ExecDel(ctx); err != nil { return err } } @@ -329,13 +289,11 @@ func (g *groupDatabase) DeleteGroupMember(ctx context.Context, groupID string, u DelGroupsMemberNum(groupID). DelJoinedGroupID(userIDs...). DelGroupMembersInfo(groupID, userIDs...). + DelGroupAllRoleLevel(groupID). ExecDel(ctx) } -func (g *groupDatabase) MapGroupMemberUserID( - ctx context.Context, - groupIDs []string, -) (map[string]*relationtb.GroupSimpleUserID, error) { +func (g *groupDatabase) MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) { return g.cache.GetGroupMemberHashMap(ctx, groupIDs) } @@ -352,62 +310,54 @@ func (g *groupDatabase) MapGroupMemberNum(ctx context.Context, groupIDs []string } func (g *groupDatabase) TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string, roleLevel int32) error { - return g.tx.Transaction(func(tx any) error { - rowsAffected, err := g.groupMemberDB.NewTx(tx).UpdateRoleLevel(ctx, groupID, oldOwnerUserID, roleLevel) - if err != nil { + return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { + if err := g.groupMemberDB.UpdateRoleLevel(ctx, groupID, oldOwnerUserID, roleLevel); err != nil { return err } - if rowsAffected != 1 { - return utils.Wrap(fmt.Errorf("oldOwnerUserID %s rowsAffected = %d", oldOwnerUserID, rowsAffected), "") - } - rowsAffected, err = g.groupMemberDB.NewTx(tx).UpdateRoleLevel(ctx, groupID, newOwnerUserID, constant.GroupOwner) - if err != nil { + if err := g.groupMemberDB.UpdateRoleLevel(ctx, groupID, newOwnerUserID, constant.GroupOwner); err != nil { return err } - if rowsAffected != 1 { - return utils.Wrap(fmt.Errorf("newOwnerUserID %s rowsAffected = %d", newOwnerUserID, rowsAffected), "") - } - return g.cache.DelGroupMembersInfo(groupID, oldOwnerUserID, newOwnerUserID).DelGroupMembersHash(groupID).ExecDel(ctx) + return g.cache.DelGroupMembersInfo(groupID, oldOwnerUserID, newOwnerUserID). + DelGroupAllRoleLevel(groupID). + DelGroupMembersHash(groupID).ExecDel(ctx) }) } -func (g *groupDatabase) UpdateGroupMember( - ctx context.Context, - groupID string, - userID string, - data map[string]any, -) error { +func (g *groupDatabase) UpdateGroupMember(ctx context.Context, groupID string, userID string, data map[string]any) error { if err := g.groupMemberDB.Update(ctx, groupID, userID, data); err != nil { return err } - return g.cache.DelGroupMembersInfo(groupID, userID).ExecDel(ctx) + c := g.cache.DelGroupMembersInfo(groupID, userID) + if g.groupMemberDB.IsUpdateRoleLevel(data) { + c = c.DelGroupAllRoleLevel(groupID) + } + return c.ExecDel(ctx) } func (g *groupDatabase) UpdateGroupMembers(ctx context.Context, data []*relationtb.BatchUpdateGroupMember) error { - cache := g.cache.NewCache() - if err := g.tx.Transaction(func(tx any) error { + return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { + c := g.cache.NewCache() for _, item := range data { - if err := g.groupMemberDB.NewTx(tx).Update(ctx, item.GroupID, item.UserID, item.Map); err != nil { + if err := g.groupMemberDB.Update(ctx, item.GroupID, item.UserID, item.Map); err != nil { return err } - cache = cache.DelGroupMembersInfo(item.GroupID, item.UserID) + if g.groupMemberDB.IsUpdateRoleLevel(item.Map) { + c = c.DelGroupAllRoleLevel(item.GroupID) + } + c = c.DelGroupMembersInfo(item.GroupID, item.UserID).DelGroupMembersHash(item.GroupID) } - return nil - }); err != nil { - return err - } - return cache.ExecDel(ctx) + return c.ExecDel(ctx, true) + }) } func (g *groupDatabase) CreateGroupRequest(ctx context.Context, requests []*relationtb.GroupRequestModel) error { - return g.tx.Transaction(func(tx any) error { - db := g.groupRequestDB.NewTx(tx) + return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { for _, request := range requests { - if err := db.Delete(ctx, request.GroupID, request.UserID); err != nil { + if err := g.groupRequestDB.Delete(ctx, request.GroupID, request.UserID); err != nil { return err } } - return db.Create(ctx, requests) + return g.groupRequestDB.Create(ctx, requests) }) } @@ -419,12 +369,8 @@ func (g *groupDatabase) TakeGroupRequest( return g.groupRequestDB.Take(ctx, groupID, userID) } -func (g *groupDatabase) PageGroupRequestUser( - ctx context.Context, - userID string, - pagination pagination.Pagination, -) (int64, []*relationtb.GroupRequestModel, error) { - return g.groupRequestDB.Page(ctx, userID, pageNumber, showNumber) +func (g *groupDatabase) PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) { + return g.groupRequestDB.Page(ctx, userID, pagination) } func (g *groupDatabase) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) { @@ -447,6 +393,5 @@ func (g *groupDatabase) DeleteGroupMemberHash(ctx context.Context, groupIDs []st for _, groupID := range groupIDs { c = c.DelGroupMembersHash(groupID) } - return c.ExecDel(ctx) } diff --git a/pkg/common/db/newmgo/group.go b/pkg/common/db/newmgo/group.go index be8a077b5..0b6a39982 100644 --- a/pkg/common/db/newmgo/group.go +++ b/pkg/common/db/newmgo/group.go @@ -24,6 +24,10 @@ func (g *GroupMgo) Create(ctx context.Context, groups []*relation.GroupModel) (e return mgotool.InsertMany(ctx, g.coll, groups) } +func (g *GroupMgo) UpdateState(ctx context.Context, groupID string, state int32) (err error) { + return g.UpdateMap(ctx, groupID, map[string]any{"state": state}) +} + func (g *GroupMgo) UpdateMap(ctx context.Context, groupID string, args map[string]any) (err error) { if len(args) == 0 { return nil diff --git a/pkg/common/db/newmgo/group_member.go b/pkg/common/db/newmgo/group_member.go index 3b9945e8f..2c2f96ba6 100644 --- a/pkg/common/db/newmgo/group_member.go +++ b/pkg/common/db/newmgo/group_member.go @@ -27,6 +27,10 @@ func (g *GroupMemberMgo) Delete(ctx context.Context, groupID string, userIDs []s return mgotool.DeleteMany(ctx, g.coll, bson.M{"group_id": groupID, "user_id": bson.M{"$in": userIDs}}) } +func (g *GroupMemberMgo) UpdateRoleLevel(ctx context.Context, groupID string, userID string, roleLevel int32) error { + return g.Update(ctx, groupID, userID, bson.M{"role_level": roleLevel}) +} + func (g *GroupMemberMgo) Update(ctx context.Context, groupID string, userID string, data map[string]any) (err error) { return mgotool.UpdateOne(ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}, bson.M{"$set": data}, true) } @@ -48,7 +52,11 @@ func (g *GroupMemberMgo) TakeOwner(ctx context.Context, groupID string) (groupMe return mgotool.FindOne[*relation.GroupMemberModel](ctx, g.coll, bson.M{"group_id": groupID, "role_level": constant.GroupOwner}) } -func (g *GroupMemberMgo) SearchMember(ctx context.Context, keyword string, groupIDs []string, userIDs []string, roleLevels []int32, pagination pagination.Pagination) (total int64, groupList []*relation.GroupMemberModel, err error) { +func (g *GroupMemberMgo) FindRoleLevelUserIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) { + return mgotool.Find[string](ctx, g.coll, bson.M{"group_id": groupID, "role_level": roleLevel}, options.Find().SetProjection(bson.M{"user_id": 1})) +} + +func (g *GroupMemberMgo) SearchMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (total int64, groupList []*relation.GroupMemberModel, err error) { //TODO implement me panic("implement me") } @@ -70,3 +78,11 @@ func (g *GroupMemberMgo) FindUserManagedGroupID(ctx context.Context, userID stri } return mgotool.Find[string](ctx, g.coll, filter, options.Find().SetProjection(bson.M{"group_id": 1})) } + +func (g *GroupMemberMgo) IsUpdateRoleLevel(data map[string]any) bool { + if len(data) == 0 { + return false + } + _, ok := data["role_level"] + return ok +} diff --git a/pkg/common/db/table/relation/group.go b/pkg/common/db/table/relation/group.go index d2a049a5c..f9afc06b0 100644 --- a/pkg/common/db/table/relation/group.go +++ b/pkg/common/db/table/relation/group.go @@ -67,12 +67,10 @@ func (GroupModel) TableName() string { type GroupModelInterface interface { Create(ctx context.Context, groups []*GroupModel) (err error) UpdateMap(ctx context.Context, groupID string, args map[string]any) (err error) - //UpdateStatus(ctx context.Context, groupID string, status int32) (err error) + UpdateState(ctx context.Context, groupID string, state int32) (err error) Find(ctx context.Context, groupIDs []string) (groups []*GroupModel, err error) - //FindNotDismissedGroup(ctx context.Context, groupIDs []string) (groups []*GroupModel, err error) Take(ctx context.Context, groupID string) (group *GroupModel, err error) Search(ctx context.Context, keyword string, pagination pagination.Pagination) (total int64, groups []*GroupModel, err error) - //GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) // 获取群总数 CountTotal(ctx context.Context, before *time.Time) (count int64, err error) // 获取范围内群增量 diff --git a/pkg/common/db/table/relation/group_member.go b/pkg/common/db/table/relation/group_member.go index ea1368e27..e35f2dd84 100644 --- a/pkg/common/db/table/relation/group_member.go +++ b/pkg/common/db/table/relation/group_member.go @@ -62,16 +62,17 @@ type GroupMemberModelInterface interface { Delete(ctx context.Context, groupID string, userIDs []string) (err error) //DeleteGroup(ctx context.Context, groupIDs []string) (err error) Update(ctx context.Context, groupID string, userID string, data map[string]any) (err error) - //UpdateRoleLevel(ctx context.Context, groupID string, userID string, roleLevel int32) (rowsAffected int64, err error) - Find(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) (groupMembers []*GroupMemberModel, err error) + UpdateRoleLevel(ctx context.Context, groupID string, userID string, roleLevel int32) error FindMemberUserID(ctx context.Context, groupID string) (userIDs []string, err error) Take(ctx context.Context, groupID string, userID string) (groupMember *GroupMemberModel, err error) TakeOwner(ctx context.Context, groupID string) (groupMember *GroupMemberModel, err error) - SearchMember(ctx context.Context, keyword string, groupIDs []string, userIDs []string, roleLevels []int32, pagination pagination.Pagination) (total int64, groupList []*GroupMemberModel, err error) + SearchMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (total int64, groupList []*GroupMemberModel, err error) + FindRoleLevelUserIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) //MapGroupMemberNum(ctx context.Context, groupIDs []string) (count map[string]uint32, err error) //FindJoinUserID(ctx context.Context, groupIDs []string) (groupUsers map[string][]string, err error) FindUserJoinedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) TakeGroupMemberNum(ctx context.Context, groupID string) (count int64, err error) //FindUsersJoinedGroupID(ctx context.Context, userIDs []string) (map[string][]string, error) FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) + IsUpdateRoleLevel(data map[string]any) bool }