From 210d04d4882482ffbde72cecfa71dcbc48619436 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Mon, 6 Feb 2023 15:32:20 +0800 Subject: [PATCH] rpc GroupApplicationResponse --- internal/rpc/group/callback.go | 4 +- internal/rpc/group/copy.go | 15 ++++- internal/rpc/group/g.go | 17 +++-- internal/rpc/group/group.go | 101 +++++++++++++++--------------- internal/rpc/group/utils.go | 13 ++++ pkg/common/db/controller/group.go | 8 ++- pkg/utils/utils_v2.go | 10 +-- 7 files changed, 97 insertions(+), 71 deletions(-) create mode 100644 internal/rpc/group/utils.go diff --git a/internal/rpc/group/callback.go b/internal/rpc/group/callback.go index cd964af53..e60186d8b 100644 --- a/internal/rpc/group/callback.go +++ b/internal/rpc/group/callback.go @@ -4,7 +4,7 @@ import ( cbApi "Open_IM/pkg/callback_struct" "Open_IM/pkg/common/config" "Open_IM/pkg/common/constant" - relation "Open_IM/pkg/common/db/mysql" + "Open_IM/pkg/common/db/table/relation" "Open_IM/pkg/common/http" "Open_IM/pkg/common/log" "Open_IM/pkg/common/tracelog" @@ -77,7 +77,7 @@ func callbackBeforeCreateGroup(ctx context.Context, req *pbGroup.CreateGroupReq) return err } -func CallbackBeforeMemberJoinGroup(ctx context.Context, operationID string, groupMember *relation.GroupMember, groupEx string) (err error) { +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) }() diff --git a/internal/rpc/group/copy.go b/internal/rpc/group/copy.go index 766d4b551..95d9d9429 100644 --- a/internal/rpc/group/copy.go +++ b/internal/rpc/group/copy.go @@ -2,10 +2,12 @@ package group import ( "Open_IM/pkg/common/db/table/relation" + pbGroup "Open_IM/pkg/proto/group" open_im_sdk "Open_IM/pkg/proto/sdk_ws" + "time" ) -func ModelToGroupInfo(m *relation.GroupModel, ownerUserID string, memberCount uint32) *open_im_sdk.GroupInfo { +func DbToPbGroupInfo(m *relation.GroupModel, ownerUserID string, memberCount uint32) *open_im_sdk.GroupInfo { return &open_im_sdk.GroupInfo{ GroupID: m.GroupID, GroupName: m.GroupName, @@ -26,3 +28,14 @@ func ModelToGroupInfo(m *relation.GroupModel, ownerUserID string, memberCount ui NotificationUserID: m.NotificationUserID, } } + +func PbToDbGroupRequest(req *pbGroup.GroupApplicationResponseReq, handleUserID string) *relation.GroupRequestModel { + return &relation.GroupRequestModel{ + UserID: req.FromUserID, + GroupID: req.GroupID, + HandleResult: req.HandleResult, + HandledMsg: req.HandledMsg, + HandleUserID: handleUserID, + HandledTime: time.Now(), + } +} diff --git a/internal/rpc/group/g.go b/internal/rpc/group/g.go index a0d1ea3ec..6be1fa8c0 100644 --- a/internal/rpc/group/g.go +++ b/internal/rpc/group/g.go @@ -5,19 +5,12 @@ import ( sdk_ws "Open_IM/pkg/proto/sdk_ws" "Open_IM/pkg/utils" "context" + "errors" "math/big" "strconv" "time" ) -//func getDBGroupRequest(ctx context.Context, req *pbGroup.GroupApplicationResponseReq) (dbGroupRequest *relation.GroupRequest) { -// dbGroupRequest = &relation.GroupRequest{} -// utils.CopyStructFields(&dbGroupRequest, req) -// dbGroupRequest.UserID = req.FromUserID -// dbGroupRequest.HandleUserID = utils.OpUserID(ctx) -// dbGroupRequest.HandledTime = time.Now() -// return dbGroupRequest -//} // //func getDBGroupMember(ctx context.Context, groupID, userID string) (dbGroupMember *relation.GroupMember, err error) { // dbGroupMember = &relation.GroupMember{} @@ -37,8 +30,12 @@ import ( // return dbGroupMember, nil //} +func GetPublicUserInfoOne(ctx context.Context, userID string) (*sdk_ws.PublicUserInfo, error) { + return nil, errors.New("todo") +} + func GetUsersInfo(ctx context.Context, userIDs []string) ([]*sdk_ws.UserInfo, error) { - return nil, nil + return nil, errors.New("todo") } func GetUserInfoMap(ctx context.Context, userIDs []string) (map[string]*sdk_ws.UserInfo, error) { @@ -52,7 +49,7 @@ func GetUserInfoMap(ctx context.Context, userIDs []string) (map[string]*sdk_ws.U } func GetPublicUserInfo(ctx context.Context, userIDs []string) ([]*sdk_ws.PublicUserInfo, error) { - return nil, nil + return nil, errors.New("todo") } func GetPublicUserInfoMap(ctx context.Context, userIDs []string) (map[string]*sdk_ws.PublicUserInfo, error) { diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index d5890cbb5..43751273c 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -1,7 +1,6 @@ package group import ( - "Open_IM/internal/rpc/fault_tolerant" chat "Open_IM/internal/rpc/msg" "Open_IM/pkg/common/config" "Open_IM/pkg/common/constant" @@ -571,7 +570,7 @@ func (s *groupServer) GetGroupApplicationList(ctx context.Context, req *pbGroup. groupRequest := open_im_sdk.GroupRequest{UserInfo: &open_im_sdk.PublicUserInfo{}} utils.CopyStructFields(&groupRequest, gr) groupRequest.UserInfo = userMap[gr.UserID] - groupRequest.GroupInfo = ModelToGroupInfo(groupMap[gr.GroupID], groupOwnerUserIDMap[gr.GroupID], uint32(groupMemberNumMap[gr.GroupID])) + groupRequest.GroupInfo = DbToPbGroupInfo(groupMap[gr.GroupID], groupOwnerUserIDMap[gr.GroupID], uint32(groupMemberNumMap[gr.GroupID])) resp.GroupRequests = append(resp.GroupRequests, &groupRequest) } return resp, nil @@ -595,73 +594,73 @@ func (s *groupServer) GetGroupsInfo(ctx context.Context, req *pbGroup.GetGroupsI return nil, err } resp.GroupInfos = utils.Slice(groups, func(e *relation2.GroupModel) *open_im_sdk.GroupInfo { - return ModelToGroupInfo(e, groupOwnerUserIDMap[e.GroupID], uint32(groupMemberNumMap[e.GroupID])) + return DbToPbGroupInfo(e, groupOwnerUserIDMap[e.GroupID], uint32(groupMemberNumMap[e.GroupID])) }) return resp, nil } -//func CheckPermission(ctx context.Context, groupID string, userID string) (err error) { -// defer func() { -// tracelog.SetCtxInfo(ctx, utils.GetSelfFuncName(), err, "groupID", groupID, "userID", userID) -// }() -// if !token_verify.IsManagerUserID(userID) && !relation.IsGroupOwnerAdmin(groupID, userID) { -// return utils.Wrap(constant.ErrNoPermission, utils.GetSelfFuncName()) -// } -// return nil -//} - func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbGroup.GroupApplicationResponseReq) (*pbGroup.GroupApplicationResponseResp, error) { resp := &pbGroup.GroupApplicationResponseResp{} - - if err := CheckPermission(ctx, req.GroupID, tracelog.GetOpUserID(ctx)); err != nil { - return nil, err + if !utils.Contain(req.HandleResult, constant.GroupResponseAgree, constant.GroupResponseRefuse) { + return nil, constant.ErrArgs.Wrap("HandleResult unknown") } - groupRequest := getDBGroupRequest(ctx, req) - if err := (&relation2.GroupRequestModel{}).Update(ctx, []*relation2.GroupRequestModel{groupRequest}); err != nil { - return nil, err + if !token_verify.IsAppManagerUid(ctx) { + groupMember, err := s.GroupInterface.TakeGroupMemberByID(ctx, req.GroupID, req.FromUserID) + if err != nil { + return nil, err + } + if !(groupMember.RoleLevel == constant.GroupOwner || groupMember.RoleLevel == constant.GroupAdmin) { + return nil, constant.ErrNoPermission.Wrap("no group owner or admin") + } } - groupInfo, err := rocksCache.GetGroupInfoFromCache(ctx, req.GroupID) + group, err := s.GroupInterface.TakeGroupByID(ctx, req.GroupID) if err != nil { return nil, err } + groupRequest, err := s.GroupInterface.TakeGroupRequest(ctx, req.GroupID, req.FromUserID) + if err != nil { + return nil, err + } + if groupRequest.HandleResult != 0 { + return nil, constant.ErrArgs.Wrap("group request already processed") + } + if _, err := s.GroupInterface.TakeGroupMemberByID(ctx, req.GroupID, req.FromUserID); err != nil { + if !IsNotFound(err) { + return nil, err + } + } else { + return nil, constant.ErrArgs.Wrap("already in group") + } + user, err := GetPublicUserInfoOne(ctx, req.FromUserID) + if err != nil { + return nil, err + } + var member *relation2.GroupMemberModel if req.HandleResult == constant.GroupResponseAgree { - member, err := getDBGroupMember(ctx, req.GroupID, req.FromUserID) - if err != nil { + member = &relation2.GroupMemberModel{ + GroupID: req.GroupID, + UserID: user.UserID, + Nickname: user.Nickname, + FaceURL: user.FaceURL, + RoleLevel: constant.GroupOrdinaryUsers, + JoinTime: time.Now(), + JoinSource: groupRequest.JoinSource, + InviterUserID: groupRequest.InviterUserID, + OperatorUserID: tracelog.GetOpUserID(ctx), + Ex: groupRequest.Ex, + } + if err = CallbackBeforeMemberJoinGroup(ctx, tracelog.GetOperationID(ctx), member, group.Ex); err != nil { return nil, err } - err = CallbackBeforeMemberJoinGroup(ctx, tracelog.GetOperationID(ctx), member, groupInfo.Ex) - if err != nil { - return nil, err - } - err = (&relation2.GroupMemberModel{}).Create(ctx, []*relation2.GroupMemberModel{member}) - if err != nil { - return nil, err - } - etcdCacheConn, err := fault_tolerant.GetDefaultConn(config.Config.RpcRegisterName.OpenImCacheName, tracelog.GetOperationID(ctx)) - if err != nil { - return nil, err - } - cacheClient := pbCache.NewCacheClient(etcdCacheConn) - cacheResp, err := cacheClient.DelGroupMemberIDListFromCache(context.Background(), &pbCache.DelGroupMemberIDListFromCacheReq{OperationID: tracelog.GetOperationID(ctx), GroupID: req.GroupID}) - if err != nil { - return nil, err - } - if cacheResp.CommonResp.ErrCode != 0 { - return nil, utils.Wrap(&constant.ErrInfo{ - ErrCode: cacheResp.CommonResp.ErrCode, - ErrMsg: cacheResp.CommonResp.ErrMsg, - }, "") - } - _ = rocksCache.DelGroupMemberListHashFromCache(ctx, req.GroupID) - _ = rocksCache.DelJoinedGroupIDListFromCache(ctx, req.FromUserID) - _ = rocksCache.DelGroupMemberNumFromCache(ctx, req.GroupID) + } + 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) - } else { - //return nil, utils.Wrap(constant.ErrArgs, "") - return nil, constant.ErrArgs.Wrap() } return resp, nil } diff --git a/internal/rpc/group/utils.go b/internal/rpc/group/utils.go new file mode 100644 index 000000000..51a774c04 --- /dev/null +++ b/internal/rpc/group/utils.go @@ -0,0 +1,13 @@ +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/common/db/controller/group.go b/pkg/common/db/controller/group.go index 0a1cd5f77..1dffd2592 100644 --- a/pkg/common/db/controller/group.go +++ b/pkg/common/db/controller/group.go @@ -4,6 +4,7 @@ import ( "Open_IM/pkg/common/db/cache" "Open_IM/pkg/common/db/relation" relation2 "Open_IM/pkg/common/db/table/relation" + unrelation2 "Open_IM/pkg/common/db/table/unrelation" "Open_IM/pkg/common/db/unrelation" "context" "github.com/dtm-labs/rockscache" @@ -18,7 +19,7 @@ type GroupInterface interface { CreateGroup(ctx context.Context, groups []*relation2.GroupModel, groupMember []*relation2.GroupMemberModel) error DeleteGroupByIDs(ctx context.Context, groupIDs []string) error TakeGroupByID(ctx context.Context, groupID string) (group *relation2.GroupModel, err error) - TakeGroupMemberByID(ctx context.Context, groupID string, userID string) (groupMember *relation2.GroupModel, err error) + TakeGroupMemberByID(ctx context.Context, groupID string, userID string) (groupMember *relation2.GroupMemberModel, err error) GetJoinedGroupList(ctx context.Context, userID string) ([]*relation2.GroupModel, error) GetGroupMemberList(ctx context.Context, groupID string) ([]*relation2.GroupMemberModel, error) GetGroupMemberListByUserID(ctx context.Context, groupID string, userIDs []string) ([]*relation2.GroupMemberModel, error) @@ -32,11 +33,14 @@ type GroupInterface interface { CreateGroupMember(ctx context.Context, groupMember []*relation2.GroupMemberModel) error CreateGroupRequest(ctx context.Context, requests []*relation2.GroupRequestModel) error + HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relation2.GroupMemberModel) error + TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relation2.GroupRequestModel, error) + //mongo CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string) error DelSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error AddUserToSuperGroup(ctx context.Context, groupID string, userIDs []string) error - GetSuperGroupByID(ctx context.Context, groupID string) (superGroup *unrelation.SuperGroup, err error) + GetSuperGroupByID(ctx context.Context, groupID string) (superGroup *unrelation2.SuperGroupModel, err error) } var _ GroupInterface = (*GroupController)(nil) diff --git a/pkg/utils/utils_v2.go b/pkg/utils/utils_v2.go index 3678c3775..0ee80d69e 100644 --- a/pkg/utils/utils_v2.go +++ b/pkg/utils/utils_v2.go @@ -67,7 +67,7 @@ func DeleteAt[E any](es *[]E, index ...int) []E { } // IndexAny get the index of the element -func IndexAny[E any, K comparable](es []E, e E, fn func(e E) K) int { +func IndexAny[E any, K comparable](e E, es []E, fn func(e E) K) int { k := fn(e) for i := 0; i < len(es); i++ { if fn(es[i]) == k { @@ -78,15 +78,15 @@ func IndexAny[E any, K comparable](es []E, e E, fn func(e E) K) int { } // IndexOf get the index of the element -func IndexOf[E comparable](es []E, e E) int { - return IndexAny(es, e, func(t E) E { +func IndexOf[E comparable](e E, es ...E) int { + return IndexAny(e, es, func(t E) E { return t }) } // Contain 是否包含 -func Contain[E comparable](es []E, e E) bool { - return IndexOf(es, e) >= 0 +func Contain[E comparable](e E, es ...E) bool { + return IndexOf(e, es...) >= 0 } // DuplicateAny 是否有重复的