From b6c4948bf2ff1914efa5dd4d98196af3dee0b5f8 Mon Sep 17 00:00:00 2001 From: away <1819625428@qq.com> Date: Mon, 28 Jun 2021 15:36:09 +0800 Subject: [PATCH] add group rpc server --- src/rpc/group/Makefile | 27 ++ src/rpc/group/group/create_group.go | 113 +++++++ .../group/group/get_group_applicationList.go | 21 ++ src/rpc/group/group/get_groups_info.go | 46 +++ src/rpc/group/group/group.go | 291 ++++++++++++++++++ .../group/group/group_application_response.go | 90 ++++++ src/rpc/group/group/join_group.go | 63 ++++ src/rpc/group/group/quti_group.go | 50 +++ src/rpc/group/group/set_group_info.go | 50 +++ src/rpc/group/group/transfer_group_owner.go | 36 +++ src/rpc/group/open_im_group.go | 13 + 11 files changed, 800 insertions(+) create mode 100644 src/rpc/group/Makefile create mode 100644 src/rpc/group/group/create_group.go create mode 100644 src/rpc/group/group/get_group_applicationList.go create mode 100644 src/rpc/group/group/get_groups_info.go create mode 100644 src/rpc/group/group/group.go create mode 100644 src/rpc/group/group/group_application_response.go create mode 100644 src/rpc/group/group/join_group.go create mode 100644 src/rpc/group/group/quti_group.go create mode 100644 src/rpc/group/group/set_group_info.go create mode 100644 src/rpc/group/group/transfer_group_owner.go create mode 100644 src/rpc/group/open_im_group.go diff --git a/src/rpc/group/Makefile b/src/rpc/group/Makefile new file mode 100644 index 000000000..2ada2e2a6 --- /dev/null +++ b/src/rpc/group/Makefile @@ -0,0 +1,27 @@ +.PHONY: all build run gotool install clean help + +BINARY_NAME=open_im_group +BIN_DIR=../../../bin/ +LAN_FILE=.go +GO_FILE:=${BINARY_NAME}${LAN_FILE} + +all: gotool build + +build: + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ${BINARY_NAME} ${GO_FILE} + +run: + @go run ./ + +gotool: + go fmt ./ + go vet ./ + +install: + make build + mv ${BINARY_NAME} ${BIN_DIR} + +clean: + @if [ -f ${BINARY_NAME} ] ; then rm ${BINARY_NAME} ; fi + + diff --git a/src/rpc/group/group/create_group.go b/src/rpc/group/group/create_group.go new file mode 100644 index 000000000..dd88f4c28 --- /dev/null +++ b/src/rpc/group/group/create_group.go @@ -0,0 +1,113 @@ +package group + +import ( + "Open_IM/src/common/config" + "Open_IM/src/common/constant" + "Open_IM/src/common/db/mysql_model/im_mysql_model" + "Open_IM/src/common/log" + pbChat "Open_IM/src/proto/chat" + pbGroup "Open_IM/src/proto/group" + "Open_IM/src/push/content_struct" + "Open_IM/src/push/logic" + "Open_IM/src/utils" + "context" + "github.com/skiffer-git/grpc-etcdv3/getcdv3" + "google.golang.org/grpc" + "net" + "strconv" + "strings" + "time" +) + +type groupServer struct { + rpcPort int + rpcRegisterName string + etcdSchema string + etcdAddr []string +} + +func NewGroupServer(port int) *groupServer { + return &groupServer{ + rpcPort: port, + rpcRegisterName: config.Config.RpcRegisterName.OpenImGroupName, + etcdSchema: config.Config.Etcd.EtcdSchema, + etcdAddr: config.Config.Etcd.EtcdAddr, + } +} +func (s *groupServer) Run() { + log.Info("", "", "rpc group init....") + + ip := utils.ServerIP + registerAddress := ip + ":" + strconv.Itoa(s.rpcPort) + //listener network + listener, err := net.Listen("tcp", registerAddress) + if err != nil { + log.InfoByArgs("listen network failed,err=%s", err.Error()) + return + } + log.Info("", "", "listen network success, address = %s", registerAddress) + defer listener.Close() + //grpc server + srv := grpc.NewServer() + defer srv.GracefulStop() + //Service registers with etcd + pbGroup.RegisterGroupServer(srv, s) + err = getcdv3.RegisterEtcd(s.etcdSchema, strings.Join(s.etcdAddr, ","), ip, s.rpcPort, s.rpcRegisterName, 10) + if err != nil { + log.ErrorByArgs("get etcd failed,err=%s", err.Error()) + return + } + err = srv.Serve(listener) + if err != nil { + log.ErrorByArgs("listen rpc_group error,err=%s", err.Error()) + return + } + log.Info("", "", "rpc create group init success") +} + +func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupReq) (*pbGroup.CreateGroupResp, error) { + log.InfoByArgs("rpc create group is server,args=%s", req.String()) + var ( + groupId string + ) + //Parse token, to find current user information + claims, err := utils.ParseToken(req.Token) + if err != nil { + log.Error(req.Token, req.OperationID, "err=%s,parse token failed", err.Error()) + return &pbGroup.CreateGroupResp{ErrorCode: config.ErrParseToken.ErrCode, ErrorMsg: config.ErrParseToken.ErrMsg}, nil + } + //Time stamp + MD5 to generate group chat id + groupId = utils.Md5(strconv.FormatInt(time.Now().Unix(), 10)) + err = im_mysql_model.InsertIntoGroup(groupId, req.GroupName, req.Introduction, req.Notification, req.FaceUrl) + if err != nil { + log.ErrorByKv("create group chat failed", req.OperationID, "err=%s", err.Error()) + return &pbGroup.CreateGroupResp{ErrorCode: config.ErrCreateGroup.ErrCode, ErrorMsg: config.ErrCreateGroup.ErrMsg}, nil + } + + //Add the group owner to the group first, otherwise the group creation will fail + err = im_mysql_model.InsertIntoGroupMember(groupId, claims.UID, "", "", constant.GroupCreator) + if err != nil { + log.Error("", req.OperationID, "create group chat failed,err=%s", err.Error()) + return &pbGroup.CreateGroupResp{ErrorCode: config.ErrCreateGroup.ErrCode, ErrorMsg: config.ErrCreateGroup.ErrMsg}, nil + } + //Binding group id and member id + for _, user := range req.MemberList { + err = im_mysql_model.InsertIntoGroupMember(groupId, user.Uid, "", "", user.SetRole) + if err != nil { + log.ErrorByArgs("pull %s to group %s failed,err=%s", user.Uid, groupId, err.Error()) + } + } + //Push message when create group chat + logic.SendMsgByWS(&pbChat.WSToMsgSvrChatMsg{ + SendID: claims.UID, + RecvID: groupId, + Content: content_struct.NewContentStructString(0, "", req.String()), + SendTime: utils.GetCurrentTimestampBySecond(), + MsgFrom: constant.SysMsgType, //Notification message identification + ContentType: constant.CreateGroupTip, //Add friend flag + SessionType: constant.GroupChatType, + OperationID: req.OperationID, + }) + log.Info(req.Token, req.OperationID, "rpc create group success return") + return &pbGroup.CreateGroupResp{GroupID: groupId}, nil +} diff --git a/src/rpc/group/group/get_group_applicationList.go b/src/rpc/group/group/get_group_applicationList.go new file mode 100644 index 000000000..f926b9c51 --- /dev/null +++ b/src/rpc/group/group/get_group_applicationList.go @@ -0,0 +1,21 @@ +package group + +import ( + "Open_IM/src/common/db/mysql_model/im_mysql_model" + "Open_IM/src/common/log" + "Open_IM/src/proto/group" + "context" +) + +func (s *groupServer) GetGroupApplicationList(_ context.Context, pb *group.GetGroupApplicationListReq) (*group.GetGroupApplicationListResp, error) { + log.Info("", "", "rpc GetGroupApplicationList call start..., [pb: %s]", pb.String()) + + reply, err := im_mysql_model.GetGroupApplicationList(pb.UID) + if err != nil { + log.Error("", "", "rpc GetGroupApplicationList call..., im_mysql_model.GetGroupApplicationList fail [uid: %s] [err: %s]", pb.UID, err.Error()) + return nil, err + } + log.Info("", "", "rpc GetGroupApplicationList call..., im_mysql_model.GetGroupApplicationList") + + return reply, nil +} diff --git a/src/rpc/group/group/get_groups_info.go b/src/rpc/group/group/get_groups_info.go new file mode 100644 index 000000000..7f8720a20 --- /dev/null +++ b/src/rpc/group/group/get_groups_info.go @@ -0,0 +1,46 @@ +package group + +import ( + "Open_IM/src/common/config" + "Open_IM/src/common/db/mysql_model/im_mysql_model" + "Open_IM/src/common/log" + pbGroup "Open_IM/src/proto/group" + "Open_IM/src/utils" + "context" +) + +func (s *groupServer) GetGroupsInfo(ctx context.Context, req *pbGroup.GetGroupsInfoReq) (*pbGroup.GetGroupsInfoResp, error) { + log.Info(req.Token, req.OperationID, "rpc get group info is server,args=%s", req.String()) + //Parse token, to find current user information + claims, err := utils.ParseToken(req.Token) + if err != nil { + log.Error(req.Token, req.OperationID, "err=%s,parse token failed", err.Error()) + return &pbGroup.GetGroupsInfoResp{ErrorCode: config.ErrParseToken.ErrCode, ErrorMsg: config.ErrParseToken.ErrMsg}, nil + } + groupsInfoList := make([]*pbGroup.GroupInfo, 0) + for _, groupID := range req.GroupIDList { + // Get group information to check whether the current user is in the current group + _, err = im_mysql_model.FindGroupMemberInfoByGroupIdAndUserId(groupID, claims.UID) + if err != nil { + log.Error(req.Token, req.OperationID, "find group member failed,err=%s", err.Error()) + continue + } + groupInfoFromMysql, err := im_mysql_model.FindGroupInfoByGroupId(groupID) + if err != nil { + log.Error(req.Token, req.OperationID, "find group info failed,err=%s", err.Error()) + continue + } + var groupInfo pbGroup.GroupInfo + groupInfo.GroupId = groupID + groupInfo.GroupName = groupInfoFromMysql.Name + groupInfo.Introduction = groupInfoFromMysql.Introduction + groupInfo.Notification = groupInfoFromMysql.Notification + groupInfo.FaceUrl = groupInfoFromMysql.FaceUrl + groupInfo.MemberCount = uint32(im_mysql_model.GetGroupMemberNumByGroupId(groupID)) + groupInfo.CreateTime = uint64(groupInfoFromMysql.CreateTime.Unix()) + + groupsInfoList = append(groupsInfoList, &groupInfo) + } + log.Info(req.Token, req.OperationID, "rpc get groupsInfo success return") + return &pbGroup.GetGroupsInfoResp{Data: groupsInfoList}, nil +} diff --git a/src/rpc/group/group/group.go b/src/rpc/group/group/group.go new file mode 100644 index 000000000..9a57defd5 --- /dev/null +++ b/src/rpc/group/group/group.go @@ -0,0 +1,291 @@ +package group + +import ( + "Open_IM/src/common/config" + "Open_IM/src/common/constant" + imdb "Open_IM/src/common/db/mysql_model/im_mysql_model" + "Open_IM/src/common/log" + pbChat "Open_IM/src/proto/chat" + pbGroup "Open_IM/src/proto/group" + "Open_IM/src/push/logic" + "Open_IM/src/utils" + "context" + "encoding/json" + "fmt" +) + +func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbGroup.GetJoinedGroupListReq) (*pbGroup.GetJoinedGroupListResp, error) { + claims, err := utils.ParseToken(req.Token) + if err != nil { + log.Error(req.Token, req.OperationID, "err=%s,parse token failed", err.Error()) + return &pbGroup.GetJoinedGroupListResp{ErrorCode: config.ErrParseToken.ErrCode, ErrorMsg: config.ErrParseToken.ErrMsg}, nil + } + log.Info(claims.UID, req.OperationID, "recv req: ", req.String()) + + joinedGroupList, err := imdb.GetJoinedGroupIdListByMemberId(claims.UID) + if err != nil { + log.Error(claims.UID, req.OperationID, "GetJoinedGroupIdListByMemberId failed, err: ", err.Error()) + return &pbGroup.GetJoinedGroupListResp{ErrorCode: config.ErrParam.ErrCode, ErrorMsg: config.ErrParam.ErrMsg}, nil + } + + var resp pbGroup.GetJoinedGroupListResp + + for _, v := range joinedGroupList { + var groupNode pbGroup.GroupInfo + num := imdb.GetGroupMemberNumByGroupId(v.GroupId) + owner := imdb.GetGroupOwnerByGroupId(v.GroupId) + group, err := imdb.FindGroupInfoByGroupId(v.GroupId) + if num > 0 && owner != "" && err == nil { + groupNode.FaceUrl = group.FaceUrl + groupNode.CreateTime = uint64(group.CreateTime.Unix()) + groupNode.GroupName = group.Name + groupNode.Introduction = group.Introduction + groupNode.Notification = group.Notification + groupNode.OwnerId = owner + groupNode.MemberCount = uint32(int32(num)) + resp.GroupList = append(resp.GroupList, &groupNode) + } + log.Info(claims.UID, req.OperationID, "member num: ", num, "owner: ", owner) + } + resp.ErrorCode = 0 + return &resp, nil +} + +func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbGroup.InviteUserToGroupReq) (*pbGroup.InviteUserToGroupResp, error) { + claims, err := utils.ParseToken(req.Token) + if err != nil { + log.Error(req.Token, req.OperationID, "err=%s,parse token failed", err.Error()) + return &pbGroup.InviteUserToGroupResp{ErrorCode: config.ErrParseToken.ErrCode, ErrorMsg: config.ErrParseToken.ErrMsg}, nil + } + log.Info(claims.UID, req.OperationID, "recv req: ", req.String()) + // + //from User: invite: applicant + //to user: invite: invited + //to application + var resp pbGroup.InviteUserToGroupResp + fromUserInfo, err := imdb.FindUserByUID(claims.UID) + if err != nil { + log.Error(claims.UID, req.OperationID, "FindUserByUID failed, err: ", err.Error()) + return &pbGroup.InviteUserToGroupResp{ErrorCode: config.ErrParam.ErrCode, ErrorMsg: config.ErrParam.ErrMsg}, nil + } + + for _, v := range req.UidList { + var resultNode pbGroup.Id2Result + resultNode.UId = v + resultNode.Result = 0 + toUserInfo, err := imdb.FindUserByUID(v) + if err != nil { + log.Error(v, req.OperationID, "FindUserByUID failed, err: ", err.Error()) + resultNode.Result = -1 + resp.Id2Result = append(resp.Id2Result, &resultNode) + continue + } + err = imdb.InsertGroupRequest(req.GroupID, fromUserInfo.UID, fromUserInfo.Name, fromUserInfo.Icon, toUserInfo.UID, req.Reason, "invited", 1) + if err != nil { + log.Error(v, req.OperationID, "InsertGroupRequest failed, err: ", err.Error(), "params: ", + req.GroupID, fromUserInfo.UID, fromUserInfo.Name, fromUserInfo.Icon, toUserInfo.UID, req.Reason) + resultNode.Result = -1 + resp.Id2Result = append(resp.Id2Result, &resultNode) + continue + } + err = imdb.InsertGroupMember(req.GroupID, toUserInfo.UID, toUserInfo.Name, toUserInfo.Icon, 0) + if err != nil { + log.Error(v, req.OperationID, "InsertGroupMember failed, ", err.Error(), "params: ", + req.GroupID, toUserInfo.UID, toUserInfo.Name, toUserInfo.Icon) + resultNode.Result = -1 + resp.Id2Result = append(resp.Id2Result, &resultNode) + continue + } + resp.Id2Result = append(resp.Id2Result, &resultNode) + } + resp.ErrorCode = 0 + resp.ErrorMsg = "ok" + + var chatMsg pbChat.WSToMsgSvrChatMsg + chatMsg.SendID = claims.UID + chatMsg.RecvID = req.GroupID + content, _ := json.Marshal(req) + chatMsg.Content = string(content) + chatMsg.SendTime = utils.GetCurrentTimestampBySecond() + chatMsg.MsgFrom = constant.UserMsgType + chatMsg.ContentType = constant.InviteUserToGroupTip + chatMsg.SessionType = constant.GroupChatType + logic.SendMsgByWS(&chatMsg) + + return &resp, nil +} + +func (s *groupServer) GetGroupAllMember(ctx context.Context, req *pbGroup.GetGroupAllMemberReq) (*pbGroup.GetGroupAllMemberResp, error) { + claims, err := utils.ParseToken(req.Token) + if err != nil { + log.Error(req.Token, req.OperationID, "err=%s,parse token failed", err.Error()) + } + if req.Token != config.Config.Secret { + return &pbGroup.GetGroupAllMemberResp{ErrorCode: config.ErrParseToken.ErrCode, ErrorMsg: config.ErrParseToken.ErrMsg}, nil + } + + var resp pbGroup.GetGroupAllMemberResp + resp.ErrorCode = 0 + memberList, err := imdb.FindGroupMemberListByGroupId(req.GroupID) + if err != nil { + resp.ErrorCode = config.ErrDb.ErrCode + resp.ErrorMsg = err.Error() + log.Error(claims.UID, req.OperationID, "FindGroupMemberListByGroupId failed, ", err.Error(), "params: ", req.GroupID) + return &resp, nil + } + + for _, v := range memberList { + var node pbGroup.GroupMemberFullInfo + node.Role = v.AdministratorLevel + node.NickName = v.NickName + node.UserId = v.Uid + node.JoinTime = uint64(v.JoinTime.Unix()) + resp.MemberList = append(resp.MemberList, &node) + } + + resp.ErrorCode = 0 + return &resp, nil +} + +func (s *groupServer) GetGroupMemberList(ctx context.Context, req *pbGroup.GetGroupMemberListReq) (*pbGroup.GetGroupMemberListResp, error) { + claims, err := utils.ParseToken(req.Token) + if err != nil { + log.Error(req.Token, req.OperationID, "err=%s,parse token failed", err.Error()) + return &pbGroup.GetGroupMemberListResp{ErrorCode: config.ErrParseToken.ErrCode, ErrorMsg: config.ErrParseToken.ErrMsg}, nil + } + // log.Info(claims.UID, req.OperationID, "recv req: ", req.String()) + fmt.Println("req: ", req.GroupID) + var resp pbGroup.GetGroupMemberListResp + resp.ErrorCode = 0 + memberList, err := imdb.GetGroupMemberByGroupId(req.GroupID, req.Filter, req.NextSeq, 30) + if err != nil { + resp.ErrorCode = config.ErrDb.ErrCode + resp.ErrorMsg = err.Error() + log.Error(claims.UID, req.OperationID, "GetGroupMemberByGroupId failed, ", err.Error(), "params: ", req.GroupID, req.Filter, req.NextSeq) + return &resp, nil + } + + for _, v := range memberList { + var node pbGroup.GroupMemberFullInfo + node.Role = v.AdministratorLevel + node.NickName = v.NickName + node.UserId = v.Uid + // node.FaceUrl = + node.JoinTime = uint64(v.JoinTime.Unix()) + resp.MemberList = append(resp.MemberList, &node) + } + //db operate get db sorted by join time + if int32(len(memberList)) < 30 { + resp.NextSeq = 0 + } else { + resp.NextSeq = req.NextSeq + int32(len(memberList)) + } + + resp.ErrorCode = 0 + return &resp, nil +} + +func (s *groupServer) KickGroupMember(ctx context.Context, req *pbGroup.KickGroupMemberReq) (*pbGroup.KickGroupMemberResp, error) { + claims, err := utils.ParseToken(req.Token) + if err != nil { + log.Error(req.Token, req.OperationID, "err=%s,parse token failed", err.Error()) + return &pbGroup.KickGroupMemberResp{ErrorCode: config.ErrParseToken.ErrCode, ErrorMsg: config.ErrParseToken.ErrMsg}, nil + } + log.Info(claims.UID, req.OperationID, "recv req: ", req.String()) + + ownerList, err := imdb.GetOwnerManagerByGroupId(req.GroupID) + if err != nil { + log.Error(claims.UID, req.OperationID, req.GroupID, "GetOwnerManagerByGroupId, ", err.Error()) + return &pbGroup.KickGroupMemberResp{ErrorCode: config.ErrParam.ErrCode, ErrorMsg: config.ErrParam.ErrMsg}, nil + } + //op is group owner? + var flag = 0 + for _, v := range ownerList { + if v.Uid == claims.UID { + flag = 1 + break + } + } + if flag != 1 { + log.Error(claims.UID, req.OperationID, "no access kick") + return &pbGroup.KickGroupMemberResp{ErrorCode: config.ErrAccess.ErrCode, ErrorMsg: config.ErrAccess.ErrMsg}, nil + } + + if len(req.UidList) == 0 { + log.Error(claims.UID, req.OperationID, "kick list 0") + return &pbGroup.KickGroupMemberResp{ErrorCode: config.ErrParam.ErrCode, ErrorMsg: config.ErrParam.ErrMsg}, nil + } + //remove + var resp pbGroup.KickGroupMemberResp + for _, v := range req.UidList { + //owner cant kicked + if v == claims.UID { + log.Error(claims.UID, req.OperationID, v, "cant kick owner") + resp.Id2Result = append(resp.Id2Result, &pbGroup.Id2Result{UId: v, Result: -1}) + continue + } + err := imdb.RemoveGroupMember(req.GroupID, v) + if err != nil { + log.Error(claims.UID, req.OperationID, v, req.GroupID, "RemoveGroupMember failed ", err.Error()) + resp.Id2Result = append(resp.Id2Result, &pbGroup.Id2Result{UId: v, Result: -1}) + } else { + resp.Id2Result = append(resp.Id2Result, &pbGroup.Id2Result{UId: v, Result: 0}) + } + } + + var chatMsg pbChat.WSToMsgSvrChatMsg + chatMsg.SendID = claims.UID + chatMsg.RecvID = req.GroupID + content, _ := json.Marshal(req) + chatMsg.Content = string(content) + chatMsg.SendTime = utils.GetCurrentTimestampBySecond() + chatMsg.MsgFrom = constant.UserMsgType + chatMsg.ContentType = constant.KickGroupMemberTip + chatMsg.SessionType = constant.GroupChatType + logic.SendMsgByWS(&chatMsg) + + for _, v := range req.UidList { + kickChatMsg := chatMsg + kickChatMsg.RecvID = v + kickChatMsg.SendTime = utils.GetCurrentTimestampBySecond() + kickChatMsg.SessionType = constant.SingleChatType + logic.SendMsgByWS(&kickChatMsg) + } + + resp.ErrorCode = 0 + return &resp, nil +} + +func (s *groupServer) GetGroupMembersInfo(ctx context.Context, req *pbGroup.GetGroupMembersInfoReq) (*pbGroup.GetGroupMembersInfoResp, error) { + claims, err := utils.ParseToken(req.Token) + if err != nil { + log.Error(req.Token, req.OperationID, "err=%s,parse token failed", err.Error()) + return &pbGroup.GetGroupMembersInfoResp{ErrorCode: config.ErrParseToken.ErrCode, ErrorMsg: config.ErrParseToken.ErrMsg}, nil + } + log.InfoByKv(claims.UID, req.OperationID, "param: ", req.MemberList) + var resp pbGroup.GetGroupMembersInfoResp + + for _, v := range req.MemberList { + var memberNode pbGroup.GroupMemberFullInfo + memberInfo, err := imdb.GetMemberInfoById(req.GroupID, v) + memberNode.UserId = v + fmt.Println("id : ", memberNode.UserId) + if err != nil { + log.Error(claims.UID, req.OperationID, req.GroupID, v, "GetMemberInfoById failed, ", err.Error()) + //error occurs, only id is valid + resp.MemberList = append(resp.MemberList, &memberNode) + continue + } + user, err := imdb.FindUserByUID(v) + if err == nil && user != nil { + memberNode.FaceUrl = user.Icon + memberNode.JoinTime = uint64(memberInfo.JoinTime.Unix()) + memberNode.UserId = user.UID + memberNode.NickName = memberInfo.NickName + memberNode.Role = memberInfo.AdministratorLevel + } + resp.MemberList = append(resp.MemberList, &memberNode) + } + resp.ErrorCode = 0 + return &resp, nil +} diff --git a/src/rpc/group/group/group_application_response.go b/src/rpc/group/group/group_application_response.go new file mode 100644 index 000000000..ceecd5ee3 --- /dev/null +++ b/src/rpc/group/group/group_application_response.go @@ -0,0 +1,90 @@ +package group + +import ( + "Open_IM/src/common/constant" + "Open_IM/src/common/db/mysql_model/im_mysql_model" + "Open_IM/src/common/log" + pbChat "Open_IM/src/proto/chat" + "Open_IM/src/proto/group" + "Open_IM/src/push/content_struct" + "Open_IM/src/push/logic" + "Open_IM/src/utils" + "context" + "encoding/json" +) + +func (s *groupServer) GroupApplicationResponse(_ context.Context, pb *group.GroupApplicationResponseReq) (*group.GroupApplicationResponseResp, error) { + log.Info("", "", "rpc GroupApplicationResponse call start..., [pb: %s]", pb.String()) + + reply, err := im_mysql_model.GroupApplicationResponse(pb) + if err != nil { + log.Error("", "", "rpc GroupApplicationResponse call..., im_mysql_model.GroupApplicationResponse fail [pb: %s] [err: %s]", pb.String(), err.Error()) + return nil, err + } + log.Info("", "", "rpc GroupApplicationResponse call..., im_mysql_model.GroupApplicationResponse") + + if pb.HandleResult == 1 { + logic.SendMsgByWS(&pbChat.WSToMsgSvrChatMsg{ + SendID: pb.OwnerID, + RecvID: pb.GroupID, + Content: pb.String(), + SendTime: utils.GetCurrentTimestampBySecond(), + MsgFrom: constant.SysMsgType, + ContentType: constant.AcceptGroupApplicationTip, + SessionType: constant.GroupChatType, + OperationID: pb.OperationID, + }) + } + + var recvID string + if pb.ToUserID == "0" { + recvID = pb.FromUserID + } else { + recvID = pb.ToUserID + } + + ownerUser, err := im_mysql_model.FindGroupMemberInfoByGroupIdAndUserId(pb.GroupID, pb.OwnerID) + if err != nil { + return nil, err + } + + agreeOrReject := content_struct.AgreeOrRejectGroupMember{ + GroupId: ownerUser.GroupId, + UserId: ownerUser.Uid, + Role: int(ownerUser.AdministratorLevel), + JoinTime: uint64(ownerUser.JoinTime.Unix()), + NickName: ownerUser.NickName, + FaceUrl: ownerUser.UserGroupFaceUrl, + Reason: pb.HandledMsg, + } + bAgreeOrReject, err := json.Marshal(agreeOrReject) + if err != nil { + return nil, err + } + + if pb.HandleResult == 1 { + logic.SendMsgByWS(&pbChat.WSToMsgSvrChatMsg{ + SendID: pb.OwnerID, + RecvID: recvID, + Content: string(bAgreeOrReject), + SendTime: utils.GetCurrentTimestampBySecond(), + MsgFrom: constant.SysMsgType, + ContentType: constant.AcceptGroupApplicationResultTip, + SessionType: constant.SingleChatType, + OperationID: pb.OperationID, + }) + } else { + logic.SendMsgByWS(&pbChat.WSToMsgSvrChatMsg{ + SendID: pb.OwnerID, + RecvID: recvID, + Content: string(bAgreeOrReject), + SendTime: utils.GetCurrentTimestampBySecond(), + MsgFrom: constant.SysMsgType, + ContentType: constant.RefuseGroupApplicationResultTip, + SessionType: constant.SingleChatType, + OperationID: pb.OperationID, + }) + } + + return reply, nil +} diff --git a/src/rpc/group/group/join_group.go b/src/rpc/group/group/join_group.go new file mode 100644 index 000000000..ca820d314 --- /dev/null +++ b/src/rpc/group/group/join_group.go @@ -0,0 +1,63 @@ +package group + +import ( + "Open_IM/src/common/config" + "Open_IM/src/common/constant" + "Open_IM/src/common/db/mysql_model/im_mysql_model" + "Open_IM/src/common/log" + pbChat "Open_IM/src/proto/chat" + pbGroup "Open_IM/src/proto/group" + "Open_IM/src/push/content_struct" + "Open_IM/src/push/logic" + "Open_IM/src/utils" + "context" +) + +func (s *groupServer) JoinGroup(ctx context.Context, req *pbGroup.JoinGroupReq) (*pbGroup.CommonResp, error) { + log.Info(req.Token, req.OperationID, "rpc join group is server,args=%s", req.String()) + //Parse token, to find current user information + claims, err := utils.ParseToken(req.Token) + if err != nil { + log.Error(req.Token, req.OperationID, "err=%s,parse token failed", err.Error()) + return &pbGroup.CommonResp{ErrorCode: config.ErrParseToken.ErrCode, ErrorMsg: config.ErrParseToken.ErrMsg}, nil + } + applicationUserInfo, err := im_mysql_model.FindUserByUID(claims.UID) + if err != nil { + log.Error(req.Token, req.OperationID, "No this user,err=%s", err.Error()) + return &pbGroup.CommonResp{ErrorCode: config.ErrSearchUserInfo.ErrCode, ErrorMsg: config.ErrSearchUserInfo.ErrMsg}, nil + } + //todo Actively apply or be invited, apply to join the group and keep a record + requestUserInfo, err := im_mysql_model.FindGroupRequestUserInfoByUidAndGroupID(req.GroupID, claims.UID) + if err == nil { + if requestUserInfo.Flag == constant.AgreeApplication { + return &pbGroup.CommonResp{ErrorCode: config.ErrJoinGroupApplication.ErrCode, ErrorMsg: config.ErrJoinGroupApplication.ErrMsg}, nil + } + if requestUserInfo.Flag == constant.Application { + err = im_mysql_model.DelGroupRequest(req.GroupID, claims.UID, "0") + } + } + if err = im_mysql_model.InsertIntoGroupRequest(req.GroupID, claims.UID, "0", req.Message, applicationUserInfo.Name, applicationUserInfo.Icon); err != nil { + log.Error(req.Token, req.OperationID, "Insert into group request failed,er=%s", err.Error()) + return &pbGroup.CommonResp{ErrorCode: config.ErrJoinGroupApplication.ErrCode, ErrorMsg: config.ErrJoinGroupApplication.ErrMsg}, nil + } + //Find the the group owner + groupCreatorInfo, err := im_mysql_model.FindGroupMemberListByGroupIdAndFilterInfo(req.GroupID, constant.GroupCreator) + if err != nil { + log.Error(req.Token, req.OperationID, "find group creator failed", err.Error()) + } else { + //Push message when join group chat + logic.SendMsgByWS(&pbChat.WSToMsgSvrChatMsg{ + SendID: claims.UID, + RecvID: groupCreatorInfo[0].Uid, + Content: content_struct.NewContentStructString(0, "", req.String()), + SendTime: utils.GetCurrentTimestampBySecond(), + MsgFrom: constant.SysMsgType, + ContentType: constant.JoinGroupTip, + SessionType: constant.SingleChatType, + OperationID: req.OperationID, + }) + } + + log.Info(req.Token, req.OperationID, "rpc join group success return") + return &pbGroup.CommonResp{}, nil +} diff --git a/src/rpc/group/group/quti_group.go b/src/rpc/group/group/quti_group.go new file mode 100644 index 000000000..dfc874a33 --- /dev/null +++ b/src/rpc/group/group/quti_group.go @@ -0,0 +1,50 @@ +package group + +import ( + "Open_IM/src/common/config" + "Open_IM/src/common/constant" + "Open_IM/src/common/db/mysql_model/im_mysql_model" + "Open_IM/src/common/log" + pbChat "Open_IM/src/proto/chat" + pbGroup "Open_IM/src/proto/group" + "Open_IM/src/push/logic" + "Open_IM/src/utils" + "context" + "encoding/json" +) + +func (s *groupServer) QuitGroup(ctx context.Context, req *pbGroup.QuitGroupReq) (*pbGroup.CommonResp, error) { + log.InfoByArgs("rpc quit group is server,args=%s", req.String()) + //Parse token, to find current user information + claims, err := utils.ParseToken(req.Token) + if err != nil { + log.Error(req.Token, req.OperationID, "err=%s,parse token failed", err.Error()) + return &pbGroup.CommonResp{ErrorCode: config.ErrParseToken.ErrCode, ErrorMsg: config.ErrParseToken.ErrMsg}, nil + } + //Check to see if there is a group and whether there is a user in the group. + _, err = im_mysql_model.FindGroupMemberInfoByGroupIdAndUserId(req.GroupID, claims.UID) + if err != nil { + log.Error(req.Token, req.OperationID, "no such group or you are not in the group,err=%s", err.Error()) + return &pbGroup.CommonResp{ErrorCode: config.ErrQuitGroup.ErrCode, ErrorMsg: config.ErrQuitGroup.ErrMsg}, nil + } + //After the user's verification is successful, user will quit the group chat. + err = im_mysql_model.DeleteGroupMemberByGroupIdAndUserId(req.GroupID, claims.UID) + if err != nil { + log.ErrorByArgs("this user exit the group failed,err=%s", err.Error()) + return &pbGroup.CommonResp{ErrorCode: config.ErrQuitGroup.ErrCode, ErrorMsg: config.ErrQuitGroup.ErrMsg}, nil + } + //Push message when quit group chat + jsonInfo, _ := json.Marshal(req) + logic.SendMsgByWS(&pbChat.WSToMsgSvrChatMsg{ + SendID: claims.UID, + RecvID: req.GroupID, + Content: string(jsonInfo), + SendTime: utils.GetCurrentTimestampBySecond(), + MsgFrom: constant.SysMsgType, + ContentType: constant.QuitGroupTip, + SessionType: constant.GroupChatType, + OperationID: req.OperationID, + }) + log.Info(req.Token, req.OperationID, "rpc quit group is success return") + return &pbGroup.CommonResp{}, nil +} diff --git a/src/rpc/group/group/set_group_info.go b/src/rpc/group/group/set_group_info.go new file mode 100644 index 000000000..c6c9ff165 --- /dev/null +++ b/src/rpc/group/group/set_group_info.go @@ -0,0 +1,50 @@ +package group + +import ( + "Open_IM/src/common/config" + "Open_IM/src/common/constant" + "Open_IM/src/common/db/mysql_model/im_mysql_model" + "Open_IM/src/common/log" + pbChat "Open_IM/src/proto/chat" + pbGroup "Open_IM/src/proto/group" + "Open_IM/src/push/logic" + "Open_IM/src/utils" + "context" + "encoding/json" +) + +func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbGroup.SetGroupInfoReq) (*pbGroup.CommonResp, error) { + log.Info(req.Token, req.OperationID, "rpc set group info is server,args=%s", req.String()) + + //Parse token, to find current user information + claims, err := utils.ParseToken(req.Token) + if err != nil { + log.Error(req.Token, req.OperationID, "err=%s,parse token failed", err.Error()) + return &pbGroup.CommonResp{ErrorCode: config.ErrParseToken.ErrCode, ErrorMsg: config.ErrParseToken.ErrMsg}, nil + } + groupUserInfo, err := im_mysql_model.FindGroupMemberInfoByGroupIdAndUserId(req.GroupID, claims.UID) + if err != nil { + log.Error("", req.OperationID, "your are not in the group,can not change this group info,err=%s", err.Error()) + return &pbGroup.CommonResp{ErrorCode: config.ErrSetGroupInfo.ErrCode, ErrorMsg: config.ErrSetGroupInfo.ErrMsg}, nil + } + if groupUserInfo.AdministratorLevel == constant.OrdinaryMember { + return &pbGroup.CommonResp{ErrorCode: config.ErrSetGroupInfo.ErrCode, ErrorMsg: config.ErrAccess.ErrMsg}, nil + } + //only administrators can set group information + if err = im_mysql_model.SetGroupInfo(req.GroupID, req.GroupName, req.Introduction, req.Notification, req.FaceUrl, ""); err != nil { + return &pbGroup.CommonResp{ErrorCode: config.ErrSetGroupInfo.ErrCode, ErrorMsg: config.ErrSetGroupInfo.ErrMsg}, nil + } + //Push message when set group info + jsonInfo, _ := json.Marshal(req) + logic.SendMsgByWS(&pbChat.WSToMsgSvrChatMsg{ + SendID: claims.UID, + RecvID: req.GroupID, + Content: string(jsonInfo), + SendTime: utils.GetCurrentTimestampBySecond(), + MsgFrom: constant.SysMsgType, + ContentType: constant.SetGroupInfoTip, + SessionType: constant.GroupChatType, + OperationID: req.OperationID, + }) + return &pbGroup.CommonResp{}, nil +} diff --git a/src/rpc/group/group/transfer_group_owner.go b/src/rpc/group/group/transfer_group_owner.go new file mode 100644 index 000000000..9e2c0fa82 --- /dev/null +++ b/src/rpc/group/group/transfer_group_owner.go @@ -0,0 +1,36 @@ +package group + +import ( + "Open_IM/src/common/constant" + "Open_IM/src/common/db/mysql_model/im_mysql_model" + "Open_IM/src/common/log" + pbChat "Open_IM/src/proto/chat" + "Open_IM/src/proto/group" + "Open_IM/src/push/logic" + "Open_IM/src/utils" + "context" +) + +func (s *groupServer) TransferGroupOwner(_ context.Context, pb *group.TransferGroupOwnerReq) (*group.TransferGroupOwnerResp, error) { + log.Info("", "", "rpc TransferGroupOwner call start..., [pb: %s]", pb.String()) + + reply, err := im_mysql_model.TransferGroupOwner(pb) + if err != nil { + log.Error("", "", "rpc TransferGroupOwner call..., im_mysql_model.TransferGroupOwner fail [pb: %s] [err: %s]", pb.String(), err.Error()) + return nil, err + } + log.Info("", "", "rpc TransferGroupOwner call..., im_mysql_model.TransferGroupOwner") + + logic.SendMsgByWS(&pbChat.WSToMsgSvrChatMsg{ + SendID: pb.OldOwner, + RecvID: pb.GroupID, + Content: pb.String(), + SendTime: utils.GetCurrentTimestampBySecond(), + MsgFrom: constant.UserMsgType, + ContentType: constant.TransferGroupOwnerTip, + SessionType: constant.GroupChatType, + OperationID: pb.OperationID, + }) + + return reply, nil +} diff --git a/src/rpc/group/open_im_group.go b/src/rpc/group/open_im_group.go new file mode 100644 index 000000000..e5f1df690 --- /dev/null +++ b/src/rpc/group/open_im_group.go @@ -0,0 +1,13 @@ +package main + +import ( + "Open_IM/src/rpc/group/group" + "flag" +) + +func main() { + rpcPort := flag.Int("port", 10500, "get RpcGroupPort from cmd,default 16000 as port") + flag.Parse() + rpcServer := group.NewGroupServer(*rpcPort) + rpcServer.Run() +}