From f5adb7a17e39fe1321d3deb30329311b03542d7f Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Wed, 8 Feb 2023 17:23:14 +0800 Subject: [PATCH] group database --- internal/rpc/group/group.go | 15 +- pkg/common/db/controller/group.go | 440 +++++++++--------- .../db/relation/group_member_model_k.go | 67 ++- .../db/relation/group_request_model_k.go | 21 +- pkg/common/db/relation/utils.go | 15 + pkg/common/db/unrelation/super_group.go | 10 + 6 files changed, 316 insertions(+), 252 deletions(-) diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 3f1376525..3e508dda6 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -22,6 +22,7 @@ import ( "fmt" "github.com/OpenIMSDK/getcdv3" grpcPrometheus "github.com/grpc-ecosystem/go-grpc-prometheus" + "math/big" "net" "strconv" "strings" @@ -788,7 +789,7 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbGroup.Trans return nil, constant.ErrNoPermission.Wrap(fmt.Sprintf("user %s no permission transfer group owner", tracelog.GetOpUserID(ctx))) } } - if err := s.GroupInterface.TransferGroupOwner(ctx, req.GroupID, req.OldOwnerUserID, req.NewOwnerUserID); err != nil { + if err := s.GroupInterface.TransferGroupOwner(ctx, req.GroupID, req.OldOwnerUserID, req.NewOwnerUserID, newOwner.RoleLevel); err != nil { return nil, err } chat.GroupOwnerTransferredNotification(req) @@ -1048,16 +1049,16 @@ func (s *groupServer) GetGroupAbstractInfo(ctx context.Context, req *pbGroup.Get if err != nil { return nil, err } - numMap, err := s.GroupInterface.MapGroupMemberNum(ctx, req.GroupIDs) - if err != nil { - return nil, err - } - hashMap, err := s.GroupInterface.MapGroupHash(ctx, req.GroupIDs) + groupUserMap, err := s.GroupInterface.MapGroupMemberUserID(ctx, req.GroupIDs) if err != nil { return nil, err } resp.GroupAbstractInfos = utils.Slice(groups, func(e *relation2.GroupModel) *pbGroup.GroupAbstractInfo { - return DbToPbGroupAbstractInfo(e.GroupID, int32(numMap[e.GroupID]), hashMap[e.GroupID]) + 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()) }) return resp, nil } diff --git a/pkg/common/db/controller/group.go b/pkg/common/db/controller/group.go index e03cff015..d715e400b 100644 --- a/pkg/common/db/controller/group.go +++ b/pkg/common/db/controller/group.go @@ -7,7 +7,9 @@ import ( relation2 "Open_IM/pkg/common/db/table/relation" unrelation2 "Open_IM/pkg/common/db/table/unrelation" "Open_IM/pkg/common/db/unrelation" + "Open_IM/pkg/utils" "context" + "fmt" "github.com/dtm-labs/rockscache" _ "github.com/dtm-labs/rockscache" "github.com/go-redis/redis/v8" @@ -15,47 +17,154 @@ import ( "gorm.io/gorm" ) -type GroupInterface GroupDataBaseInterface +//type GroupInterface GroupDataBaseInterface -//type GroupInterface interface { -// // Group -// CreateGroup(ctx context.Context, groups []*relation2.GroupModel, groupMembers []*relation2.GroupMemberModel) error -// TakeGroup(ctx context.Context, groupID string) (group *relation2.GroupModel, err error) -// FindGroup(ctx context.Context, groupIDs []string) (groups []*relation2.GroupModel, err error) -// SearchGroup(ctx context.Context, keyword string, pageNumber, showNumber int32) (int32, []*relation2.GroupModel, error) -// UpdateGroup(ctx context.Context, groupID string, data map[string]any) error -// DismissGroup(ctx context.Context, groupID string) error // 解散群,并删除群成员 -// // GroupMember -// TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relation2.GroupMemberModel, err error) -// TakeGroupOwner(ctx context.Context, groupID string) (*relation2.GroupMemberModel, error) -// FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relation2.GroupMemberModel, error) -// PageGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (int32, []*relation2.GroupMemberModel, error) -// SearchGroupMember(ctx context.Context, name string, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (int32, []*relation2.GroupMemberModel, error) -// HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relation2.GroupMemberModel) error -// DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error -// MapGroupHash(ctx context.Context, groupIDs []string) (map[string]uint64, error) -// MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]int, error) -// TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string) error // 转让群 -// UpdateGroupMember(ctx context.Context, groupID, userID string, data map[string]any) error -// // GroupRequest -// CreateGroupRequest(ctx context.Context, requests []*relation2.GroupRequestModel) error -// TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relation2.GroupRequestModel, error) -// PageGroupRequestUser(ctx context.Context, userID string, pageNumber, showNumber int32) (int32, []*relation2.GroupRequestModel, error) -// // SuperGroup -// TakeSuperGroup(ctx context.Context, groupID string) (superGroup *unrelation2.SuperGroupModel, err error) -// FindJoinSuperGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (total int32, groupIDs []string, err error) -// CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string) error -// DeleteSuperGroup(ctx context.Context, groupID string) error -// DeleteSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error -// CreateSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error -// MapSuperGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) -//} -// -//var _ GroupInterface = (*GroupController)(nil) -// -//type GroupController struct { -// database GroupDataBaseInterface -//} +type GroupInterface interface { + CreateGroup(ctx context.Context, groups []*relation2.GroupModel, groupMembers []*relation2.GroupMemberModel) error + TakeGroup(ctx context.Context, groupID string) (group *relation2.GroupModel, err error) + FindGroup(ctx context.Context, groupIDs []string) (groups []*relation2.GroupModel, err error) + SearchGroup(ctx context.Context, keyword string, pageNumber, showNumber int32) (int32, []*relation2.GroupModel, error) + UpdateGroup(ctx context.Context, groupID string, data map[string]any) error + DismissGroup(ctx context.Context, groupID string) error // 解散群,并删除群成员 + // GroupMember + TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relation2.GroupMemberModel, err error) + TakeGroupOwner(ctx context.Context, groupID string) (*relation2.GroupMemberModel, error) + FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relation2.GroupMemberModel, error) + PageGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (int32, []*relation2.GroupMemberModel, error) + SearchGroupMember(ctx context.Context, keyword string, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (int32, []*relation2.GroupMemberModel, error) + HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relation2.GroupMemberModel) error + DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error + MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string][]string, 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, userID string, data map[string]any) error + // GroupRequest + CreateGroupRequest(ctx context.Context, requests []*relation2.GroupRequestModel) error + TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relation2.GroupRequestModel, error) + PageGroupRequestUser(ctx context.Context, userID string, pageNumber, showNumber int32) (int32, []*relation2.GroupRequestModel, error) + // SuperGroup + TakeSuperGroup(ctx context.Context, groupID string) (superGroup *unrelation2.SuperGroupModel, err error) + FindJoinSuperGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (total int32, groupIDs []string, err error) + CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string) error + DeleteSuperGroup(ctx context.Context, groupID string) error + DeleteSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error + CreateSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error + MapSuperGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) +} + +var _ GroupInterface = (*GroupController)(nil) + +type GroupController struct { + database GroupDataBaseInterface +} + +func (g *GroupController) CreateGroup(ctx context.Context, groups []*relation2.GroupModel, groupMembers []*relation2.GroupMemberModel) error { + return g.database.CreateGroup(ctx, groups, groupMembers) +} + +func (g *GroupController) TakeGroup(ctx context.Context, groupID string) (group *relation2.GroupModel, err error) { + return g.TakeGroup(ctx, groupID) +} + +func (g *GroupController) FindGroup(ctx context.Context, groupIDs []string) (groups []*relation2.GroupModel, err error) { + return g.database.FindGroup(ctx, groupIDs) +} + +func (g *GroupController) SearchGroup(ctx context.Context, keyword string, pageNumber, showNumber int32) (int32, []*relation2.GroupModel, error) { + return g.database.SearchGroup(ctx, keyword, pageNumber, showNumber) +} + +func (g *GroupController) UpdateGroup(ctx context.Context, groupID string, data map[string]any) error { + return g.database.UpdateGroup(ctx, groupID, data) +} + +func (g *GroupController) DismissGroup(ctx context.Context, groupID string) error { + return g.database.DismissGroup(ctx, groupID) +} + +func (g *GroupController) TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relation2.GroupMemberModel, err error) { + return g.database.TakeGroupMember(ctx, groupID, userID) +} + +func (g *GroupController) TakeGroupOwner(ctx context.Context, groupID string) (*relation2.GroupMemberModel, error) { + return g.database.TakeGroupOwner(ctx, groupID) +} + +func (g *GroupController) FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relation2.GroupMemberModel, error) { + return g.database.FindGroupMember(ctx, groupIDs, userIDs, roleLevels) +} + +func (g *GroupController) PageGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (int32, []*relation2.GroupMemberModel, error) { + return g.database.PageGroupMember(ctx, groupIDs, userIDs, roleLevels, pageNumber, showNumber) +} + +func (g *GroupController) SearchGroupMember(ctx context.Context, keyword string, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (int32, []*relation2.GroupMemberModel, error) { + return g.database.SearchGroupMember(ctx, keyword, groupIDs, userIDs, roleLevels, pageNumber, showNumber) +} + +func (g *GroupController) HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relation2.GroupMemberModel) error { + return g.database.HandlerGroupRequest(ctx, groupID, userID, handledMsg, handleResult, member) +} + +func (g *GroupController) DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error { + return g.database.DeleteGroupMember(ctx, groupID, userIDs) +} + +func (g *GroupController) MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string][]string, error) { + return g.database.MapGroupMemberUserID(ctx, groupIDs) +} + +func (g *GroupController) MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) { + return g.database.MapGroupMemberNum(ctx, groupIDs) +} + +func (g *GroupController) TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string, roleLevel int32) error { + return g.database.TransferGroupOwner(ctx, groupID, oldOwnerUserID, newOwnerUserID, roleLevel) +} + +func (g *GroupController) UpdateGroupMember(ctx context.Context, groupID, userID string, data map[string]any) error { + return g.database.UpdateGroupMember(ctx, groupID, userID, data) +} + +func (g *GroupController) CreateGroupRequest(ctx context.Context, requests []*relation2.GroupRequestModel) error { + return g.database.CreateGroupRequest(ctx, requests) +} + +func (g *GroupController) TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relation2.GroupRequestModel, error) { + return g.database.TakeGroupRequest(ctx, groupID, userID) +} + +func (g *GroupController) PageGroupRequestUser(ctx context.Context, userID string, pageNumber, showNumber int32) (int32, []*relation2.GroupRequestModel, error) { + return g.database.PageGroupRequestUser(ctx, userID, pageNumber, showNumber) +} + +func (g *GroupController) TakeSuperGroup(ctx context.Context, groupID string) (superGroup *unrelation2.SuperGroupModel, err error) { + return g.database.TakeSuperGroup(ctx, groupID) +} + +func (g *GroupController) FindJoinSuperGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (total int32, groupIDs []string, err error) { + return g.database.FindJoinSuperGroup(ctx, userID, pageNumber, showNumber) +} + +func (g *GroupController) CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string) error { + return g.database.CreateSuperGroup(ctx, groupID, initMemberIDList) +} + +func (g *GroupController) DeleteSuperGroup(ctx context.Context, groupID string) error { + return g.database.DeleteSuperGroup(ctx, groupID) +} + +func (g *GroupController) DeleteSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error { + return g.database.DeleteSuperGroupMember(ctx, groupID, userIDs) +} + +func (g *GroupController) CreateSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error { + return g.database.CreateSuperGroupMember(ctx, groupID, userIDs) +} + +func (g *GroupController) MapSuperGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) { + return g.database.MapSuperGroupMemberNum(ctx, groupIDs) +} type GroupDataBaseInterface interface { CreateGroup(ctx context.Context, groups []*relation2.GroupModel, groupMembers []*relation2.GroupMemberModel) error @@ -72,9 +181,9 @@ type GroupDataBaseInterface interface { SearchGroupMember(ctx context.Context, keyword string, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (int32, []*relation2.GroupMemberModel, error) HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relation2.GroupMemberModel) error DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error - MapGroupHash(ctx context.Context, groupIDs []string) (map[string]uint64, error) - MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]int, error) - TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string) error // 转让群 + MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string][]string, 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, userID string, data map[string]any) error // GroupRequest CreateGroupRequest(ctx context.Context, requests []*relation2.GroupRequestModel) error @@ -112,154 +221,6 @@ func newGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, mgoClient *mongo.C return database } -//func (g *GroupDataBase) DeleteGroupByIDs(ctx context.Context, groupIDs []string) error { -// return g.groupDB.DB.Transaction(func(tx *gorm.DB) error { -// if err := g.groupDB.Delete(ctx, groupIDs, tx); err != nil { -// return err -// } -// if err := g.cache.DelGroupsInfo(ctx, groupIDs); err != nil { -// return err -// } -// return nil -// }) -//} -// -//func (g *GroupDataBase) TakeGroupByID(ctx context.Context, groupID string) (group *relation2.GroupModel, err error) { -// return g.cache.GetGroupInfo(ctx, groupID) -//} -// -//func (g *GroupDataBase) Update(ctx context.Context, groups []*relation2.GroupModel) error { -// return g.db.Transaction(func(tx *gorm.DB) error { -// if err := g.groupDB.Update(ctx, groups, tx); err != nil { -// return err -// } -// var groupIDs []string -// for _, group := range groups { -// groupIDs = append(groupIDs, group.GroupID) -// } -// if err := g.cache.DelGroupsInfo(ctx, groupIDs); err != nil { -// return err -// } -// return nil -// }) -//} -// -//func (g *GroupDataBase) GetJoinedGroupList(ctx context.Context, userID string) ([]*relation2.GroupModel, error) { -// -// return nil, nil -//} -// -//func (g *GroupDataBase) CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string) error { -// sess, err := g.mongoDB.MgoClient.StartSession() -// if err != nil { -// return err -// } -// defer sess.EndSession(ctx) -// sCtx := mongo.NewSessionContext(ctx, sess) -// if err = g.mongoDB.CreateSuperGroup(sCtx, groupID, initMemberIDList); err != nil { -// _ = sess.AbortTransaction(ctx) -// return err -// } -// -// if err = g.cache.BatchDelJoinedSuperGroupIDs(ctx, initMemberIDList); err != nil { -// _ = sess.AbortTransaction(ctx) -// return err -// } -// return sess.CommitTransaction(ctx) -//} -// -//func (g *GroupDataBase) GetSuperGroupByID(ctx context.Context, groupID string) (superGroup *unrelation.SuperGroup, err error) { -// return g.mongoDB.GetSuperGroup(ctx, groupID) -//} - -//func (g *GroupDataBase) FindGroup(ctx context.Context, groupIDs []string) (groups []*relation2.GroupModel, err error) { -// return g.groupDB.Find(ctx, groupIDs) -//} -// -//func (g *GroupDataBase) SearchGroup(ctx context.Context, name string, pageNumber, showNumber int32) (int32, []*relation2.GroupModel, error) { -// return g.groupDB.Search(ctx, name, pageNumber, showNumber) -//} -// -//func (g *GroupDataBase) TakeGroup(ctx context.Context, groupID string) (group *relation2.GroupModel, err error) { -// return g.groupDB.Take(ctx, groupID) -//} -// -//func (g *GroupDataBase) FindJoinedGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (int32, []*relation2.GroupModel, error) { -// total, members, err := g.groupMemberDB.PageByUser(ctx, userID, pageNumber, showNumber) -// if err != nil { -// return 0, nil, err -// } -// if len(members) == 0 { -// return total, []*relation2.GroupModel{}, nil -// } -// groupIDs := utils.Slice(members, func(e *relation2.GroupMemberModel) string { -// return e.GroupID -// }) -// groups, err := g.groupDB.Find(ctx, groupIDs) -// if err != nil { -// return 0, nil, err -// } -// utils.OrderPtr(groupIDs, &groups, func(e *relation2.GroupModel) string { -// return e.GroupID -// }) -// return total, groups, nil -//} -// -//func (g *GroupDataBase) UpdateGroup(ctx context.Context, groupID string, data map[string]any) error { -// return g.groupDB.UpdateMap(ctx, groupID, data) -//} -// -//func (g *GroupDataBase) DismissGroup(ctx context.Context, groupID string) error { -// return utils.Wrap(g.db.Transaction(func(tx *gorm.DB) error { -// if err := g.groupDB.UpdateStatus(ctx, groupID, constant.GroupStatusDismissed, tx); err != nil { -// return err -// } -// return g.groupMemberDB.DeleteGroup(ctx, []string{groupID}, tx) -// }), "") -//} -// -//func (g *GroupDataBase) CreateGroup(ctx context.Context, groups []*relation2.GroupModel, groupMembers []*relation2.GroupMemberModel) error { -// if len(groups) > 0 && len(groupMembers) > 0 { -// return g.db.Transaction(func(tx *gorm.DB) error { -// if err := g.groupDB.Create(ctx, groups, tx); err != nil { -// return err -// } -// return g.groupMemberDB.Create(ctx, groupMembers, tx) -// }) -// } -// if len(groups) > 0 { -// return g.groupDB.Create(ctx, groups) -// } -// if len(groupMembers) > 0 { -// return g.groupMemberDB.Create(ctx, groupMembers) -// } -// return nil -//} -// -//func (g *GroupDataBase) TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relation2.GroupMemberModel, err error) { -// return g.groupMemberDB.Take(ctx, groupID, userID) -//} -// -//func (g *GroupDataBase) FindGroupMember(ctx context.Context, groupID string, userIDs []string) ([]*relation2.GroupMemberModel, error) { -// return g.groupMemberDB.FindGroupUser(ctx, []string{groupID}, userIDs, nil) -//} -// -//func (g *GroupDataBase) FindGroupMemberAll(ctx context.Context, groupID string) ([]*relation2.GroupMemberModel, error) { -// return g.groupMemberDB.FindGroupUser(ctx, []string{groupID}, nil, nil) -//} -// -//func (g *GroupDataBase) SearchGroupMember(ctx context.Context, groupID string, name string, pageNumber, showNumber int32) (int32, []*relation2.GroupMemberModel, error) { -// return g.groupMemberDB.SearchMember(ctx, groupID, name, pageNumber, showNumber) -//} -// -//func (g *GroupDataBase) TakeGroupOwner(ctx context.Context, groupID string) (*relation2.GroupMemberModel, error) { -// return g.groupMemberDB.TakeOwner(ctx, groupID) -//} -// -//func (g *GroupDataBase) FindGroupOwnerUser(ctx context.Context, groupIDs []string) ([]*relation2.GroupMemberModel, error) { -// return g.groupMemberDB.FindGroupUser(ctx, groupIDs, nil, []int32{constant.GroupOwner}) -//} - var _ GroupDataBaseInterface = (*GroupDataBase)(nil) type GroupDataBase struct { @@ -336,81 +297,108 @@ func (g *GroupDataBase) SearchGroupMember(ctx context.Context, keyword string, g } func (g *GroupDataBase) HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relation2.GroupMemberModel) error { - //TODO implement me - panic("implement me") + if member == nil { + return g.groupRequestDB.UpdateHandler(ctx, groupID, userID, handledMsg, handleResult) + } + return g.db.Transaction(func(tx *gorm.DB) error { + if err := g.groupRequestDB.UpdateHandler(ctx, groupID, userID, handledMsg, handleResult, tx); err != nil { + return err + } + return g.groupMemberDB.Create(ctx, []*relation2.GroupMemberModel{member}, tx) + }) } func (g *GroupDataBase) DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error { - //TODO implement me - panic("implement me") + return g.groupMemberDB.Delete(ctx, groupID, userIDs) } -func (g *GroupDataBase) MapGroupHash(ctx context.Context, groupIDs []string) (map[string]uint64, error) { - //TODO implement me - panic("implement me") +func (g *GroupDataBase) MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string][]string, error) { + return g.groupMemberDB.FindJoinUserID(ctx, groupIDs) } -func (g *GroupDataBase) MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]int, error) { - //TODO implement me - panic("implement me") +func (g *GroupDataBase) MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) { + return g.groupMemberDB.MapGroupMemberNum(ctx, groupIDs) } -func (g *GroupDataBase) TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string) error { - //TODO implement me - panic("implement me") +func (g *GroupDataBase) TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string, roleLevel int32) error { + return g.db.Transaction(func(tx *gorm.DB) error { + rowsAffected, err := g.groupMemberDB.UpdateRoleLevel(ctx, groupID, oldOwnerUserID, roleLevel, tx) + if err != nil { + return err + } + if rowsAffected != 1 { + return utils.Wrap(fmt.Errorf("oldOwnerUserID %s rowsAffected = %d", oldOwnerUserID, rowsAffected), "") + } + rowsAffected, err = g.groupMemberDB.UpdateRoleLevel(ctx, groupID, newOwnerUserID, constant.GroupOwner, tx) + if err != nil { + return err + } + if rowsAffected != 1 { + return utils.Wrap(fmt.Errorf("newOwnerUserID %s rowsAffected = %d", newOwnerUserID, rowsAffected), "") + } + return nil + }) } func (g *GroupDataBase) UpdateGroupMember(ctx context.Context, groupID, userID string, data map[string]any) error { - //TODO implement me - panic("implement me") + return g.groupMemberDB.Update(ctx, groupID, userID, data) } func (g *GroupDataBase) CreateGroupRequest(ctx context.Context, requests []*relation2.GroupRequestModel) error { - //TODO implement me - panic("implement me") + return g.groupRequestDB.Create(ctx, requests) } func (g *GroupDataBase) TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relation2.GroupRequestModel, error) { - //TODO implement me - panic("implement me") + return g.groupRequestDB.Take(ctx, groupID, userID) } func (g *GroupDataBase) PageGroupRequestUser(ctx context.Context, userID string, pageNumber, showNumber int32) (int32, []*relation2.GroupRequestModel, error) { - //TODO implement me - panic("implement me") + return g.groupRequestDB.Page(ctx, userID, pageNumber, showNumber) } func (g *GroupDataBase) TakeSuperGroup(ctx context.Context, groupID string) (superGroup *unrelation2.SuperGroupModel, err error) { - //TODO implement me - panic("implement me") + return g.mongoDB.GetSuperGroup(ctx, groupID) } func (g *GroupDataBase) FindJoinSuperGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (total int32, groupIDs []string, err error) { - //TODO implement me - panic("implement me") + return g.mongoDB.GetJoinGroup(ctx, userID, pageNumber, showNumber) } func (g *GroupDataBase) CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string) error { - //TODO implement me - panic("implement me") + return MongoTransaction(ctx, g.mongoDB.MgoClient, func(ctx mongo.SessionContext) error { + if err := g.mongoDB.CreateSuperGroup(ctx, groupID, initMemberIDList); err != nil { + return err + } + return g.cache.BatchDelJoinedSuperGroupIDs(ctx, initMemberIDList) + }) } func (g *GroupDataBase) DeleteSuperGroup(ctx context.Context, groupID string) error { - //TODO implement me - panic("implement me") + return g.mongoDB.DeleteSuperGroup(ctx, groupID) } func (g *GroupDataBase) DeleteSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error { - //TODO implement me - panic("implement me") + return g.mongoDB.RemoverUserFromSuperGroup(ctx, groupID, userIDs) } func (g *GroupDataBase) CreateSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error { - //TODO implement me - panic("implement me") + return g.mongoDB.AddUserToSuperGroup(ctx, groupID, userIDs) } func (g *GroupDataBase) MapSuperGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) { - //TODO implement me - panic("implement me") + return g.mongoDB.MapGroupMemberCount(ctx, groupIDs) +} + +func MongoTransaction(ctx context.Context, mgo *mongo.Client, fn func(ctx mongo.SessionContext) error) error { + sess, err := mgo.StartSession() + if err != nil { + return err + } + sCtx := mongo.NewSessionContext(ctx, sess) + defer sess.EndSession(sCtx) + if err := fn(sCtx); err != nil { + _ = sess.AbortTransaction(sCtx) + return err + } + return utils.Wrap(sess.CommitTransaction(sCtx), "") } diff --git a/pkg/common/db/relation/group_member_model_k.go b/pkg/common/db/relation/group_member_model_k.go index 4bf36c90d..3f9a6bc62 100644 --- a/pkg/common/db/relation/group_member_model_k.go +++ b/pkg/common/db/relation/group_member_model_k.go @@ -24,13 +24,20 @@ func (g *GroupMemberGorm) Create(ctx context.Context, groupMemberList []*relatio return utils.Wrap(getDBConn(g.DB, tx).Create(&groupMemberList).Error, "") } -func (g *GroupMemberGorm) Delete(ctx context.Context, groupMembers []*relation.GroupMemberModel, tx ...*gorm.DB) (err error) { +func (g *GroupMemberGorm) Delete(ctx context.Context, groupID string, userIDs []string, tx ...*gorm.DB) (err error) { defer func() { - tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupMembers", groupMembers) + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userIDs", userIDs) }() - return utils.Wrap(getDBConn(g.DB, tx).Delete(groupMembers).Error, "") + return utils.Wrap(getDBConn(g.DB, tx).Where("group_id = ? and user_id in (?)", groupID, userIDs).Delete(&relation.GroupMemberModel{}).Error, "") } +//func (g *GroupMemberGorm) Delete(ctx context.Context, groupMembers []*relation.GroupMemberModel, tx ...*gorm.DB) (err error) { +// defer func() { +// tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupMembers", groupMembers) +// }() +// return utils.Wrap(getDBConn(g.DB, tx).Delete(groupMembers).Error, "") +//} + func (g *GroupMemberGorm) DeleteGroup(ctx context.Context, groupIDs []string, tx ...*gorm.DB) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupIDs", groupIDs) @@ -45,9 +52,21 @@ func (g *GroupMemberGorm) UpdateByMap(ctx context.Context, groupID string, userI return utils.Wrap(getDBConn(g.DB, tx).Model(&relation.GroupMemberModel{}).Where("group_id = ? and user_id = ?", groupID, userID).Updates(args).Error, "") } -func (g *GroupMemberGorm) Update(ctx context.Context, groupMembers []*relation.GroupMemberModel, tx ...*gorm.DB) (err error) { - defer func() { tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupMembers", groupMembers) }() - return utils.Wrap(getDBConn(g.DB, tx).Updates(&groupMembers).Error, "") +func (g *GroupMemberGorm) Update(ctx context.Context, groupID string, userID string, data map[string]any, tx ...*gorm.DB) (err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID, "data", data) + }() + return utils.Wrap(getDBConn(g.DB, tx).Model(&relation.GroupMemberModel{}).Where("group_id = ? and user_id = ?", groupID, userID).Updates(data).Error, "") +} + +func (g *GroupMemberGorm) UpdateRoleLevel(ctx context.Context, groupID string, userID string, roleLevel int32, tx ...*gorm.DB) (rowsAffected int64, err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID, "roleLevel", roleLevel) + }() + db := getDBConn(g.DB, tx).Model(&relation.GroupMemberModel{}).Where("group_id = ? and user_id = ?", groupID, userID).Updates(map[string]any{ + "role_level": roleLevel, + }) + return db.RowsAffected, utils.Wrap(db.Error, "") } func (g *GroupMemberGorm) Find(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32, tx ...*gorm.DB) (groupList []*relation.GroupMemberModel, err error) { @@ -67,17 +86,6 @@ func (g *GroupMemberGorm) Find(ctx context.Context, groupIDs []string, userIDs [ return groupList, utils.Wrap(db.Find(&groupList).Error, "") } -//func (g *GroupMemberGorm) Find(ctx context.Context, groupMembers []*relation.GroupMemberModel, tx ...*gorm.DB) (groupList []*relation.GroupMemberModel, err error) { -// defer func() { -// tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupMembers", groupMembers, "groupList", groupList) -// }() -// var where [][]interface{} -// for _, groupMember := range groupMembers { -// where = append(where, []interface{}{groupMember.GroupID, groupMember.UserID}) -// } -// return groupList, utils.Wrap(getDBConn(g.DB, tx).Where("(group_id, user_id) in ?", where).Find(&groupList).Error, "") -//} - func (g *GroupMemberGorm) FindGroupUser(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32, tx ...*gorm.DB) (groupList []*relation.GroupMemberModel, err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupIDs", groupIDs, "userIDs", userIDs, "groupList", groupList) @@ -121,3 +129,28 @@ func (g *GroupMemberGorm) SearchMember(ctx context.Context, keyword string, grou gormIn(&db, "role_level", roleLevels) return gormSearch[relation.GroupMemberModel](db, []string{"nickname"}, keyword, pageNumber, showNumber) } + +func (g *GroupMemberGorm) MapGroupMemberNum(ctx context.Context, groupIDs []string, tx ...*gorm.DB) (count map[string]uint32, err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupIDs", groupIDs, "count", count) + }() + return mapCount(getDBConn(g.DB, tx).Where("group_id in (?)", groupIDs), "group_id") +} + +func (g *GroupMemberGorm) FindJoinUserID(ctx context.Context, groupIDs []string, tx ...*gorm.DB) (groupUsers map[string][]string, err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupIDs", groupIDs, "groupUsers", groupUsers) + }() + var items []struct { + GroupID string `gorm:"group_id"` + UserID string `gorm:"user_id"` + } + if err := getDBConn(g.DB, tx).Model(&relation.GroupMemberModel{}).Where("group_id in (?)", groupIDs).Find(&items).Error; err != nil { + return nil, utils.Wrap(err, "") + } + groupUsers = make(map[string][]string) + for _, item := range items { + groupUsers[item.GroupID] = append(groupUsers[item.GroupID], item.UserID) + } + return groupUsers, nil +} diff --git a/pkg/common/db/relation/group_request_model_k.go b/pkg/common/db/relation/group_request_model_k.go index d40f3ed4a..46c0f335e 100644 --- a/pkg/common/db/relation/group_request_model_k.go +++ b/pkg/common/db/relation/group_request_model_k.go @@ -32,11 +32,21 @@ func (g *GroupRequestGorm) Delete(ctx context.Context, groupRequests []*relation return utils.Wrap(getDBConn(g.DB, tx).Delete(&groupRequests).Error, utils.GetSelfFuncName()) } -func (g *GroupRequestGorm) UpdateByMap(ctx context.Context, groupID string, userID string, args map[string]interface{}, tx ...*gorm.DB) (err error) { +func (g *GroupRequestGorm) UpdateMap(ctx context.Context, groupID string, userID string, args map[string]interface{}, tx ...*gorm.DB) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID, "args", args) }() - return utils.Wrap(getDBConn(g.DB, tx).Where("group_id = ? and user_id = ? ", groupID, userID).Updates(args).Error, utils.GetSelfFuncName()) + return utils.Wrap(getDBConn(g.DB, tx).Model(&relation.GroupRequestModel{}).Where("group_id = ? and user_id = ? ", groupID, userID).Updates(args).Error, utils.GetSelfFuncName()) +} + +func (g *GroupRequestGorm) UpdateHandler(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, tx ...*gorm.DB) (err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID, "handledMsg", handledMsg, "handleResult", handleResult) + }() + return utils.Wrap(getDBConn(g.DB, tx).Model(&relation.GroupRequestModel{}).Where("group_id = ? and user_id = ? ", groupID, userID).Updates(map[string]any{ + "handle_msg": handledMsg, + "handle_result": handleResult, + }).Error, utils.GetSelfFuncName()) } func (g *GroupRequestGorm) Update(ctx context.Context, groupRequests []*relation.GroupRequestModel, tx ...*gorm.DB) (err error) { @@ -64,3 +74,10 @@ func (g *GroupRequestGorm) Take(ctx context.Context, groupID string, userID stri }() return groupRequest, utils.Wrap(getDBConn(g.DB, tx).Where("group_id = ? and user_id = ? ", groupID, userID).Take(groupRequest).Error, utils.GetSelfFuncName()) } + +func (g *GroupRequestGorm) Page(ctx context.Context, userID string, pageNumber, showNumber int32, tx ...*gorm.DB) (total int32, groups []*relation.GroupRequestModel, err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "pageNumber", pageNumber, "showNumber", showNumber, "total", total, "groups", groups) + }() + return gormSearch[relation.GroupRequestModel](getDBConn(g.DB, tx).Where("user_id = ?", userID), nil, "", pageNumber, showNumber) +} diff --git a/pkg/common/db/relation/utils.go b/pkg/common/db/relation/utils.go index e025e089a..83e5e7bd2 100644 --- a/pkg/common/db/relation/utils.go +++ b/pkg/common/db/relation/utils.go @@ -39,3 +39,18 @@ func gormIn[E any](db **gorm.DB, field string, es []E) { } *db = (*db).Where(field+" in (?)", es) } + +func mapCount(db *gorm.DB, field string) (map[string]uint32, error) { + var items []struct { + ID string `gorm:"column:id"` + Count uint32 `gorm:"column:count"` + } + if err := db.Select(field + " as id, count(1) as count").Group(field).Find(&items).Error; err != nil { + return nil, err + } + m := make(map[string]uint32) + for _, item := range items { + m[item.ID] = item.Count + } + return m, nil +} diff --git a/pkg/common/db/unrelation/super_group.go b/pkg/common/db/unrelation/super_group.go index 9227494e2..e3a57d624 100644 --- a/pkg/common/db/unrelation/super_group.go +++ b/pkg/common/db/unrelation/super_group.go @@ -98,6 +98,16 @@ func (db *SuperGroupMongoDriver) GetSuperGroupByUserID(ctx context.Context, user return &user, utils.Wrap(err, "") } +func (db *SuperGroupMongoDriver) GetJoinGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (int32, []string, error) { + //TODO implement me + panic("implement me") +} + +func (db *SuperGroupMongoDriver) MapGroupMemberCount(ctx context.Context, groupIDs []string) (map[string]uint32, error) { + //TODO implement me + panic("implement me") +} + func (db *SuperGroupMongoDriver) DeleteSuperGroup(ctx context.Context, groupID string) error { opts := options.Session().SetDefaultReadConcern(readconcern.Majority()) return db.MgoDB.Client().UseSessionWithOptions(ctx, opts, func(sCtx mongo.SessionContext) error {