From 09c6fbdfe417e4ffa55b3fc3084fb3ddc370d306 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Fri, 10 Feb 2023 19:17:33 +0800 Subject: [PATCH] group --- internal/common/check/user.go | 30 +++- internal/rpc/group/callback.go | 223 ++++++++++++++------------- internal/rpc/group/g.go | 94 ------------ internal/rpc/group/group.go | 152 +++++++++++++------ internal/rpc/group/utils.go | 13 -- pkg/callbackstruct/group.go | 4 +- pkg/common/constant/errors.go | 1 + pkg/common/db/cache/group.go | 241 ++++++++++++++++-------------- pkg/common/db/controller/group.go | 54 +++---- pkg/utils/utils_v2.go | 13 ++ 10 files changed, 415 insertions(+), 410 deletions(-) delete mode 100644 internal/rpc/group/g.go delete mode 100644 internal/rpc/group/utils.go diff --git a/internal/common/check/user.go b/internal/common/check/user.go index 66f75198f..af5954c91 100644 --- a/internal/common/check/user.go +++ b/internal/common/check/user.go @@ -6,6 +6,32 @@ import ( "errors" ) -func GetUsersInfo(ctx context.Context, args ...interface{}) ([]*sdkws.UserInfo, error) { - return nil, errors.New("TODO:GetUserInfo") +//func GetUsersInfo(ctx context.Context, args ...interface{}) ([]*sdkws.UserInfo, error) { +// return nil, errors.New("TODO:GetUserInfo") +//} + +func NewUserCheck() *UserCheck { + return &UserCheck{} +} + +type UserCheck struct{} + +func (u *UserCheck) GetUsersInfos(ctx context.Context, userIDs []string, complete bool) ([]*sdkws.UserInfo, error) { + return nil, errors.New("todo") +} + +func (u *UserCheck) GetUsersInfoMap(ctx context.Context, userIDs []string, complete bool) (map[string]*sdkws.UserInfo, error) { + return nil, errors.New("todo") +} + +func (u *UserCheck) GetPublicUserInfo(ctx context.Context, userID string) (*sdkws.PublicUserInfo, error) { + return nil, errors.New("todo") +} + +func (u *UserCheck) GetPublicUserInfos(ctx context.Context, userIDs []string, complete bool) ([]*sdkws.PublicUserInfo, error) { + return nil, errors.New("todo") +} + +func (u *UserCheck) GetPublicUserInfoMap(ctx context.Context, userIDs []string, complete bool) (map[string]*sdkws.PublicUserInfo, error) { + return nil, errors.New("todo") } diff --git a/internal/rpc/group/callback.go b/internal/rpc/group/callback.go index b437e8702..0c174b8bf 100644 --- a/internal/rpc/group/callback.go +++ b/internal/rpc/group/callback.go @@ -1,92 +1,105 @@ package group import ( - cbApi "Open_IM/pkg/callback_struct" + "Open_IM/pkg/apistruct" + "Open_IM/pkg/callbackstruct" "Open_IM/pkg/common/config" "Open_IM/pkg/common/constant" "Open_IM/pkg/common/db/table/relation" "Open_IM/pkg/common/http" - "Open_IM/pkg/common/log" "Open_IM/pkg/common/tracelog" - pbGroup "Open_IM/pkg/proto/group" + "Open_IM/pkg/proto/group" "Open_IM/pkg/utils" "context" "google.golang.org/protobuf/types/known/wrapperspb" ) -func callbackBeforeCreateGroup(ctx context.Context, req *pbGroup.CreateGroupReq) (err error) { - defer func() { - tracelog.SetCtxInfo(ctx, utils.GetFuncName(1), err, "req", req) - }() +func CallbackBeforeCreateGroup(ctx context.Context, req *group.CreateGroupReq) (err error) { if !config.Config.Callback.CallbackBeforeCreateGroup.Enable { return nil } - log.NewDebug(req.OperationID, utils.GetSelfFuncName(), req.String()) - commonCallbackReq := &cbApi.CallbackBeforeCreateGroupReq{ + defer func() { + tracelog.SetCtxInfo(ctx, utils.GetFuncName(1), err, "req", req) + }() + operationID := tracelog.GetOperationID(ctx) + commonCallbackReq := &callbackstruct.CallbackBeforeCreateGroupReq{ CallbackCommand: constant.CallbackBeforeCreateGroupCommand, - OperationID: req.OperationID, + OperationID: operationID, GroupInfo: *req.GroupInfo, - InitMemberList: req.InitMemberList, } - callbackResp := cbApi.CommonCallbackResp{OperationID: req.OperationID} - resp := &cbApi.CallbackBeforeCreateGroupResp{ - CommonCallbackResp: &callbackResp, + commonCallbackReq.InitMemberList = append(commonCallbackReq.InitMemberList, &apistruct.GroupAddMemberInfo{ + UserID: req.OwnerUserID, + RoleLevel: constant.GroupOwner, + }) + for _, userID := range req.AdminUserIDs { + commonCallbackReq.InitMemberList = append(commonCallbackReq.InitMemberList, &apistruct.GroupAddMemberInfo{ + UserID: userID, + RoleLevel: constant.GroupAdmin, + }) } - //utils.CopyStructFields(req, msg.MsgData) - defer log.NewDebug(req.OperationID, utils.GetSelfFuncName(), commonCallbackReq, *resp) - err = http.CallBackPostReturn(config.Config.Callback.CallbackUrl, constant.CallbackBeforeCreateGroupCommand, commonCallbackReq, - resp, config.Config.Callback.CallbackBeforeCreateGroup) - if err == nil { - if resp.GroupID != nil { - req.GroupInfo.GroupID = *resp.GroupID - } - if resp.GroupName != nil { - req.GroupInfo.GroupName = *resp.GroupName - } - if resp.Notification != nil { - req.GroupInfo.Notification = *resp.Notification - } - if resp.Introduction != nil { - req.GroupInfo.Introduction = *resp.Introduction - } - if resp.FaceURL != nil { - req.GroupInfo.FaceURL = *resp.FaceURL - } - if resp.OwnerUserID != nil { - req.GroupInfo.OwnerUserID = *resp.OwnerUserID - } - if resp.Ex != nil { - req.GroupInfo.Ex = *resp.Ex - } - if resp.Status != nil { - req.GroupInfo.Status = *resp.Status - } - if resp.CreatorUserID != nil { - req.GroupInfo.CreatorUserID = *resp.CreatorUserID - } - if resp.GroupType != nil { - req.GroupInfo.GroupType = *resp.GroupType - } - if resp.NeedVerification != nil { - req.GroupInfo.NeedVerification = *resp.NeedVerification - } - if resp.LookMemberInfo != nil { - req.GroupInfo.LookMemberInfo = *resp.LookMemberInfo - } + for _, userID := range req.AdminUserIDs { + commonCallbackReq.InitMemberList = append(commonCallbackReq.InitMemberList, &apistruct.GroupAddMemberInfo{ + UserID: userID, + RoleLevel: constant.GroupOrdinaryUsers, + }) } - return err + resp := &callbackstruct.CallbackBeforeCreateGroupResp{ + CommonCallbackResp: &callbackstruct.CommonCallbackResp{OperationID: operationID}, + } + err = http.CallBackPostReturn(config.Config.Callback.CallbackUrl, constant.CallbackBeforeCreateGroupCommand, commonCallbackReq, resp, config.Config.Callback.CallbackBeforeCreateGroup) + if err != nil { + return err + } + + if resp.GroupID != nil { + req.GroupInfo.GroupID = *resp.GroupID + } + if resp.GroupName != nil { + req.GroupInfo.GroupName = *resp.GroupName + } + if resp.Notification != nil { + req.GroupInfo.Notification = *resp.Notification + } + if resp.Introduction != nil { + req.GroupInfo.Introduction = *resp.Introduction + } + if resp.FaceURL != nil { + req.GroupInfo.FaceURL = *resp.FaceURL + } + if resp.OwnerUserID != nil { + req.GroupInfo.OwnerUserID = *resp.OwnerUserID + } + if resp.Ex != nil { + req.GroupInfo.Ex = *resp.Ex + } + if resp.Status != nil { + req.GroupInfo.Status = *resp.Status + } + if resp.CreatorUserID != nil { + req.GroupInfo.CreatorUserID = *resp.CreatorUserID + } + if resp.GroupType != nil { + req.GroupInfo.GroupType = *resp.GroupType + } + if resp.NeedVerification != nil { + req.GroupInfo.NeedVerification = *resp.NeedVerification + } + if resp.LookMemberInfo != nil { + req.GroupInfo.LookMemberInfo = *resp.LookMemberInfo + } + return nil } -func CallbackBeforeMemberJoinGroup(ctx context.Context, operationID string, groupMember *relation.GroupMemberModel, groupEx string) (err error) { - defer func() { - tracelog.SetCtxInfo(ctx, utils.GetFuncName(1), err, "groupMember", *groupMember, "groupEx", groupEx) - }() - callbackResp := cbApi.CommonCallbackResp{OperationID: operationID} +func CallbackBeforeMemberJoinGroup(ctx context.Context, groupMember *relation.GroupMemberModel, groupEx string) (err error) { if !config.Config.Callback.CallbackBeforeMemberJoinGroup.Enable { return nil } - log.NewDebug(operationID, "args: ", *groupMember) - callbackReq := cbApi.CallbackBeforeMemberJoinGroupReq{ + defer func() { + tracelog.SetCtxInfo(ctx, utils.GetFuncName(1), err, "groupMember", *groupMember, "groupEx", groupEx) + }() + operationID := tracelog.GetOperationID(ctx) + callbackResp := callbackstruct.CommonCallbackResp{OperationID: operationID} + callbackReq := callbackstruct.CallbackBeforeMemberJoinGroupReq{ CallbackCommand: constant.CallbackBeforeMemberJoinGroupCommand, OperationID: operationID, GroupID: groupMember.GroupID, @@ -94,42 +107,44 @@ func CallbackBeforeMemberJoinGroup(ctx context.Context, operationID string, grou Ex: groupMember.Ex, GroupEx: groupEx, } - resp := &cbApi.CallbackBeforeMemberJoinGroupResp{ + resp := &callbackstruct.CallbackBeforeMemberJoinGroupResp{ CommonCallbackResp: &callbackResp, } err = http.CallBackPostReturn(config.Config.Callback.CallbackUrl, constant.CallbackBeforeMemberJoinGroupCommand, callbackReq, resp, config.Config.Callback.CallbackBeforeMemberJoinGroup) - if err == nil { - if resp.MuteEndTime != nil { - groupMember.MuteEndTime = utils.UnixSecondToTime(*resp.MuteEndTime) - } - if resp.FaceURL != nil { - groupMember.FaceURL = *resp.FaceURL - } - if resp.Ex != nil { - groupMember.Ex = *resp.Ex - } - if resp.NickName != nil { - groupMember.Nickname = *resp.NickName - } - if resp.RoleLevel != nil { - groupMember.RoleLevel = *resp.RoleLevel - } + if err != nil { + return err } - return err + if resp.MuteEndTime != nil { + groupMember.MuteEndTime = utils.UnixSecondToTime(*resp.MuteEndTime) + } + if resp.FaceURL != nil { + groupMember.FaceURL = *resp.FaceURL + } + if resp.Ex != nil { + groupMember.Ex = *resp.Ex + } + if resp.NickName != nil { + groupMember.Nickname = *resp.NickName + } + if resp.RoleLevel != nil { + groupMember.RoleLevel = *resp.RoleLevel + } + return nil } -func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *pbGroup.SetGroupMemberInfo) (err error) { - defer func() { - tracelog.SetCtxInfo(ctx, utils.GetFuncName(1), err, "req", *req) - }() - callbackResp := cbApi.CommonCallbackResp{OperationID: req.OperationID} +func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMemberInfo) (err error) { if !config.Config.Callback.CallbackBeforeSetGroupMemberInfo.Enable { return nil } - callbackReq := cbApi.CallbackBeforeSetGroupMemberInfoReq{ + defer func() { + tracelog.SetCtxInfo(ctx, utils.GetFuncName(1), err, "req", *req) + }() + operationID := tracelog.GetOperationID(ctx) + callbackResp := callbackstruct.CommonCallbackResp{OperationID: operationID} + callbackReq := callbackstruct.CallbackBeforeSetGroupMemberInfoReq{ CallbackCommand: constant.CallbackBeforeSetGroupMemberInfoCommand, - OperationID: req.OperationID, + OperationID: operationID, GroupID: req.GroupID, UserID: req.UserID, } @@ -145,24 +160,24 @@ func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *pbGroup.SetGroup if req.Ex != nil { callbackReq.Ex = req.Ex.Value } - resp := &cbApi.CallbackBeforeSetGroupMemberInfoResp{ + resp := &callbackstruct.CallbackBeforeSetGroupMemberInfoResp{ CommonCallbackResp: &callbackResp, } - err = http.CallBackPostReturn(config.Config.Callback.CallbackUrl, constant.CallbackBeforeSetGroupMemberInfoCommand, callbackReq, - resp, config.Config.Callback.CallbackBeforeSetGroupMemberInfo.CallbackTimeOut, &config.Config.Callback.CallbackBeforeSetGroupMemberInfo.CallbackFailedContinue) - if err == nil { - if resp.FaceURL != nil { - req.FaceURL = &wrapperspb.StringValue{Value: *resp.FaceURL} - } - if resp.Nickname != nil { - req.Nickname = &wrapperspb.StringValue{Value: *resp.Nickname} - } - if resp.RoleLevel != nil { - req.RoleLevel = &wrapperspb.Int32Value{Value: *resp.RoleLevel} - } - if resp.Ex != nil { - req.Ex = &wrapperspb.StringValue{Value: *resp.Ex} - } + err = http.CallBackPostReturn(config.Config.Callback.CallbackUrl, constant.CallbackBeforeSetGroupMemberInfoCommand, callbackReq, resp, config.Config.Callback.CallbackBeforeSetGroupMemberInfo) + if err != nil { + return err + } + if resp.FaceURL != nil { + req.FaceURL = &wrapperspb.StringValue{Value: *resp.FaceURL} + } + if resp.Nickname != nil { + req.Nickname = &wrapperspb.StringValue{Value: *resp.Nickname} + } + if resp.RoleLevel != nil { + req.RoleLevel = &wrapperspb.Int32Value{Value: *resp.RoleLevel} + } + if resp.Ex != nil { + req.Ex = &wrapperspb.StringValue{Value: *resp.Ex} } return err } diff --git a/internal/rpc/group/g.go b/internal/rpc/group/g.go deleted file mode 100644 index 3bbbb4afa..000000000 --- a/internal/rpc/group/g.go +++ /dev/null @@ -1,94 +0,0 @@ -package group - -import ( - "Open_IM/pkg/common/constant" - "Open_IM/pkg/common/tracelog" - pbConversation "Open_IM/pkg/proto/conversation" - sdkws "Open_IM/pkg/proto/sdkws" - "Open_IM/pkg/utils" - "context" - "errors" - "math/big" - "strconv" - "strings" - "time" -) - -func GetPublicUserInfoOne(ctx context.Context, userID string) (*sdkws.PublicUserInfo, error) { - return nil, errors.New("todo") -} - -func GetUsersInfo(ctx context.Context, userIDs []string) ([]*sdkws.UserInfo, error) { - return nil, errors.New("todo") -} - -func GetUserInfoMap(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error) { - users, err := GetUsersInfo(ctx, userIDs) - if err != nil { - return nil, err - } - return utils.SliceToMap(users, func(e *sdkws.UserInfo) string { - return e.UserID - }), nil -} - -func GetPublicUserInfo(ctx context.Context, userIDs []string) ([]*sdkws.PublicUserInfo, error) { - return nil, errors.New("todo") -} - -func GetPublicUserInfoMap(ctx context.Context, userIDs []string) (map[string]*sdkws.PublicUserInfo, error) { - users, err := GetPublicUserInfo(ctx, userIDs) - if err != nil { - return nil, err - } - return utils.SliceToMap(users, func(e *sdkws.PublicUserInfo) string { - return e.UserID - }), nil -} - -func GetUsername(ctx context.Context, userIDs []string) (map[string]string, error) { - if len(userIDs) == 0 { - return map[string]string{}, nil - } - users, err := GetPublicUserInfo(ctx, userIDs) - if err != nil { - return nil, err - } - if ids := utils.Single(userIDs, utils.Slice(users, func(e *sdkws.PublicUserInfo) string { - return e.UserID - })); len(ids) > 0 { - return nil, constant.ErrUserIDNotFound.Wrap(strings.Join(ids, ",")) - } - return utils.SliceToMapAny(users, func(e *sdkws.PublicUserInfo) (string, string) { - return e.UserID, e.Nickname - }), nil -} - -func GroupNotification(ctx context.Context, groupID string) { - var conversationReq pbConversation.ModifyConversationFieldReq - conversation := pbConversation.Conversation{ - OwnerUserID: tracelog.GetOpUserID(ctx), - ConversationID: utils.GetConversationIDBySessionType(groupID, constant.GroupChatType), - ConversationType: constant.GroupChatType, - GroupID: groupID, - } - conversationReq.Conversation = &conversation - conversationReq.OperationID = tracelog.GetOperationID(ctx) - conversationReq.FieldType = constant.FieldGroupAtType - conversation.GroupAtType = constant.GroupNotification - conversationReq.UserIDList = cacheResp.UserIDList - - _, err = pbConversation.NewConversationClient(s.etcdConn.GetConn("", config.Config.RpcRegisterName.OpenImConversationName)).ModifyConversationField(ctx, &conversationReq) - tracelog.SetCtxInfo(ctx, "ModifyConversationField", err, "req", &conversationReq, "resp", conversationReply) -} - -func genGroupID(ctx context.Context, groupID string) string { - if groupID != "" { - return groupID - } - groupID = utils.Md5(tracelog.GetOperationID(ctx) + strconv.FormatInt(time.Now().UnixNano(), 10)) - bi := big.NewInt(0) - bi.SetString(groupID[0:8], 16) - groupID = bi.String() - return groupID -} diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 9bdb77165..72da66aeb 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -1,6 +1,7 @@ package group import ( + "Open_IM/internal/common/check" "Open_IM/internal/common/network" chat "Open_IM/internal/rpc/msg" "Open_IM/pkg/common/config" @@ -22,6 +23,9 @@ import ( "context" "fmt" grpcPrometheus "github.com/grpc-ecosystem/go-grpc-prometheus" + "gorm.io/gorm" + "math/big" + "math/rand" "net" "strconv" "strings" @@ -38,6 +42,7 @@ type groupServer struct { zkAddr []string GroupInterface controller.GroupInterface registerCenter discoveryRegistry.SvcDiscoveryRegistry + user *check.UserCheck } func NewGroupServer(port int) *groupServer { @@ -72,8 +77,8 @@ func NewGroupServer(port int) *groupServer { } //conns, err := g.registerCenter.GetConns(config.Config.RpcRegisterName.OpenImConversationName) - g.GroupInterface = controller.NewGroupInterface(mysql.GormConn(), redis.GetClient(), mongo.GetClient()) + g.user = check.NewUserCheck() return &g } @@ -132,6 +137,69 @@ func (s *groupServer) CheckGroupAdmin(ctx context.Context, groupID string) error return nil } +func (s *groupServer) GetUsernameMap(ctx context.Context, userIDs []string, complete bool) (map[string]string, error) { + if len(userIDs) == 0 { + return map[string]string{}, nil + } + users, err := s.user.GetPublicUserInfos(ctx, userIDs, complete) + if err != nil { + return nil, err + } + return utils.SliceToMapAny(users, func(e *open_im_sdk.PublicUserInfo) (string, string) { + return e.UserID, e.Nickname + }), nil +} + +func (s *groupServer) GroupNotification(ctx context.Context, groupID string) { + // todo 群公告修改通知 + //var conversationReq pbConversation.ModifyConversationFieldReq + //conversation := pbConversation.Conversation{ + // OwnerUserID: tracelog.GetOpUserID(ctx), + // ConversationID: utils.GetConversationIDBySessionType(groupID, constant.GroupChatType), + // ConversationType: constant.GroupChatType, + // GroupID: groupID, + //} + //conversationReq.Conversation = &conversation + //conversationReq.FieldType = constant.FieldGroupAtType + //conversation.GroupAtType = constant.GroupNotification + //conversationReq.UserIDList = userIDs + //_, err := pbConversation.NewConversationClient(s.etcdConn.GetConn("", config.Config.RpcRegisterName.OpenImConversationName)).ModifyConversationField(ctx, &conversationReq) + //tracelog.SetCtxInfo(ctx, "ModifyConversationField", err, "req", &conversationReq, "resp", conversationReply) +} + +func (s *groupServer) IsNotFound(err error) bool { + return utils.Unwrap(err) == gorm.ErrRecordNotFound +} + +func (s *groupServer) GenGroupID(ctx context.Context, groupID *string) error { + if *groupID != "" { + _, err := s.GroupInterface.TakeGroup(ctx, *groupID) + if err == nil { + return constant.ErrGroupIDExisted.Wrap("group id existed " + *groupID) + } else if s.IsNotFound(err) { + return nil + } else { + return err + } + } + for i := 0; i < 10; i++ { + id := utils.Md5(strings.Join([]string{tracelog.GetOperationID(ctx), strconv.FormatInt(time.Now().UnixNano(), 10), strconv.Itoa(rand.Int())}, ",;,")) + bi := big.NewInt(0) + bi.SetString(id[0:8], 16) + id = bi.String() + _, err := s.GroupInterface.TakeGroup(ctx, id) + if err == nil { + continue + } else if s.IsNotFound(err) { + *groupID = id + return nil + } else { + return err + } + } + return constant.ErrData.Wrap("group id gen error") +} + func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupReq) (*pbGroup.CreateGroupResp, error) { resp := &pbGroup.CreateGroupResp{GroupInfo: &open_im_sdk.GroupInfo{}} if err := tokenverify.CheckAccessV3(ctx, req.OwnerUserID); err != nil { @@ -144,19 +212,18 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupR if utils.Duplicate(userIDs) { return nil, constant.ErrArgs.Wrap("group member repeated") } - userMap, err := GetUserInfoMap(ctx, userIDs) + userMap, err := s.user.GetUsersInfoMap(ctx, userIDs, true) if err != nil { return nil, err } - if ids := utils.Single(userIDs, utils.Keys(userMap)); len(ids) > 0 { - return nil, constant.ErrUserIDNotFound.Wrap(strings.Join(ids, ",")) - } - if err := callbackBeforeCreateGroup(ctx, req); err != nil { + if err := CallbackBeforeCreateGroup(ctx, req); err != nil { return nil, err } var groupMembers []*relationTb.GroupMemberModel group := PbToDBGroupInfo(req.GroupInfo) - group.GroupID = genGroupID(ctx, req.GroupInfo.GroupID) + if err := s.GenGroupID(ctx, &group.GroupID); err != nil { + return nil, err + } joinGroup := func(userID string, roleLevel int32) error { groupMember := PbToDbGroupMember(userMap[userID]) groupMember.Nickname = "" @@ -165,7 +232,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupR groupMember.OperatorUserID = tracelog.GetOpUserID(ctx) groupMember.JoinSource = constant.JoinByInvitation groupMember.InviterUserID = tracelog.GetOpUserID(ctx) - if err := CallbackBeforeMemberJoinGroup(ctx, tracelog.GetOperationID(ctx), groupMember, group.Ex); err != nil { + if err := CallbackBeforeMemberJoinGroup(ctx, groupMember, group.Ex); err != nil { return err } groupMembers = append(groupMembers, groupMember) @@ -271,13 +338,10 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbGroup.Invite if ids := utils.Single(req.InvitedUserIDs, utils.Keys(memberMap)); len(ids) > 0 { return nil, constant.ErrArgs.Wrap("user in group " + strings.Join(ids, ",")) } - userMap, err := GetUserInfoMap(ctx, req.InvitedUserIDs) + userMap, err := s.user.GetUsersInfoMap(ctx, req.InvitedUserIDs, true) if err != nil { return nil, err } - if ids := utils.Single(req.InvitedUserIDs, utils.Keys(userMap)); len(ids) > 0 { - return nil, constant.ErrArgs.Wrap("user not found " + strings.Join(ids, ",")) - } if group.NeedVerification == constant.AllNeedVerification { if !tokenverify.IsAppManagerUid(ctx) { opUserID := tracelog.GetOpUserID(ctx) @@ -328,7 +392,7 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbGroup.Invite member.OperatorUserID = opUserID member.InviterUserID = opUserID member.JoinSource = constant.JoinByInvitation - if err := CallbackBeforeMemberJoinGroup(ctx, tracelog.GetOperationID(ctx), member, group.Ex); err != nil { + if err := CallbackBeforeMemberJoinGroup(ctx, member, group.Ex); err != nil { return nil, err } groupMembers = append(groupMembers, member) @@ -354,9 +418,9 @@ func (s *groupServer) GetGroupAllMember(ctx context.Context, req *pbGroup.GetGro if err != nil { return nil, err } - nameMap, err := GetUsername(ctx, utils.Filter(members, func(e *relationTb.GroupMemberModel) (string, bool) { + nameMap, err := s.GetUsernameMap(ctx, utils.Filter(members, func(e *relationTb.GroupMemberModel) (string, bool) { return e.UserID, e.Nickname == "" - })) + }), true) if err != nil { return nil, err } @@ -376,9 +440,9 @@ func (s *groupServer) GetGroupMemberList(ctx context.Context, req *pbGroup.GetGr return nil, err } resp.Total = total - nameMap, err := GetUsername(ctx, utils.Filter(members, func(e *relationTb.GroupMemberModel) (string, bool) { + nameMap, err := s.GetUsernameMap(ctx, utils.Filter(members, func(e *relationTb.GroupMemberModel) (string, bool) { return e.UserID, e.Nickname == "" - })) + }), true) if err != nil { return nil, err } @@ -470,9 +534,9 @@ func (s *groupServer) GetGroupMembersInfo(ctx context.Context, req *pbGroup.GetG if err != nil { return nil, err } - nameMap, err := GetUsername(ctx, utils.Filter(members, func(e *relationTb.GroupMemberModel) (string, bool) { + nameMap, err := s.GetUsernameMap(ctx, utils.Filter(members, func(e *relationTb.GroupMemberModel) (string, bool) { return e.UserID, e.Nickname == "" - })) + }), true) if err != nil { return nil, err } @@ -505,13 +569,10 @@ func (s *groupServer) GetGroupApplicationList(ctx context.Context, req *pbGroup. } userIDs = utils.Distinct(userIDs) groupIDs = utils.Distinct(groupIDs) - userMap, err := GetPublicUserInfoMap(ctx, userIDs) + userMap, err := s.user.GetPublicUserInfoMap(ctx, userIDs, true) if err != nil { return nil, err } - if ids := utils.Single(utils.Keys(userMap), userIDs); len(ids) > 0 { - return nil, constant.ErrUserIDNotFound.Wrap(strings.Join(ids, ",")) - } groups, err := s.GroupInterface.FindGroup(ctx, utils.Distinct(groupIDs)) if err != nil { return nil, err @@ -590,19 +651,18 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbGroup if groupRequest.HandleResult != 0 { return nil, constant.ErrArgs.Wrap("group request already processed") } - if _, err := s.GroupInterface.TakeGroupMember(ctx, req.GroupID, req.FromUserID); err != nil { - if !IsNotFound(err) { - return nil, err - } - } else { - return nil, constant.ErrArgs.Wrap("already in group") + var join bool + if _, err = s.GroupInterface.TakeGroupMember(ctx, req.GroupID, req.FromUserID); err == nil { + join = true // 已经在群里了 + } else if !s.IsNotFound(err) { + return nil, err } - user, err := GetPublicUserInfoOne(ctx, req.FromUserID) + user, err := s.user.GetPublicUserInfo(ctx, req.FromUserID) if err != nil { return nil, err } var member *relationTb.GroupMemberModel - if req.HandleResult == constant.GroupResponseAgree { + if (!join) && req.HandleResult == constant.GroupResponseAgree { member = &relationTb.GroupMemberModel{ GroupID: req.GroupID, UserID: user.UserID, @@ -615,25 +675,27 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbGroup OperatorUserID: tracelog.GetOpUserID(ctx), Ex: groupRequest.Ex, } - if err = CallbackBeforeMemberJoinGroup(ctx, tracelog.GetOperationID(ctx), member, group.Ex); err != nil { + if err = CallbackBeforeMemberJoinGroup(ctx, member, group.Ex); err != nil { return nil, err } } if err := s.GroupInterface.HandlerGroupRequest(ctx, req.GroupID, req.FromUserID, req.HandledMsg, req.HandleResult, member); err != nil { return nil, err } - if req.HandleResult == constant.GroupResponseAgree { - chat.GroupApplicationAcceptedNotification(req) - chat.MemberEnterNotification(req) - } else if req.HandleResult == constant.GroupResponseRefuse { - chat.GroupApplicationRejectedNotification(req) + if !join { + if req.HandleResult == constant.GroupResponseAgree { + chat.GroupApplicationAcceptedNotification(req) + chat.MemberEnterNotification(ctx, req) + } else if req.HandleResult == constant.GroupResponseRefuse { + chat.GroupApplicationRejectedNotification(req) + } } return resp, nil } func (s *groupServer) JoinGroup(ctx context.Context, req *pbGroup.JoinGroupReq) (*pbGroup.JoinGroupResp, error) { resp := &pbGroup.JoinGroupResp{} - if _, err := GetPublicUserInfoOne(ctx, tracelog.GetOpUserID(ctx)); err != nil { + if _, err := s.user.GetPublicUserInfo(ctx, tracelog.GetOpUserID(ctx)); err != nil { return nil, err } group, err := s.GroupInterface.TakeGroup(ctx, req.GroupID) @@ -657,7 +719,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbGroup.JoinGroupReq) groupMember.OperatorUserID = tracelog.GetOpUserID(ctx) groupMember.JoinSource = constant.JoinByInvitation groupMember.InviterUserID = tracelog.GetOpUserID(ctx) - if err := CallbackBeforeMemberJoinGroup(ctx, tracelog.GetOperationID(ctx), groupMember, group.Ex); err != nil { + if err := CallbackBeforeMemberJoinGroup(ctx, groupMember, group.Ex); err != nil { return nil, err } if err := s.GroupInterface.CreateGroup(ctx, nil, []*relationTb.GroupMemberModel{groupMember}); err != nil { @@ -732,7 +794,7 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbGroup.SetGroupInf } chat.GroupInfoSetNotification(tracelog.GetOperationID(ctx), tracelog.GetOpUserID(ctx), req.GroupInfoForSet.GroupID, group.GroupName, group.Notification, group.Introduction, group.FaceURL, req.GroupInfoForSet.NeedVerification) if req.GroupInfoForSet.Notification != "" { - GroupNotification(ctx, group.GroupID) + s.GroupNotification(ctx, group.GroupID) } return resp, nil } @@ -830,9 +892,9 @@ func (s *groupServer) GetGroupMembersCMS(ctx context.Context, req *pbGroup.GetGr return nil, err } resp.Total = total - nameMap, err := GetUsername(ctx, utils.Filter(members, func(e *relationTb.GroupMemberModel) (string, bool) { + nameMap, err := s.GetUsernameMap(ctx, utils.Filter(members, func(e *relationTb.GroupMemberModel) (string, bool) { return e.UserID, e.Nickname == "" - })) + }), true) if err != nil { return nil, err } @@ -847,7 +909,7 @@ func (s *groupServer) GetGroupMembersCMS(ctx context.Context, req *pbGroup.GetGr func (s *groupServer) GetUserReqApplicationList(ctx context.Context, req *pbGroup.GetUserReqApplicationListReq) (*pbGroup.GetUserReqApplicationListResp, error) { resp := &pbGroup.GetUserReqApplicationListResp{} - user, err := GetPublicUserInfoOne(ctx, req.UserID) + user, err := s.user.GetPublicUserInfo(ctx, req.UserID) if err != nil { return nil, err } @@ -1105,9 +1167,9 @@ func (s *groupServer) GetUserInGroupMembers(ctx context.Context, req *pbGroup.Ge if err != nil { return nil, err } - nameMap, err := GetUsername(ctx, utils.Filter(members, func(e *relationTb.GroupMemberModel) (string, bool) { + nameMap, err := s.GetUsernameMap(ctx, utils.Filter(members, func(e *relationTb.GroupMemberModel) (string, bool) { return e.UserID, e.Nickname == "" - })) + }), true) if err != nil { return nil, err } diff --git a/internal/rpc/group/utils.go b/internal/rpc/group/utils.go deleted file mode 100644 index 51a774c04..000000000 --- a/internal/rpc/group/utils.go +++ /dev/null @@ -1,13 +0,0 @@ -package group - -import ( - "Open_IM/pkg/common/tracelog" - "gorm.io/gorm" -) - -func IsNotFound(err error) bool { - if err == nil { - return false - } - return tracelog.Unwrap(err) == gorm.ErrRecordNotFound -} diff --git a/pkg/callbackstruct/group.go b/pkg/callbackstruct/group.go index e504151c1..a84753326 100644 --- a/pkg/callbackstruct/group.go +++ b/pkg/callbackstruct/group.go @@ -1,7 +1,7 @@ package callbackstruct import ( - "Open_IM/pkg/proto/group" + "Open_IM/pkg/apistruct" common "Open_IM/pkg/proto/sdkws" ) @@ -9,7 +9,7 @@ type CallbackBeforeCreateGroupReq struct { CallbackCommand string `json:"callbackCommand"` OperationID string `json:"operationID"` common.GroupInfo - InitMemberList []*group.GroupAddMemberInfo `json:"initMemberList"` + InitMemberList []*apistruct.GroupAddMemberInfo `json:"initMemberList"` } type CallbackBeforeCreateGroupResp struct { diff --git a/pkg/common/constant/errors.go b/pkg/common/constant/errors.go index 8dc933b22..fc5984946 100644 --- a/pkg/common/constant/errors.go +++ b/pkg/common/constant/errors.go @@ -13,6 +13,7 @@ var ( ErrUserIDNotFound = &ErrInfo{UserIDNotFoundError, "UserIDNotFoundError", ""} ErrGroupIDNotFound = &ErrInfo{GroupIDNotFoundError, "GroupIDNotFoundError", ""} + ErrGroupIDExisted = &ErrInfo{GroupIDNotFoundError, "GroupIDExisted", ""} // todo group id 已存在 ErrRecordNotFound = &ErrInfo{RecordNotFoundError, "RecordNotFoundError", ""} diff --git a/pkg/common/db/cache/group.go b/pkg/common/db/cache/group.go index 8376a1d56..0e8322f0d 100644 --- a/pkg/common/db/cache/group.go +++ b/pkg/common/db/cache/group.go @@ -1,17 +1,14 @@ package cache import ( - "Open_IM/pkg/common/db/relation" relationTb "Open_IM/pkg/common/db/table/relation" "Open_IM/pkg/common/db/unrelation" "Open_IM/pkg/common/tracelog" "Open_IM/pkg/utils" "context" - "encoding/json" "github.com/dtm-labs/rockscache" "github.com/go-redis/redis/v8" "math/big" - "strconv" "strings" "time" ) @@ -157,6 +154,27 @@ func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID strin }) } +func (g *GroupCacheRedis) GetGroupMemberHash1(ctx context.Context, groupIDs []string) (map[string]*relationTb.GroupSimpleUserID, error) { + // todo + mapGroupUserIDs, err := g.groupMember.FindJoinUserID(ctx, groupIDs) + if err != nil { + return nil, err + } + res := make(map[string]*relationTb.GroupSimpleUserID) + for _, groupID := range groupIDs { + userIDs := mapGroupUserIDs[groupID] + users := &relationTb.GroupSimpleUserID{} + if len(userIDs) > 0 { + utils.Sort(userIDs, true) + bi := big.NewInt(0) + bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16) + users.Hash = bi.Uint64() + } + res[groupID] = users + } + return res, nil +} + func (g *GroupCacheRedis) DelGroupMembersHash(ctx context.Context, groupID string) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID) @@ -178,111 +196,104 @@ func (g *GroupCacheRedis) DelGroupMemberIDs(ctx context.Context, groupID string) return g.rcClient.TagAsDeleted(g.getGroupMemberIDsKey(groupID)) } -// JoinedGroups -func (g *GroupCacheRedis) GetJoinedGroupIDs(ctx context.Context, userID string) (joinedGroupIDs []string, err error) { - getJoinedGroupIDList := func() (string, error) { - joinedGroupList, err := relation.GetJoinedGroupIDListByUserID(userID) - if err != nil { - return "", err - } - bytes, err := json.Marshal(joinedGroupList) - if err != nil { - return "", utils.Wrap(err, "") - } - return string(bytes), nil - } - defer func() { - tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID, "joinedGroupIDs", joinedGroupIDs) - }() - joinedGroupIDListStr, err := g.rcClient.Fetch(g.getJoinedGroupsKey(userID), time.Second*30*60, getJoinedGroupIDList) - if err != nil { - return nil, err - } - err = json.Unmarshal([]byte(joinedGroupIDListStr), &joinedGroupIDs) - return joinedGroupIDs, utils.Wrap(err, "") -} +//// JoinedGroups +//func (g *GroupCacheRedis) GetJoinedGroupIDs(ctx context.Context, userID string) (joinedGroupIDs []string, err error) { +// getJoinedGroupIDList := func() (string, error) { +// joinedGroupList, err := relation.GetJoinedGroupIDListByUserID(userID) +// if err != nil { +// return "", err +// } +// bytes, err := json.Marshal(joinedGroupList) +// if err != nil { +// return "", utils.Wrap(err, "") +// } +// return string(bytes), nil +// } +// defer func() { +// tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID, "joinedGroupIDs", joinedGroupIDs) +// }() +// joinedGroupIDListStr, err := g.rcClient.Fetch(g.getJoinedGroupsKey(userID), time.Second*30*60, getJoinedGroupIDList) +// if err != nil { +// return nil, err +// } +// err = json.Unmarshal([]byte(joinedGroupIDListStr), &joinedGroupIDs) +// return joinedGroupIDs, utils.Wrap(err, "") +//} -func (g *GroupCacheRedis) DelJoinedGroupIDs(ctx context.Context, userID string) (err error) { +func (g *GroupCacheRedis) DelJoinedGroupID(ctx context.Context, userID string) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID) }() return g.rcClient.TagAsDeleted(g.getJoinedGroupsKey(userID)) } -// GetGroupMemberInfo -func (g *GroupCacheRedis) GetGroupMemberInfo(ctx context.Context, groupID, userID string) (groupMember *relation.GroupMember, err error) { - getGroupMemberInfo := func() (string, error) { - groupMemberInfo, err := relation.GetGroupMemberInfoByGroupIDAndUserID(groupID, userID) - if err != nil { - return "", err - } - bytes, err := json.Marshal(groupMemberInfo) - if err != nil { - return "", utils.Wrap(err, "") - } - return string(bytes), nil - } - defer func() { - tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID, "groupMember", *groupMember) - }() - groupMemberInfoStr, err := g.rcClient.Fetch(g.getGroupMemberInfoKey(groupID, userID), time.Second*30*60, getGroupMemberInfo) - if err != nil { - return nil, err - } - groupMember = &relation.GroupMember{} - err = json.Unmarshal([]byte(groupMemberInfoStr), groupMember) - return groupMember, utils.Wrap(err, "") +//func (g *GroupCacheRedis) DelJoinedGroupIDs(ctx context.Context, userIDs []string) (err error) { +// defer func() { +// tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID) +// }() +// for _, userID := range userIDs { +// if err := g.DelJoinedGroupID(ctx, userID); err != nil { +// return err +// } +// } +// return nil +//} + +func (g *GroupCacheRedis) GetGroupMemberInfo(ctx context.Context, groupID, userID string) (groupMember *relationTb.GroupMemberModel, err error) { + return GetCache(ctx, g.rcClient, g.getGroupMemberInfoKey(groupID, userID), g.expireTime, func(ctx context.Context) (*relationTb.GroupMemberModel, error) { + return g.groupMember.Take(ctx, groupID, userID) + }) } -func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, groupID, userIDs []string) (groupMember *relationTb.GroupMemberModel, err error) { +//func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, groupID, userIDs []string) (groupMember *relationTb.GroupMemberModel, err error) { +// +// return nil, err +//} - return nil, err -} - -func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, count, offset int32, groupID string) (groupMembers []*relation.GroupMember, err error) { - defer func() { - tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "count", count, "offset", offset, "groupID", groupID, "groupMember", groupMembers) - }() - groupMemberIDList, err := g.GetGroupMemberIDs(ctx, groupID) - if err != nil { - return nil, err - } - if count < 0 || offset < 0 { - return nil, nil - } - var groupMemberList []*relation.GroupMember - var start, stop int32 - start = offset - stop = offset + count - l := int32(len(groupMemberIDList)) - if start > stop { - return nil, nil - } - if start >= l { - return nil, nil - } - if count != 0 { - if stop >= l { - stop = l - } - groupMemberIDList = groupMemberIDList[start:stop] - } else { - if l < 1000 { - stop = l - } else { - stop = 1000 - } - groupMemberIDList = groupMemberIDList[start:stop] - } - for _, userID := range groupMemberIDList { - groupMember, err := g.GetGroupMemberInfo(ctx, groupID, userID) - if err != nil { - return - } - groupMembers = append(groupMembers, groupMember) - } - return groupMemberList, nil -} +//func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, count, offset int32, groupID string) (groupMembers []*relation.GroupMember, err error) { +// defer func() { +// tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "count", count, "offset", offset, "groupID", groupID, "groupMember", groupMembers) +// }() +// groupMemberIDList, err := g.GetGroupMemberIDs(ctx, groupID) +// if err != nil { +// return nil, err +// } +// if count < 0 || offset < 0 { +// return nil, nil +// } +// var groupMemberList []*relation.GroupMember +// var start, stop int32 +// start = offset +// stop = offset + count +// l := int32(len(groupMemberIDList)) +// if start > stop { +// return nil, nil +// } +// if start >= l { +// return nil, nil +// } +// if count != 0 { +// if stop >= l { +// stop = l +// } +// groupMemberIDList = groupMemberIDList[start:stop] +// } else { +// if l < 1000 { +// stop = l +// } else { +// stop = 1000 +// } +// groupMemberIDList = groupMemberIDList[start:stop] +// } +// for _, userID := range groupMemberIDList { +// groupMember, err := g.GetGroupMemberInfo(ctx, groupID, userID) +// if err != nil { +// return +// } +// groupMembers = append(groupMembers, groupMember) +// } +// return groupMemberList, nil +//} func (g *GroupCacheRedis) DelGroupMemberInfo(ctx context.Context, groupID, userID string) (err error) { defer func() { @@ -292,23 +303,23 @@ func (g *GroupCacheRedis) DelGroupMemberInfo(ctx context.Context, groupID, userI } // groupMemberNum -func (g *GroupCacheRedis) GetGroupMemberNum(ctx context.Context, groupID string) (num int, err error) { - getGroupMemberNum := func() (string, error) { - num, err := relation.GetGroupMemberNumByGroupID(groupID) - if err != nil { - return "", err - } - return strconv.Itoa(int(num)), nil - } - defer func() { - tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "num", num) - }() - groupMember, err := g.rcClient.Fetch(g.getGroupMemberNumKey(groupID), time.Second*30*60, getGroupMemberNum) - if err != nil { - return 0, err - } - return strconv.Atoi(groupMember) -} +//func (g *GroupCacheRedis) GetGroupMemberNum(ctx context.Context, groupID string) (num int, err error) { +// getGroupMemberNum := func() (string, error) { +// num, err := relation.GetGroupMemberNumByGroupID(groupID) +// if err != nil { +// return "", err +// } +// return strconv.Itoa(int(num)), nil +// } +// defer func() { +// tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "num", num) +// }() +// groupMember, err := g.rcClient.Fetch(g.getGroupMemberNumKey(groupID), time.Second*30*60, getGroupMemberNum) +// if err != nil { +// return 0, err +// } +// return strconv.Atoi(groupMember) +//} func (g *GroupCacheRedis) DelGroupMemberNum(ctx context.Context, groupID string) (err error) { defer func() { diff --git a/pkg/common/db/controller/group.go b/pkg/common/db/controller/group.go index ba39bb511..8a39442c8 100644 --- a/pkg/common/db/controller/group.go +++ b/pkg/common/db/controller/group.go @@ -15,8 +15,6 @@ import ( "github.com/go-redis/redis/v8" "go.mongodb.org/mongo-driver/mongo" "gorm.io/gorm" - "math/big" - "strings" ) //type GroupInterface GroupDataBaseInterface @@ -248,7 +246,7 @@ type GroupDataBase struct { func (g *GroupDataBase) delGroupMemberCache(ctx context.Context, groupID string, userIDs []string) error { for _, userID := range userIDs { - if err := g.cache.DelJoinedGroupIDs(ctx, userID); err != nil { + if err := g.cache.DelJoinedGroupID(ctx, userID); err != nil { return err } if err := g.cache.DelJoinedSuperGroupIDs(ctx, userID); err != nil { @@ -272,21 +270,24 @@ func (g *GroupDataBase) FindGroupMemberUserID(ctx context.Context, groupID strin } func (g *GroupDataBase) CreateGroup(ctx context.Context, groups []*relationTb.GroupModel, groupMembers []*relationTb.GroupMemberModel) error { - if len(groups) > 0 && len(groupMembers) > 0 { - return g.db.Transaction(func(tx *gorm.DB) error { + return g.db.Transaction(func(tx *gorm.DB) error { + if len(groups) > 0 { 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 + } + if len(groupMembers) > 0 { + if err := g.groupMemberDB.Create(ctx, groupMembers, tx); err != nil { + return err + } + //if err := g.cache.DelJoinedGroupIDs(ctx, utils.Slice(groupMembers, func(e *relationTb.GroupMemberModel) string { + // return e.UserID + //})); err != nil { + // return err + //} + } + return nil + }) } func (g *GroupDataBase) TakeGroup(ctx context.Context, groupID string) (group *relationTb.GroupModel, err error) { @@ -337,12 +338,11 @@ func (g *GroupDataBase) TakeGroupMember(ctx context.Context, groupID string, use } func (g *GroupDataBase) TakeGroupOwner(ctx context.Context, groupID string) (*relationTb.GroupMemberModel, error) { - return g.groupMemberDB.TakeOwner(ctx, groupID) + return g.groupMemberDB.TakeOwner(ctx, groupID) // todo cache group owner } func (g *GroupDataBase) FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relationTb.GroupMemberModel, error) { - //g.cache.GetGroupMembersInfo() - return g.groupMemberDB.Find(ctx, groupIDs, userIDs, roleLevels) + return g.groupMemberDB.Find(ctx, groupIDs, userIDs, roleLevels) // todo cache group find } func (g *GroupDataBase) PageGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (uint32, []*relationTb.GroupMemberModel, error) { @@ -383,23 +383,7 @@ func (g *GroupDataBase) DeleteGroupMember(ctx context.Context, groupID string, u } func (g *GroupDataBase) MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*relationTb.GroupSimpleUserID, error) { - mapGroupUserIDs, err := g.groupMemberDB.FindJoinUserID(ctx, groupIDs) - if err != nil { - return nil, err - } - res := make(map[string]*relationTb.GroupSimpleUserID) - for _, groupID := range groupIDs { - userIDs := mapGroupUserIDs[groupID] - users := &relationTb.GroupSimpleUserID{} - if len(userIDs) > 0 { - utils.Sort(userIDs, true) - bi := big.NewInt(0) - bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16) - users.Hash = bi.Uint64() - } - res[groupID] = users - } - return res, nil + return g.cache.GetGroupMemberHash1(ctx, groupIDs) } func (g *GroupDataBase) MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) { diff --git a/pkg/utils/utils_v2.go b/pkg/utils/utils_v2.go index 91c8fecd9..bd2959845 100644 --- a/pkg/utils/utils_v2.go +++ b/pkg/utils/utils_v2.go @@ -412,3 +412,16 @@ func (o *sortSlice[E]) Swap(i, j int) { type Ordered interface { ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64 | ~string } + +func Unwrap(err error) error { + for err != nil { + unwrap, ok := err.(interface { + Unwrap() error + }) + if !ok { + break + } + err = unwrap.Unwrap() + } + return err +}