diff --git a/cmd/open_im_api/docs/docs.go b/cmd/open_im_api/docs/docs.go index 5d7cff87e..8b711dfe1 100644 --- a/cmd/open_im_api/docs/docs.go +++ b/cmd/open_im_api/docs/docs.go @@ -1375,7 +1375,7 @@ const docTemplate = `{ "群组相关" ], "summary": "获取用户加入群列表", - "operationId": "GetJoinedGroupList", + "operationId": "FindJoinedGroup", "parameters": [ { "type": "string", diff --git a/cmd/open_im_api/main.go b/cmd/open_im_api/main.go index 6d50ecad8..42e3ba55a 100644 --- a/cmd/open_im_api/main.go +++ b/cmd/open_im_api/main.go @@ -118,7 +118,7 @@ func main() { groupRouterGroup.POST("/get_user_req_group_applicationList", group.GetUserReqGroupApplicationList) groupRouterGroup.POST("/get_groups_info", group.GetGroupsInfo) //1 groupRouterGroup.POST("/kick_group", group.KickGroupMember) //1 - // groupRouterGroup.POST("/get_group_member_list", group.GetGroupMemberList) //no use + // groupRouterGroup.POST("/get_group_member_list", group.FindGroupMemberAll) //no use groupRouterGroup.POST("/get_group_all_member_list", group.GetGroupAllMemberList) //1 groupRouterGroup.POST("/get_group_members_info", group.GetGroupMembersInfo) //1 groupRouterGroup.POST("/invite_user_to_group", group.InviteUserToGroup) //1 diff --git a/go.mod b/go.mod index 022546d7d..93a2c693c 100644 --- a/go.mod +++ b/go.mod @@ -17,16 +17,11 @@ require ( github.com/aws/aws-sdk-go-v2/credentials v1.12.9 github.com/aws/aws-sdk-go-v2/service/sts v1.16.9 github.com/bwmarrin/snowflake v0.3.0 - github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/dtm-labs/rockscache v0.0.11 github.com/fatih/structs v1.1.0 github.com/gin-gonic/gin v1.8.2 - github.com/go-openapi/spec v0.20.6 // indirect - github.com/go-openapi/swag v0.21.1 // indirect - github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/validator/v10 v10.11.1 github.com/go-redis/redis/v8 v8.11.5 - github.com/goccy/go-json v0.10.0 // indirect github.com/gogo/protobuf v1.3.2 github.com/golang-jwt/jwt/v4 v4.4.2 github.com/golang/protobuf v1.5.2 @@ -34,7 +29,6 @@ require ( github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/jinzhu/copier v0.3.5 github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible - github.com/mattn/go-isatty v0.0.17 // indirect github.com/minio/minio-go/v7 v7.0.22 github.com/mitchellh/mapstructure v1.4.2 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 @@ -51,26 +45,124 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.428 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.0.428 github.com/tencentyun/qcloud-cos-sts-sdk v0.0.0-20210325043845-84a0811633ca - github.com/ugorji/go/codec v1.2.8 // indirect go.etcd.io/etcd/client/v3 v3.5.6 go.mongodb.org/mongo-driver v1.8.3 - go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.9.0 // indirect - go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.5.0 // indirect golang.org/x/image v0.3.0 golang.org/x/net v0.5.0 + golang.org/x/tools v0.1.12 google.golang.org/api v0.103.0 - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect google.golang.org/grpc v1.52.0 google.golang.org/protobuf v1.28.1 - gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df - gopkg.in/ini.v1 v1.66.2 // indirect gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.3.5 gorm.io/gorm v1.23.8 ) +require ( + cloud.google.com/go v0.105.0 // indirect + cloud.google.com/go/compute v1.13.0 // indirect + cloud.google.com/go/compute/metadata v0.2.1 // indirect + cloud.google.com/go/firestore v1.9.0 // indirect + cloud.google.com/go/iam v0.8.0 // indirect + cloud.google.com/go/longrunning v0.3.0 // indirect + cloud.google.com/go/storage v1.27.0 // indirect + github.com/KyleBanks/depth v1.2.1 // indirect + github.com/OpenIMSDK/open_log v1.0.0 // indirect + github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // indirect + github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect + github.com/alibabacloud-go/openapi-util v0.0.9 // indirect + github.com/alibabacloud-go/tea-utils v1.3.9 // indirect + github.com/aliyun/credentials-go v1.1.2 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.8 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.14 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.8 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.3.15 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.8 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.11.12 // indirect + github.com/aws/smithy-go v1.12.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/eapache/go-resiliency v1.2.0 // indirect + github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect + github.com/eapache/queue v1.1.0 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.20.0 // indirect + github.com/go-openapi/spec v0.20.6 // indirect + github.com/go-openapi/swag v0.21.1 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/go-sql-driver/mysql v1.6.0 // indirect + github.com/go-stack/stack v1.8.0 // indirect + github.com/goccy/go-json v0.10.0 // indirect + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect + github.com/golang/snappy v0.0.3 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.7.0 // indirect + github.com/hashicorp/go-uuid v1.0.2 // indirect + github.com/jcmturner/aescts/v2 v2.0.0 // indirect + github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect + github.com/jcmturner/gofork v1.0.0 // indirect + github.com/jcmturner/gokrb5/v8 v8.4.2 // indirect + github.com/jcmturner/rpc/v2 v2.0.3 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.13.6 // indirect + github.com/klauspost/cpuid v1.3.1 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/lestrrat-go/strftime v1.0.6 // indirect + github.com/lithammer/shortuuid v3.0.0+incompatible // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/minio/md5-simd v1.1.0 // indirect + github.com/minio/sha256-simd v0.1.1 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect + github.com/pierrec/lz4 v2.6.0+incompatible // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/rs/xid v1.2.1 // indirect + github.com/tjfoc/gmsm v1.3.2 // indirect + github.com/ugorji/go/codec v1.2.8 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.0.2 // indirect + github.com/xdg-go/stringprep v1.0.2 // indirect + github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect + go.etcd.io/etcd/api/v3 v3.5.6 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.6 // indirect + go.opencensus.io v0.24.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/crypto v0.5.0 // indirect + golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.4.0 // indirect + golang.org/x/text v0.6.0 // indirect + golang.org/x/time v0.1.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect + gopkg.in/ini.v1 v1.66.2 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) + replace github.com/Shopify/sarama => github.com/Shopify/sarama v1.29.0 diff --git a/internal/api/group/group.go b/internal/api/group/group.go index 7e4dc357c..95b6803a0 100644 --- a/internal/api/group/group.go +++ b/internal/api/group/group.go @@ -72,7 +72,7 @@ func KickGroupMember(c *gin.Context) { client := rpc.NewGroupClient(etcdConn) RpcResp, err := client.KickGroupMember(context.Background(), req) if err != nil { - log.NewError(req.OperationID, "GetGroupMemberList failed ", err.Error(), req.String()) + log.NewError(req.OperationID, "FindGroupMemberAll failed ", err.Error(), req.String()) c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": err.Error()}) return } @@ -136,7 +136,7 @@ func GetGroupMembersInfo(c *gin.Context) { RpcResp, err := client.GetGroupMembersInfo(context.Background(), req) if err != nil { - log.NewError(req.OperationID, "GetGroupMemberList failed ", err.Error(), req.String()) + log.NewError(req.OperationID, "FindGroupMemberAll failed ", err.Error(), req.String()) c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": err.Error()}) return } @@ -167,7 +167,7 @@ func GetGroupMemberList(c *gin.Context) { return } - log.NewInfo(req.OperationID, "GetGroupMemberList args ", req.String()) + log.NewInfo(req.OperationID, "FindGroupMemberAll args ", req.String()) etcdConn := getcdv3.GetDefaultConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImGroupName, req.OperationID) if etcdConn == nil { @@ -180,7 +180,7 @@ func GetGroupMemberList(c *gin.Context) { RpcResp, err := client.GetGroupMemberList(context.Background(), req) if err != nil { - log.NewError(req.OperationID, "GetGroupMemberList failed, ", err.Error(), req.String()) + log.NewError(req.OperationID, "FindGroupMemberAll failed, ", err.Error(), req.String()) c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": err.Error()}) return } @@ -188,7 +188,7 @@ func GetGroupMemberList(c *gin.Context) { memberListResp := api.GetGroupMemberListResp{CommResp: api.CommResp{ErrCode: RpcResp.CommonResp.ErrCode, ErrMsg: RpcResp.CommonResp.ErrMsg}, MemberList: RpcResp.MemberList, NextSeq: RpcResp.NextSeq} memberListResp.Data = jsonData.JsonDataList(memberListResp.MemberList) - log.NewInfo(req.OperationID, "GetGroupMemberList api return ", memberListResp) + log.NewInfo(req.OperationID, "FindGroupMemberAll api return ", memberListResp) c.JSON(http.StatusOK, memberListResp) } @@ -280,7 +280,7 @@ func GetJoinedGroupList(c *gin.Context) { return } - log.NewInfo(req.OperationID, "GetJoinedGroupList args ", req.String()) + log.NewInfo(req.OperationID, "FindJoinedGroup args ", req.String()) etcdConn := getcdv3.GetDefaultConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImGroupName, req.OperationID) if etcdConn == nil { @@ -292,14 +292,14 @@ func GetJoinedGroupList(c *gin.Context) { client := rpc.NewGroupClient(etcdConn) RpcResp, err := client.GetJoinedGroupList(context.Background(), req) if err != nil { - log.NewError(req.OperationID, "GetJoinedGroupList failed ", err.Error(), req.String()) + log.NewError(req.OperationID, "FindJoinedGroup failed ", err.Error(), req.String()) c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": err.Error()}) return } GroupListResp := api.GetJoinedGroupListResp{CommResp: api.CommResp{ErrCode: RpcResp.CommonResp.ErrCode, ErrMsg: RpcResp.CommonResp.ErrMsg}, GroupInfoList: RpcResp.GroupList} GroupListResp.Data = jsonData.JsonDataList(GroupListResp.GroupInfoList) - log.NewInfo(req.OperationID, "GetJoinedGroupList api return ", GroupListResp) + log.NewInfo(req.OperationID, "FindJoinedGroup api return ", GroupListResp) c.JSON(http.StatusOK, GroupListResp) } diff --git a/internal/common/check/group.go b/internal/common/check/group.go new file mode 100644 index 000000000..56df95e76 --- /dev/null +++ b/internal/common/check/group.go @@ -0,0 +1,17 @@ +package check + +import ( + server_api_params "Open_IM/pkg/proto/sdk_ws" + "errors" +) + +type GroupChecker struct { +} + +func NewGroupChecker() *GroupChecker { + return &GroupChecker{} +} + +func (g *GroupChecker) GetGroupInfo(groupID string) (*server_api_params.GroupInfo, error) { + return nil, errors.New("TODO:GetUserInfo") +} diff --git a/internal/rpc/admin_cms/admin_cms.go b/internal/rpc/admin_cms/admin_cms.go index 28b641a34..fe82e7b2d 100644 --- a/internal/rpc/admin_cms/admin_cms.go +++ b/internal/rpc/admin_cms/admin_cms.go @@ -207,7 +207,7 @@ func (s *adminCMSServer) GetChatLogs(ctx context.Context, req *pbAdminCMS.GetCha pbChatLog.SenderNickname = recvUser.Nickname case constant.GroupChatType, constant.SuperGroupChatType: - group, err := s.groupInterface.TakeGroupByID(ctx, chatLog.RecvID) + group, err := s.groupInterface.TakeGroup(ctx, chatLog.RecvID) if err != nil { return nil, err } diff --git a/internal/rpc/conversation/conversaion.go b/internal/rpc/conversation/conversaion.go index e9b16387b..bacba5202 100644 --- a/internal/rpc/conversation/conversaion.go +++ b/internal/rpc/conversation/conversaion.go @@ -1,17 +1,22 @@ package conversation import ( + "Open_IM/internal/common/check" chat "Open_IM/internal/rpc/msg" "Open_IM/pkg/common/constant" - "Open_IM/pkg/common/db" - imdb "Open_IM/pkg/common/db/mysql_model/im_mysql_model" - rocksCache "Open_IM/pkg/common/db/rocks_cache" + "Open_IM/pkg/common/db/cache" + "Open_IM/pkg/common/db/controller" + "Open_IM/pkg/common/db/relation" + "Open_IM/pkg/common/db/table" + "Open_IM/pkg/common/db/unrelation" "Open_IM/pkg/common/log" promePkg "Open_IM/pkg/common/prometheus" "Open_IM/pkg/getcdv3" pbConversation "Open_IM/pkg/proto/conversation" + pbUser "Open_IM/pkg/proto/user" "Open_IM/pkg/utils" "context" + "github.com/dtm-labs/rockscache" "net" "strconv" "strings" @@ -23,156 +28,55 @@ import ( "google.golang.org/grpc" ) -type rpcConversation struct { +type conversationServer struct { rpcPort int rpcRegisterName string etcdSchema string etcdAddr []string + groupChecker *check.GroupChecker + controller.ConversationInterface } -func (rpc *rpcConversation) ModifyConversationField(c context.Context, req *pbConversation.ModifyConversationFieldReq) (*pbConversation.ModifyConversationFieldResp, error) { - log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String()) - resp := &pbConversation.ModifyConversationFieldResp{} - var err error - isSyncConversation := true - if req.Conversation.ConversationType == constant.GroupChatType { - groupInfo, err := imdb.GetGroupInfoByGroupID(req.Conversation.GroupID) - if err != nil { - log.NewError(req.OperationID, "GetGroupInfoByGroupID failed ", req.Conversation.GroupID, err.Error()) - resp.CommonResp = &pbConversation.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg} - return resp, nil - } - if groupInfo.Status == constant.GroupStatusDismissed && !req.Conversation.IsNotInGroup && req.FieldType != constant.FieldUnread { - errMsg := "group status is dismissed" - resp.CommonResp = &pbConversation.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: errMsg} - return resp, nil - } - } - var conversation imdb.Conversation - if err := utils.CopyStructFields(&conversation, req.Conversation); err != nil { - log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "CopyStructFields failed", *req.Conversation, err.Error()) - } - haveUserID, _ := imdb.GetExistConversationUserIDList(req.UserIDList, req.Conversation.ConversationID) - switch req.FieldType { - case constant.FieldRecvMsgOpt: - for _, v := range req.UserIDList { - if err = db.DB.SetSingleConversationRecvMsgOpt(v, req.Conversation.ConversationID, req.Conversation.RecvMsgOpt); err != nil { - log.NewError(req.OperationID, utils.GetSelfFuncName(), "cache failed, rpc return", err.Error()) - resp.CommonResp = &pbConversation.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg} - return resp, nil - } - } - err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"recv_msg_opt": conversation.RecvMsgOpt}) - case constant.FieldGroupAtType: - err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"group_at_type": conversation.GroupAtType}) - case constant.FieldIsNotInGroup: - err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"is_not_in_group": conversation.IsNotInGroup}) - case constant.FieldIsPinned: - err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"is_pinned": conversation.IsPinned}) - case constant.FieldIsPrivateChat: - err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"is_private_chat": conversation.IsPrivateChat}) - case constant.FieldEx: - err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"ex": conversation.Ex}) - case constant.FieldAttachedInfo: - err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"attached_info": conversation.AttachedInfo}) - case constant.FieldUnread: - isSyncConversation = false - err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"update_unread_count_time": conversation.UpdateUnreadCountTime}) - case constant.FieldBurnDuration: - err = imdb.UpdateColumnsConversations(haveUserID, req.Conversation.ConversationID, map[string]interface{}{"burn_duration": conversation.BurnDuration}) - } - if err != nil { - log.NewError(req.OperationID, utils.GetSelfFuncName(), "UpdateColumnsConversations error", err.Error()) - resp.CommonResp = &pbConversation.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg} - return resp, nil - } - for _, v := range utils.DifferenceString(haveUserID, req.UserIDList) { - conversation.OwnerUserID = v - err = rocksCache.DelUserConversationIDListFromCache(v) - if err != nil { - log.NewError(req.OperationID, utils.GetSelfFuncName(), v, req.Conversation.ConversationID, err.Error()) - } - err := imdb.SetOneConversation(conversation) - if err != nil { - log.NewError(req.OperationID, utils.GetSelfFuncName(), "SetConversation error", err.Error()) - resp.CommonResp = &pbConversation.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg} - return resp, nil - } - } - - // notification - if req.Conversation.ConversationType == constant.SingleChatType && req.FieldType == constant.FieldIsPrivateChat { - //sync peer user conversation if conversation is singleChatType - if err := syncPeerUserConversation(req.Conversation, req.OperationID); err != nil { - log.NewError(req.OperationID, utils.GetSelfFuncName(), "syncPeerUserConversation", err.Error()) - resp.CommonResp = &pbConversation.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg} - return resp, nil - } - - } else { - if isSyncConversation { - for _, v := range req.UserIDList { - if err = rocksCache.DelConversationFromCache(v, req.Conversation.ConversationID); err != nil { - log.NewError(req.OperationID, utils.GetSelfFuncName(), v, req.Conversation.ConversationID, err.Error()) - } - chat.ConversationChangeNotification(req.OperationID, v) - } - } else { - for _, v := range req.UserIDList { - if err = rocksCache.DelConversationFromCache(v, req.Conversation.ConversationID); err != nil { - log.NewError(req.OperationID, utils.GetSelfFuncName(), v, req.Conversation.ConversationID, err.Error()) - } - chat.ConversationUnreadChangeNotification(req.OperationID, v, req.Conversation.ConversationID, conversation.UpdateUnreadCountTime) - } - } - - } - log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "rpc return", resp.String()) - resp.CommonResp = &pbConversation.CommonResp{} - return resp, nil -} -func syncPeerUserConversation(conversation *pbConversation.Conversation, operationID string) error { - peerUserConversation := imdb.Conversation{ - OwnerUserID: conversation.UserID, - ConversationID: utils.GetConversationIDBySessionType(conversation.OwnerUserID, constant.SingleChatType), - ConversationType: constant.SingleChatType, - UserID: conversation.OwnerUserID, - GroupID: "", - RecvMsgOpt: 0, - UnreadCount: 0, - DraftTextTime: 0, - IsPinned: false, - IsPrivateChat: conversation.IsPrivateChat, - AttachedInfo: "", - Ex: "", - } - err := imdb.PeerUserSetConversation(peerUserConversation) - if err != nil { - log.NewError(operationID, utils.GetSelfFuncName(), "SetConversation error", err.Error()) - return err - } - err = rocksCache.DelConversationFromCache(conversation.UserID, utils.GetConversationIDBySessionType(conversation.OwnerUserID, constant.SingleChatType)) - if err != nil { - log.NewError(operationID, utils.GetSelfFuncName(), "DelConversationFromCache failed", err.Error(), conversation.OwnerUserID, conversation.ConversationID) - } - err = rocksCache.DelConversationFromCache(conversation.OwnerUserID, conversation.ConversationID) - if err != nil { - log.NewError(operationID, utils.GetSelfFuncName(), "DelConversationFromCache failed", err.Error(), conversation.OwnerUserID, conversation.ConversationID) - } - chat.ConversationSetPrivateNotification(operationID, conversation.OwnerUserID, conversation.UserID, conversation.IsPrivateChat) - return nil -} -func NewRpcConversationServer(port int) *rpcConversation { +func NewConversationServer(port int) *conversationServer { log.NewPrivateLog(constant.LogFileName) - return &rpcConversation{ + c := conversationServer{ rpcPort: port, rpcRegisterName: config.Config.RpcRegisterName.OpenImConversationName, etcdSchema: config.Config.Etcd.EtcdSchema, etcdAddr: config.Config.Etcd.EtcdAddr, + groupChecker: check.NewGroupChecker(), } + var cDB relation.Conversation + var cCache cache.ConversationCache + //mysql init + var mysql relation.Mysql + err := mysql.InitConn().AutoMigrateModel(&table.ConversationModel{}) + if err != nil { + panic("db init err:" + err.Error()) + } + if mysql.GormConn() != nil { + //get gorm model + cDB = relation.NewConversationGorm(mysql.GormConn()) + } else { + panic("db init err:" + "conn is nil") + } + //redis init + var redis cache.RedisClient + redis.InitRedis() + rcClient := rockscache.NewClient(redis.GetClient(), rockscache.Options{ + RandomExpireAdjustment: 0.2, + DisableCacheRead: false, + DisableCacheDelete: false, + StrongConsistency: true, + }) + cCache = cache.NewConversationRedis(rcClient) + + database := controller.NewConversationDataBase(cDB, cCache) + c.ConversationInterface = controller.NewConversationController(database) + return &c } -func (rpc *rpcConversation) Run() { +func (c *conversationServer) Run() { log.NewInfo("0", "rpc conversation start...") listenIP := "" @@ -181,11 +85,11 @@ func (rpc *rpcConversation) Run() { } else { listenIP = config.Config.ListenIP } - address := listenIP + ":" + strconv.Itoa(rpc.rpcPort) + address := listenIP + ":" + strconv.Itoa(c.rpcPort) listener, err := net.Listen("tcp", address) if err != nil { - panic("listening err:" + err.Error() + rpc.rpcRegisterName) + panic("listening err:" + err.Error() + c.rpcRegisterName) } log.NewInfo("0", "listen network success, ", address, listener) //grpc server @@ -204,7 +108,7 @@ func (rpc *rpcConversation) Run() { defer srv.GracefulStop() //service registers with etcd - pbConversation.RegisterConversationServer(srv, rpc) + pbConversation.RegisterConversationServer(srv, c) rpcRegisterIP := config.Config.RpcRegisterIP if config.Config.RpcRegisterIP == "" { rpcRegisterIP, err = utils.GetLocalIP() @@ -213,13 +117,13 @@ func (rpc *rpcConversation) Run() { } } log.NewInfo("", "rpcRegisterIP", rpcRegisterIP) - err = getcdv3.RegisterEtcd(rpc.etcdSchema, strings.Join(rpc.etcdAddr, ","), rpcRegisterIP, rpc.rpcPort, rpc.rpcRegisterName, 10) + err = getcdv3.RegisterEtcd(c.etcdSchema, strings.Join(c.etcdAddr, ","), rpcRegisterIP, c.rpcPort, c.rpcRegisterName, 10, "") if err != nil { log.NewError("0", "RegisterEtcd failed ", err.Error(), - rpc.etcdSchema, strings.Join(rpc.etcdAddr, ","), rpcRegisterIP, rpc.rpcPort, rpc.rpcRegisterName) + c.etcdSchema, strings.Join(c.etcdAddr, ","), rpcRegisterIP, c.rpcPort, c.rpcRegisterName) panic(utils.Wrap(err, "register conversation module rpc to etcd err")) } - log.NewInfo("0", "RegisterConversationServer ok ", rpc.etcdSchema, strings.Join(rpc.etcdAddr, ","), rpcRegisterIP, rpc.rpcPort, rpc.rpcRegisterName) + log.NewInfo("0", "RegisterConversationServer ok ", c.etcdSchema, strings.Join(c.etcdAddr, ","), rpcRegisterIP, c.rpcPort, c.rpcRegisterName) err = srv.Serve(listener) if err != nil { log.NewError("0", "Serve failed ", err.Error()) @@ -227,3 +131,141 @@ func (rpc *rpcConversation) Run() { } log.NewInfo("0", "rpc conversation ok") } + +func (c *conversationServer) GetConversation(ctx context.Context, req *pbConversation.GetConversationReq) (*pbConversation.GetConversationResp, error) { + resp := &pbConversation.GetConversationResp{Conversation: &pbConversation.Conversation{}} + conversations, err := c.ConversationInterface.FindConversations(ctx, req.OwnerUserID, []string{req.ConversationID}) + if err != nil { + return nil, err + } + if len(conversations) > 0 { + if err := utils.CopyStructFields(resp.Conversation, &conversations[0]); err != nil { + return nil, err + } + return resp, nil + } + return nil, nil +} + +func (c *conversationServer) GetAllConversations(ctx context.Context, req *pbConversation.GetAllConversationsReq) (*pbConversation.GetAllConversationsResp, error) { + resp := &pbConversation.GetAllConversationsResp{Conversations: []*pbConversation.Conversation{}} + conversations, err := c.ConversationInterface.GetUserAllConversation(ctx, req.OwnerUserID) + if err != nil { + return nil, err + } + if err := utils.CopyStructFields(&resp.Conversations, conversations); err != nil { + return nil, err + } + return resp, nil +} + +func (c *conversationServer) GetConversations(ctx context.Context, req *pbConversation.GetConversationsReq) (*pbConversation.GetConversationsResp, error) { + resp := &pbConversation.GetConversationsResp{Conversations: []*pbConversation.Conversation{}} + conversations, err := c.ConversationInterface.FindConversations(ctx, req.OwnerUserID, req.ConversationIDs) + if err != nil { + return nil, err + } + if err := utils.CopyStructFields(&resp.Conversations, conversations); err != nil { + return nil, err + } + return resp, nil +} + +func (c *conversationServer) BatchSetConversations(ctx context.Context, req *pbConversation.BatchSetConversationsReq) (*pbConversation.BatchSetConversationsResp, error) { + resp := &pbConversation.BatchSetConversationsResp{} + var conversations []*table.ConversationModel + if err := utils.CopyStructFields(&conversations, req.Conversations); err != nil { + return nil, err + } + err := c.ConversationInterface.SetUserConversations(ctx, req.OwnerUserID, conversations) + if err != nil { + return nil, err + } + chat.ConversationChangeNotification(ctx, req.OwnerUserID) + return resp, nil +} + +func (c *conversationServer) SetConversation(ctx context.Context, req *pbConversation.SetConversationReq) (*pbConversation.SetConversationResp, error) { + panic("implement me") +} + +func (c *conversationServer) SetRecvMsgOpt(ctx context.Context, req *pbConversation.SetRecvMsgOptReq) (*pbConversation.SetRecvMsgOptResp, error) { + panic("implement me") +} + +func (c *conversationServer) ModifyConversationField(ctx context.Context, req *pbConversation.ModifyConversationFieldReq) (*pbConversation.ModifyConversationFieldResp, error) { + resp := &pbConversation.ModifyConversationFieldResp{} + var err error + isSyncConversation := true + if req.Conversation.ConversationType == constant.GroupChatType { + groupInfo, err := c.groupChecker.GetGroupInfo(req.Conversation.GroupID) + if err != nil { + return nil, err + } + if groupInfo.Status == constant.GroupStatusDismissed && req.FieldType != constant.FieldUnread { + return nil, err + } + } + var conversation table.ConversationModel + if err := utils.CopyStructFields(&conversation, req.Conversation); err != nil { + return nil, err + } + if req.FieldType == constant.FieldIsPrivateChat { + err := c.ConversationInterface.SyncPeerUserPrivateConversationTx(ctx, req.Conversation) + if err != nil { + return nil, err + } + chat.ConversationSetPrivateNotification(req.OperationID, req.Conversation.OwnerUserID, req.Conversation.UserID, req.Conversation.IsPrivateChat) + return resp, nil + } + //haveUserID, err := c.ConversationInterface.GetUserIDExistConversation(ctx, req.UserIDList, req.Conversation.ConversationID) + //if err != nil { + // return nil, err + //} + filedMap := make(map[string]interface{}) + switch req.FieldType { + case constant.FieldRecvMsgOpt: + filedMap["recv_msg_opt"] = req.Conversation.RecvMsgOpt + case constant.FieldGroupAtType: + filedMap["group_at_type"] = req.Conversation.GroupAtType + case constant.FieldIsNotInGroup: + filedMap["is_not_in_group"] = req.Conversation.IsNotInGroup + case constant.FieldIsPinned: + filedMap["is_pinned"] = req.Conversation.IsPinned + case constant.FieldEx: + filedMap["ex"] = req.Conversation.Ex + case constant.FieldAttachedInfo: + filedMap["attached_info"] = req.Conversation.AttachedInfo + case constant.FieldUnread: + isSyncConversation = false + filedMap["update_unread_count_time"] = req.Conversation.UpdateUnreadCountTime + case constant.FieldBurnDuration: + filedMap["burn_duration"] = req.Conversation.BurnDuration + } + c.ConversationInterface.SetUsersConversationFiledTx(ctx, req.UserIDList, &conversation, filedMap) + err = c.ConversationInterface.UpdateUsersConversationFiled(ctx, haveUserID, req.Conversation.ConversationID, filedMap) + if err != nil { + return nil, err + } + var conversations []*pbConversation.Conversation + for _, v := range utils.DifferenceString(haveUserID, req.UserIDList) { + temp := new(pbConversation.Conversation) + _ = utils.CopyStructFields(temp, req.Conversation) + temp.OwnerUserID = v + conversations = append(conversations, temp) + } + err = c.ConversationInterface.CreateConversation(ctx, conversations) + if err != nil { + return nil, err + } + if isSyncConversation { + for _, v := range req.UserIDList { + chat.ConversationChangeNotification(req.OperationID, v) + } + } else { + for _, v := range req.UserIDList { + chat.ConversationUnreadChangeNotification(req.OperationID, v, req.Conversation.ConversationID, req.Conversation.UpdateUnreadCountTime) + } + } + return resp, nil +} 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 654521e1a..ba24f9109 100644 --- a/internal/rpc/group/copy.go +++ b/internal/rpc/group/copy.go @@ -1 +1,119 @@ 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 DbToPbGroupInfo(m *relation.GroupModel, ownerUserID string, memberCount uint32) *open_im_sdk.GroupInfo { + return &open_im_sdk.GroupInfo{ + GroupID: m.GroupID, + GroupName: m.GroupName, + Notification: m.Notification, + Introduction: m.Introduction, + FaceURL: m.FaceURL, + OwnerUserID: ownerUserID, + CreateTime: m.CreateTime.UnixMilli(), + MemberCount: memberCount, + Ex: m.Ex, + Status: m.Status, + CreatorUserID: m.CreatorUserID, + GroupType: m.GroupType, + NeedVerification: m.NeedVerification, + LookMemberInfo: m.LookMemberInfo, + ApplyMemberFriend: m.ApplyMemberFriend, + NotificationUpdateTime: m.NotificationUpdateTime.UnixMilli(), + 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(), + } +} + +func DbToPbCMSGroup(m *relation.GroupModel, ownerUserID string, ownerUserName string, memberCount uint32) *pbGroup.CMSGroup { + return &pbGroup.CMSGroup{ + GroupInfo: DbToPbGroupInfo(m, ownerUserID, memberCount), + GroupOwnerUserID: ownerUserID, + GroupOwnerUserName: ownerUserName, + } +} + +func DbToPbGroupMembersCMSResp(m *relation.GroupMemberModel) *open_im_sdk.GroupMemberFullInfo { + return &open_im_sdk.GroupMemberFullInfo{ + GroupID: m.GroupID, + UserID: m.UserID, + RoleLevel: m.RoleLevel, + JoinTime: m.JoinTime.UnixMilli(), + Nickname: m.Nickname, + FaceURL: m.FaceURL, + //AppMangerLevel: m.AppMangerLevel, + JoinSource: m.JoinSource, + OperatorUserID: m.OperatorUserID, + Ex: m.Ex, + MuteEndTime: m.MuteEndTime.UnixMilli(), + InviterUserID: m.InviterUserID, + } +} + +func DbToPbGroupRequest(m *relation.GroupRequestModel, user *open_im_sdk.PublicUserInfo, group *open_im_sdk.GroupInfo) *open_im_sdk.GroupRequest { + return &open_im_sdk.GroupRequest{ + UserInfo: user, + GroupInfo: group, + HandleResult: m.HandleResult, + ReqMsg: m.ReqMsg, + HandleMsg: m.HandledMsg, + ReqTime: m.ReqTime.UnixMilli(), + HandleUserID: m.HandleUserID, + HandleTime: m.HandledTime.UnixMilli(), + Ex: m.Ex, + JoinSource: m.JoinSource, + InviterUserID: m.InviterUserID, + } +} + +func DbToPbGroupAbstractInfo(groupID string, groupMemberNumber int32, groupMemberListHash uint64) *pbGroup.GroupAbstractInfo { + return &pbGroup.GroupAbstractInfo{ + GroupID: groupID, + GroupMemberNumber: groupMemberNumber, + GroupMemberListHash: groupMemberListHash, + } +} + +func PbToDBGroupInfo(m *open_im_sdk.GroupInfo) *relation.GroupModel { + return &relation.GroupModel{ + GroupID: m.GroupID, + GroupName: m.GroupName, + Notification: m.Notification, + Introduction: m.Introduction, + FaceURL: m.FaceURL, + CreateTime: time.Now(), + Ex: m.Ex, + Status: m.Status, + CreatorUserID: m.CreatorUserID, + GroupType: m.GroupType, + NeedVerification: m.NeedVerification, + LookMemberInfo: m.LookMemberInfo, + ApplyMemberFriend: m.ApplyMemberFriend, + NotificationUpdateTime: time.UnixMilli(m.NotificationUpdateTime), + NotificationUserID: m.NotificationUserID, + } +} + +func PbToDbGroupMember(m *open_im_sdk.UserInfo) *relation.GroupMemberModel { + return &relation.GroupMemberModel{ + UserID: m.UserID, + Nickname: m.Nickname, + FaceURL: m.FaceURL, + Ex: m.Ex, + } +} diff --git a/internal/rpc/group/db_map.go b/internal/rpc/group/db_map.go new file mode 100644 index 000000000..ebdf9a8f0 --- /dev/null +++ b/internal/rpc/group/db_map.go @@ -0,0 +1,62 @@ +package group + +import ( + pbGroup "Open_IM/pkg/proto/group" + open_im_sdk "Open_IM/pkg/proto/sdk_ws" + "time" +) + +func UpdateGroupInfoMap(group *open_im_sdk.GroupInfoForSet) map[string]any { + m := make(map[string]any) + if group.GroupName != "" { + m["group_name"] = group.GroupName + } + if group.Notification != "" { + m["notification"] = group.Notification + } + if group.Introduction != "" { + m["introduction"] = group.Introduction + } + if group.FaceURL != "" { + m["face_url"] = group.FaceURL + } + if group.NeedVerification != nil { + m["need_verification"] = group.NeedVerification.Value + } + if group.LookMemberInfo != nil { + m["look_member_info"] = group.LookMemberInfo.Value + } + if group.ApplyMemberFriend != nil { + m["apply_member_friend"] = group.ApplyMemberFriend.Value + } + return m +} + +func UpdateGroupStatusMap(status int) map[string]any { + return map[string]any{ + "status": status, + } +} + +func UpdateGroupMemberMutedTimeMap(t time.Time) map[string]any { + return map[string]any{ + "mute_end_time": t, + } +} + +func UpdateGroupMemberMap(req *pbGroup.SetGroupMemberInfoReq) map[string]any { + m := make(map[string]any) + if req.Nickname != nil { + m["nickname"] = req.Nickname.Value + } + if req.FaceURL != nil { + m["face_url"] = req.FaceURL.Value + } + if req.RoleLevel != nil { + m["role_level"] = req.RoleLevel.Value + } + if req.Ex != nil { + m["ex"] = req.Ex.Value + } + return m +} diff --git a/internal/rpc/group/g.go b/internal/rpc/group/g.go index f5e4b4d54..48e5b03ab 100644 --- a/internal/rpc/group/g.go +++ b/internal/rpc/group/g.go @@ -1,56 +1,66 @@ package group import ( + "Open_IM/pkg/common/constant" "Open_IM/pkg/common/tracelog" + pbConversation "Open_IM/pkg/proto/conversation" 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{} -// -// member := relation.GroupMember{} -// member.GroupID = groupID -// member.UserID = userID -// member.RoleLevel = constant.GroupOrdinaryUsers -// member.OperatorUserID = utils.OpUserID(ctx) -// -// member.FaceURL = user.FaceURL -// member.Nickname = user.Nickname -// member.JoinSource = request.JoinSource -// member.InviterUserID = request.InviterUserID -// member.MuteEndTime = time.Unix(int64(time.Now().Second()), 0) -// -// return dbGroupMember, nil -//} - -func getUsersInfo(ctx context.Context, userIDs []string) ([]*sdk_ws.UserInfo, error) { - return nil, nil +func GetPublicUserInfoOne(ctx context.Context, userID string) (*sdk_ws.PublicUserInfo, error) { + return nil, errors.New("todo") } -func getUserMap(ctx context.Context, userIDs []string) (map[string]*sdk_ws.UserInfo, error) { - users, err := getUsersInfo(ctx, userIDs) +func GetUsersInfo(ctx context.Context, userIDs []string) ([]*sdk_ws.UserInfo, error) { + return nil, errors.New("todo") +} + +func GetUserInfoMap(ctx context.Context, userIDs []string) (map[string]*sdk_ws.UserInfo, error) { + users, err := GetUsersInfo(ctx, userIDs) if err != nil { return nil, err } - userMap := make(map[string]*sdk_ws.UserInfo) - for i, user := range users { - userMap[user.UserID] = users[i] + return utils.SliceToMap(users, func(e *sdk_ws.UserInfo) string { + return e.UserID + }), nil +} + +func GetPublicUserInfo(ctx context.Context, userIDs []string) ([]*sdk_ws.PublicUserInfo, error) { + return nil, errors.New("todo") +} + +func GetPublicUserInfoMap(ctx context.Context, userIDs []string) (map[string]*sdk_ws.PublicUserInfo, error) { + users, err := GetPublicUserInfo(ctx, userIDs) + if err != nil { + return nil, err } - return userMap, nil + return utils.SliceToMap(users, func(e *sdk_ws.PublicUserInfo) string { + return e.UserID + }), 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 { diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 2175aee04..8f5753ff3 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" @@ -15,16 +14,12 @@ import ( promePkg "Open_IM/pkg/common/prometheus" "Open_IM/pkg/common/token_verify" "Open_IM/pkg/common/tracelog" - "fmt" - "github.com/OpenIMSDK/getcdv3" - - pbConversation "Open_IM/pkg/proto/conversation" pbGroup "Open_IM/pkg/proto/group" open_im_sdk "Open_IM/pkg/proto/sdk_ws" - pbUser "Open_IM/pkg/proto/user" "Open_IM/pkg/utils" "context" - "errors" + "fmt" + "github.com/OpenIMSDK/getcdv3" grpcPrometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "net" "strconv" @@ -33,7 +28,6 @@ import ( "google.golang.org/grpc" "google.golang.org/protobuf/types/known/wrapperspb" - "gorm.io/gorm" ) type groupServer struct { @@ -157,6 +151,19 @@ func (s *groupServer) Run() { log.NewInfo("", "group rpc success") } +func (s *groupServer) CheckGroupAdmin(ctx context.Context, groupID string) error { + if !token_verify.IsAppManagerUid(ctx) { + groupMember, err := s.GroupInterface.TakeGroupMember(ctx, groupID, tracelog.GetOpUserID(ctx)) + if err != nil { + return err + } + if !(groupMember.RoleLevel == constant.GroupOwner || groupMember.RoleLevel == constant.GroupAdmin) { + return constant.ErrNoPermission.Wrap("no group owner or admin") + } + } + return nil +} + func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupReq) (*pbGroup.CreateGroupResp, error) { resp := &pbGroup.CreateGroupResp{GroupInfo: &open_im_sdk.GroupInfo{}} if err := token_verify.CheckAccessV3(ctx, req.OwnerUserID); err != nil { @@ -165,55 +172,44 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupR if req.OwnerUserID == "" { return nil, constant.ErrArgs.Wrap("no group owner") } - var userIDs []string - for _, userID := range req.InitMembers { - userIDs = append(userIDs, userID) - } - for _, userID := range req.AdminUserIDs { - userIDs = append(userIDs, userID) - } - userIDs = append(userIDs, req.OwnerUserID) - if utils.IsDuplicateID(userIDs) { + userIDs := append(append(req.InitMembers, req.AdminUserIDs...), req.OwnerUserID) + if utils.Duplicate(userIDs) { return nil, constant.ErrArgs.Wrap("group member repeated") } - users, err := getUsersInfo(ctx, userIDs) + userMap, err := GetUserInfoMap(ctx, userIDs) if err != nil { return nil, err } - userMap := make(map[string]*open_im_sdk.UserInfo) - for i, user := range users { - userMap[user.UserID] = users[i] - } - for _, userID := range userIDs { - if userMap[userID] == nil { - return nil, constant.ErrUserIDNotFound.Wrap(userID) - } + 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 { return nil, err } - var group relation2.GroupModel var groupMembers []*relation2.GroupMemberModel - utils.CopyStructFields(&group, req.GroupInfo) + group := PbToDBGroupInfo(req.GroupInfo) group.GroupID = genGroupID(ctx, req.GroupInfo.GroupID) + joinGroup := func(userID string, roleLevel int32) error { + groupMember := PbToDbGroupMember(userMap[userID]) + groupMember.GroupID = group.GroupID + groupMember.RoleLevel = roleLevel + 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 { + return err + } + groupMembers = append(groupMembers, groupMember) + return nil + } + if err := joinGroup(req.OwnerUserID, constant.GroupOwner); err != nil { + return nil, err + } if req.GroupInfo.GroupType == constant.SuperGroup { if err := s.GroupInterface.CreateSuperGroup(ctx, group.GroupID, userIDs); err != nil { return nil, err } } else { - joinGroup := func(userID string, roleLevel int32) error { - user := userMap[userID] - groupMember := &relation2.GroupMemberModel{GroupID: group.GroupID, RoleLevel: roleLevel, OperatorUserID: tracelog.GetOpUserID(ctx), JoinSource: constant.JoinByInvitation, InviterUserID: tracelog.GetOpUserID(ctx)} - utils.CopyStructFields(&groupMember, user) - if err := CallbackBeforeMemberJoinGroup(ctx, tracelog.GetOperationID(ctx), groupMember, group.Ex); err != nil { - return err - } - groupMembers = append(groupMembers, groupMember) - return nil - } - if err := joinGroup(req.OwnerUserID, constant.GroupOwner); err != nil { - return nil, err - } for _, userID := range req.AdminUserIDs { if err := joinGroup(userID, constant.GroupAdmin); err != nil { return nil, err @@ -225,10 +221,10 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupR } } } - if err := s.GroupInterface.CreateGroup(ctx, []*relation2.GroupModel{&group}, groupMembers); err != nil { + if err := s.GroupInterface.CreateGroup(ctx, []*relation2.GroupModel{group}, groupMembers); err != nil { return nil, err } - utils.CopyStructFields(resp.GroupInfo, group) + resp.GroupInfo = DbToPbGroupInfo(group, req.OwnerUserID, uint32(len(userIDs))) resp.GroupInfo.MemberCount = uint32(len(userIDs)) if req.GroupInfo.GroupType == constant.SuperGroup { go func() { @@ -247,22 +243,22 @@ func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbGroup.GetJo if err := token_verify.CheckAccessV3(ctx, req.FromUserID); err != nil { return nil, err } - groups, err := s.GroupInterface.GetJoinedGroupList(ctx, req.FromUserID) + total, groups, err := s.GroupInterface.FindJoinedGroup(ctx, req.FromUserID, req.Pagination.PageNumber, req.Pagination.ShowNumber) if err != nil { return nil, err } + resp.Total = total if len(groups) == 0 { return resp, nil } - var groupIDs []string - for _, group := range groups { - groupIDs = append(groupIDs, group.GroupID) - } - groupMemberNum, err := s.GroupInterface.GetGroupMemberNum(ctx, groupIDs) + groupIDs := utils.Slice(groups, func(e *relation2.GroupModel) string { + return e.GroupID + }) + groupMemberNum, err := s.GroupInterface.MapGroupMemberNum(ctx, groupIDs) if err != nil { return nil, err } - groupOwnerUserID, err := s.GroupInterface.GetGroupOwnerUserID(ctx, groupIDs) + groupOwnerUserID, err := s.GroupInterface.MapGroupOwnerUserID(ctx, groupIDs) if err != nil { return nil, err } @@ -270,13 +266,7 @@ func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbGroup.GetJo if group.Status == constant.GroupStatusDismissed || group.GroupType == constant.SuperGroup { continue } - var groupNode open_im_sdk.GroupInfo - utils.CopyStructFields(&groupNode, group) - groupNode.MemberCount = uint32(groupMemberNum[group.GroupID]) - groupNode.OwnerUserID = groupOwnerUserID[group.GroupID] - groupNode.CreateTime = group.CreateTime.UnixMilli() - groupNode.NotificationUpdateTime = group.NotificationUpdateTime.UnixMilli() - resp.Groups = append(resp.Groups, &groupNode) + resp.Groups = append(resp.Groups, DbToPbGroupInfo(group, groupOwnerUserID[group.GroupID], uint32(groupMemberNum[group.GroupID]))) } resp.Total = int32(len(resp.Groups)) return resp, nil @@ -287,37 +277,32 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbGroup.Invite if len(req.InvitedUserIDs) == 0 { return nil, constant.ErrArgs.Wrap("user empty") } - if utils.IsDuplicateID(req.InvitedUserIDs) { + if utils.Duplicate(req.InvitedUserIDs) { return nil, constant.ErrArgs.Wrap("userID duplicate") } - group, err := s.GroupInterface.TakeGroupByID(ctx, req.GroupID) + group, err := s.GroupInterface.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } if group.Status == constant.GroupStatusDismissed { return nil, constant.ErrDismissedAlready.Wrap() } - members, err := s.GroupInterface.GetGroupMemberList(ctx, group.GroupID) + members, err := s.GroupInterface.FindGroupMemberAll(ctx, group.GroupID) if err != nil { return nil, err } - memberMap := make(map[string]*relation2.GroupMemberModel) - for i, member := range members { - memberMap[member.GroupID] = members[i] + memberMap := utils.SliceToMap(members, func(e *relation2.GroupMemberModel) string { + return e.UserID + }) + if ids := utils.Single(req.InvitedUserIDs, utils.Keys(memberMap)); len(ids) > 0 { + return nil, constant.ErrArgs.Wrap("user in group " + strings.Join(ids, ",")) } - for _, userID := range req.InvitedUserIDs { - if _, ok := memberMap[userID]; ok { - return nil, constant.ErrArgs.Wrap("user in group " + userID) - } - } - userMap, err := getUserMap(ctx, req.InvitedUserIDs) + userMap, err := GetUserInfoMap(ctx, req.InvitedUserIDs) if err != nil { return nil, err } - for _, userID := range req.InvitedUserIDs { - if _, ok := userMap[userID]; !ok { - return nil, constant.ErrUserIDNotFound.Wrap(userID) - } + 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 !token_verify.IsAppManagerUid(ctx) { @@ -362,18 +347,16 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbGroup.Invite opUserID := tracelog.GetOpUserID(ctx) var groupMembers []*relation2.GroupMemberModel for _, userID := range req.InvitedUserIDs { - user := userMap[userID] - var member relation2.GroupMemberModel - utils.CopyStructFields(&member, user) + member := PbToDbGroupMember(userMap[userID]) member.GroupID = req.GroupID member.RoleLevel = constant.GroupOrdinaryUsers 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, tracelog.GetOperationID(ctx), member, group.Ex); err != nil { return nil, err } - groupMembers = append(groupMembers, &member) + groupMembers = append(groupMembers, member) } if err := s.GroupInterface.CreateGroupMember(ctx, groupMembers); err != nil { return nil, err @@ -385,65 +368,38 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbGroup.Invite func (s *groupServer) GetGroupAllMember(ctx context.Context, req *pbGroup.GetGroupAllMemberReq) (*pbGroup.GetGroupAllMemberResp, error) { resp := &pbGroup.GetGroupAllMemberResp{} - group, err := s.GroupInterface.TakeGroupByID(ctx, req.GroupID) + group, err := s.GroupInterface.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } - if group.GroupType != constant.SuperGroup { - members, err := s.GroupInterface.GetGroupMemberList(ctx, req.GroupID) - if err != nil { - return nil, err - } - var userIDs []string - for _, member := range members { - userIDs = append(userIDs, member.UserID) - } - for _, member := range members { - var node open_im_sdk.GroupMemberFullInfo - utils.CopyStructFields(&node, member) - resp.Members = append(resp.Members, &node) - } + if group.GroupType == constant.SuperGroup { + return nil, constant.ErrArgs.Wrap("unsupported super group") } + members, err := s.GroupInterface.FindGroupMemberAll(ctx, req.GroupID) + if err != nil { + return nil, err + } + resp.Members = utils.Slice(members, func(e *relation2.GroupMemberModel) *open_im_sdk.GroupMemberFullInfo { + return DbToPbGroupMembersCMSResp(e) + }) return resp, nil } func (s *groupServer) GetGroupMemberList(ctx context.Context, req *pbGroup.GetGroupMemberListReq) (*pbGroup.GetGroupMemberListResp, error) { resp := &pbGroup.GetGroupMemberListResp{} - members, err := s.GroupInterface.GetGroupMemberFilterList(ctx, req.GroupID, req.Filter, req.Pagination.PageNumber, req.Pagination.ShowNumber) + members, err := s.GroupInterface.FindGroupMemberFilterList(ctx, req.GroupID, req.Filter, req.Pagination.PageNumber, req.Pagination.ShowNumber) if err != nil { return nil, err } - for _, member := range members { - var info open_im_sdk.GroupMemberFullInfo - utils.CopyStructFields(&info, &member) - resp.Members = append(resp.Members, &info) - } + resp.Members = utils.Slice(members, func(e *relation2.GroupMemberModel) *open_im_sdk.GroupMemberFullInfo { + return DbToPbGroupMembersCMSResp(e) + }) return resp, nil } -//func (s *groupServer) getGroupUserLevel(groupID, userID string) (int, error) { -// opFlag := 0 -// if !token_verify.IsManagerUserID(userID) { -// opInfo, err := relation.GetGroupMemberInfoByGroupIDAndUserID(groupID, userID) -// if err != nil { -// return opFlag, utils.Wrap(err, "") -// } -// if opInfo.RoleLevel == constant.GroupOrdinaryUsers { -// opFlag = 0 -// } else if opInfo.RoleLevel == constant.GroupOwner { -// opFlag = 2 // owner -// } else { -// opFlag = 3 // admin -// } -// } else { -// opFlag = 1 // app manager -// } -// return opFlag, nil -//} - func (s *groupServer) KickGroupMember(ctx context.Context, req *pbGroup.KickGroupMemberReq) (*pbGroup.KickGroupMemberResp, error) { resp := &pbGroup.KickGroupMemberResp{} - group, err := s.GroupInterface.TakeGroupByID(ctx, req.GroupID) + group, err := s.GroupInterface.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } @@ -458,7 +414,7 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbGroup.KickGrou return nil, constant.ErrArgs.Wrap("opUserID in KickedUserIDs") } if group.GroupType == constant.SuperGroup { - if err := s.GroupInterface.DelSuperGroupMember(ctx, req.GroupID, req.KickedUserIDs); err != nil { + if err := s.GroupInterface.DeleteSuperGroupMember(ctx, req.GroupID, req.KickedUserIDs); err != nil { return nil, err } go func() { @@ -467,7 +423,7 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbGroup.KickGrou } }() } else { - members, err := s.GroupInterface.FindGroupMembersByID(ctx, req.GroupID, append(req.KickedUserIDs, opUserID)) + members, err := s.GroupInterface.FindGroupMember(ctx, req.GroupID, append(req.KickedUserIDs, opUserID)) if err != nil { return nil, err } @@ -500,7 +456,7 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbGroup.KickGrou return nil, constant.ErrNoPermission.Wrap("opUserID is OrdinaryUser") } } - if err := s.GroupInterface.DelGroupMember(ctx, group.GroupID, req.KickedUserIDs); err != nil { + if err := s.GroupInterface.DeleteGroupMember(ctx, group.GroupID, req.KickedUserIDs); err != nil { return nil, err } chat.MemberKickedNotification(req, req.KickedUserIDs) @@ -510,42 +466,16 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbGroup.KickGrou func (s *groupServer) GetGroupMembersInfo(ctx context.Context, req *pbGroup.GetGroupMembersInfoReq) (*pbGroup.GetGroupMembersInfoResp, error) { resp := &pbGroup.GetGroupMembersInfoResp{} - members, err := s.GroupInterface.GetGroupMemberListByUserID(ctx, req.GroupID, req.Members) + members, err := s.GroupInterface.FindGroupMember(ctx, req.GroupID, req.Members) if err != nil { return nil, err } - for _, member := range members { - var memberNode open_im_sdk.GroupMemberFullInfo - utils.CopyStructFields(&memberNode, member) - memberNode.JoinTime = member.JoinTime.UnixMilli() - resp.Members = append(resp.Members, &memberNode) - } + resp.Members = utils.Slice(members, func(e *relation2.GroupMemberModel) *open_im_sdk.GroupMemberFullInfo { + return DbToPbGroupMembersCMSResp(e) + }) return resp, nil } -//func FillGroupInfoByGroupID(operationID, groupID string, groupInfo *open_im_sdk.GroupInfo) error { -// group, err := relation.TakeGroupInfoByGroupID(groupID) -// if err != nil { -// log.Error(operationID, "TakeGroupInfoByGroupID failed ", err.Error(), groupID) -// return utils.Wrap(err, "") -// } -// if group.Status == constant.GroupStatusDismissed { -// log.Debug(operationID, " group constant.GroupStatusDismissed ", group.GroupID) -// return utils.Wrap(constant.ErrDismissedAlready, "") -// } -// return utils.Wrap(cp.GroupDBCopyOpenIM(groupInfo, group), "") -//} - -//func FillPublicUserInfoByUserID(operationID, userID string, userInfo *open_im_sdk.PublicUserInfo) error { -// user, err := relation.TakeUserByUserID(userID) -// if err != nil { -// log.Error(operationID, "TakeUserByUserID failed ", err.Error(), userID) -// return utils.Wrap(err, "") -// } -// cp.UserDBCopyOpenIMPublicUser(userInfo, user) -// return nil -//} - func (s *groupServer) GetGroupApplicationList(ctx context.Context, req *pbGroup.GetGroupApplicationListReq) (*pbGroup.GetGroupApplicationListResp, error) { resp := &pbGroup.GetGroupApplicationListResp{} groupRequests, err := s.GroupInterface.GetGroupRecvApplicationList(ctx, req.FromUserID) @@ -563,212 +493,171 @@ func (s *groupServer) GetGroupApplicationList(ctx context.Context, req *pbGroup. userIDs = append(userIDs, gr.UserID) groupIDs = append(groupIDs, gr.GroupID) } - userMap, err := getUserMap(ctx, userIDs) + userIDs = utils.Distinct(userIDs) + groupIDs = utils.Distinct(groupIDs) + userMap, err := GetPublicUserInfoMap(ctx, userIDs) if err != nil { return nil, err } - for _, userID := range userIDs { - if _, ok := userMap[userID]; !ok { - return nil, constant.ErrUserIDNotFound.Wrap(userID) - } + if ids := utils.Single(utils.Keys(userMap), userIDs); len(ids) > 0 { + return nil, constant.ErrUserIDNotFound.Wrap(strings.Join(ids, ",")) } - groups, err := s.GroupInterface.FindGroupsByID(ctx, groupIDs) + groups, err := s.GroupInterface.FindGroup(ctx, utils.Distinct(groupIDs)) if err != nil { return nil, err } - groupMap := make(map[string]*relation2.GroupModel) - for i, group := range groups { - groupMap[group.GroupID] = groups[i] + groupMap := utils.SliceToMap(groups, func(e *relation2.GroupModel) string { + return e.GroupID + }) + if ids := utils.Single(utils.Keys(groupMap), groupIDs); len(ids) > 0 { + return nil, constant.ErrGroupIDNotFound.Wrap(strings.Join(ids, ",")) } - - for _, gr := range groupRequests { - groupRequest := open_im_sdk.GroupRequest{UserInfo: &open_im_sdk.PublicUserInfo{}, GroupInfo: &open_im_sdk.GroupInfo{}} - utils.CopyStructFields(&groupRequest, gr) - getUserMap() - - } - - var errResult error - tracelog.SetCtxInfo(ctx, "GetRecvGroupApplicationList", nil, " FromUserID: ", req.FromUserID, "GroupApplicationList: ", groupRequests) - for _, v := range groupRequests { - node := open_im_sdk.GroupRequest{UserInfo: &open_im_sdk.PublicUserInfo{}, GroupInfo: &open_im_sdk.GroupInfo{}} - err := FillGroupInfoByGroupID(tracelog.GetOperationID(ctx), v.GroupID, node.GroupInfo) - if err != nil { - if !errors.Is(errors.Unwrap(err), constant.ErrDismissedAlready) { - errResult = err - } - continue - } - tracelog.SetCtxInfo(ctx, "FillGroupInfoByGroupID ", nil, " groupID: ", v.GroupID, " groupInfo: ", node.GroupInfo) - err = FillPublicUserInfoByUserID(tracelog.GetOperationID(ctx), v.UserID, node.UserInfo) - if err != nil { - errResult = err - continue - } - cp.GroupRequestDBCopyOpenIM(&node, &v) - resp.GroupRequestList = append(resp.GroupRequestList, &node) - } - if errResult != nil && len(resp.GroupRequestList) == 0 { + groupMemberNumMap, err := s.GroupInterface.MapGroupMemberNum(ctx, groupIDs) + if err != nil { return nil, err } - tracelog.SetRpcRespInfo(ctx, utils.GetSelfFuncName(), resp.String()) + groupOwnerUserIDMap, err := s.GroupInterface.MapGroupOwnerUserID(ctx, groupIDs) + if err != nil { + return nil, err + } + resp.GroupRequests = utils.Slice(groupRequests, func(e *relation2.GroupRequestModel) *open_im_sdk.GroupRequest { + return DbToPbGroupRequest(e, userMap[e.UserID], DbToPbGroupInfo(groupMap[e.GroupID], groupOwnerUserIDMap[e.GroupID], uint32(groupMemberNumMap[e.GroupID]))) + }) return resp, nil } func (s *groupServer) GetGroupsInfo(ctx context.Context, req *pbGroup.GetGroupsInfoReq) (*pbGroup.GetGroupsInfoResp, error) { resp := &pbGroup.GetGroupsInfoResp{} - groupsInfoList := make([]*open_im_sdk.GroupInfo, 0) - for _, groupID := range req.GroupIDList { - groupInfoFromRedis, err := rocksCache.GetGroupInfoFromCache(ctx, groupID) - if err != nil { - continue - } - var groupInfo open_im_sdk.GroupInfo - cp.GroupDBCopyOpenIM(&groupInfo, groupInfoFromRedis) - groupInfo.NeedVerification = groupInfoFromRedis.NeedVerification - groupsInfoList = append(groupsInfoList, &groupInfo) + if len(req.GroupIDs) == 0 { + return nil, constant.ErrArgs.Wrap("groupID is empty") } - resp.GroupInfoList = groupsInfoList + groups, err := s.GroupInterface.FindGroup(ctx, req.GroupIDs) + if err != nil { + return nil, err + } + groupMemberNumMap, err := s.GroupInterface.MapGroupMemberNum(ctx, req.GroupIDs) + if err != nil { + return nil, err + } + groupOwnerUserIDMap, err := s.GroupInterface.MapGroupOwnerUserID(ctx, req.GroupIDs) + if err != nil { + return nil, err + } + resp.GroupInfos = utils.Slice(groups, func(e *relation2.GroupModel) *open_im_sdk.GroupInfo { + 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.TakeGroupMember(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.TakeGroup(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.TakeGroupMember(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 } func (s *groupServer) JoinGroup(ctx context.Context, req *pbGroup.JoinGroupReq) (*pbGroup.JoinGroupResp, error) { resp := &pbGroup.JoinGroupResp{} - - if _, err := relation.GetUserByUserID(tracelog.GetOpUserID(ctx)); err != nil { + if _, err := GetPublicUserInfoOne(ctx, tracelog.GetOpUserID(ctx)); err != nil { return nil, err } - groupInfo, err := rocksCache.GetGroupInfoFromCache(ctx, req.GroupID) + group, err := s.GroupInterface.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } - if groupInfo.Status == constant.GroupStatusDismissed { - return nil, utils.Wrap(constant.ErrDismissedAlready, "") + if group.Status == constant.GroupStatusDismissed { + return nil, constant.ErrDismissedAlready.Wrap() } - - if groupInfo.NeedVerification == constant.Directly { - if groupInfo.GroupType != constant.SuperGroup { - us, err := relation.GetUserByUserID(tracelog.GetOpUserID(ctx)) - if err != nil { - return nil, err - } - //to group member - groupMember := relation2.GroupMemberModel{GroupID: req.GroupID, RoleLevel: constant.GroupOrdinaryUsers, OperatorUserID: tracelog.GetOpUserID(ctx)} - utils.CopyStructFields(&groupMember, us) - if err := CallbackBeforeMemberJoinGroup(ctx, tracelog.GetOperationID(ctx), &groupMember, groupInfo.Ex); err != nil { - return nil, err - } - if err := s.DelGroupAndUserCache(ctx, req.GroupID, []string{tracelog.GetOpUserID(ctx)}); err != nil { - return nil, err - } - err = relation.InsertIntoGroupMember(groupMember) - if err != nil { - return nil, err - } - - var sessionType int - if groupInfo.GroupType == constant.NormalGroup { - sessionType = constant.GroupChatType - } else { - sessionType = constant.SuperGroupChatType - } - var reqPb pbUser.SetConversationReq - var c pbConversation.Conversation - reqPb.OperationID = tracelog.GetOperationID(ctx) - c.OwnerUserID = tracelog.GetOpUserID(ctx) - c.ConversationID = utils.GetConversationIDBySessionType(req.GroupID, sessionType) - c.ConversationType = int32(sessionType) - c.GroupID = req.GroupID - c.IsNotInGroup = false - c.UpdateUnreadCountTime = utils.GetCurrentTimestampByMill() - reqPb.Conversation = &c - etcdConn, err := getcdv3.GetConn(ctx, config.Config.RpcRegisterName.OpenImUserName) - if err != nil { - return nil, err - } - client := pbUser.NewUserClient(etcdConn) - respPb, err := client.SetConversation(context.Background(), &reqPb) - tracelog.SetCtxInfo(ctx, "SetConversation", err, "req", reqPb, "resp", respPb) - chat.MemberEnterDirectlyNotification(req.GroupID, tracelog.GetOpUserID(ctx), tracelog.GetOperationID(ctx)) - return resp, nil - } else { - constant.SetErrorForResp(constant.ErrGroupTypeNotSupport, resp.CommonResp) - return resp, nil + if group.NeedVerification == constant.Directly { + if group.GroupType == constant.SuperGroup { + return nil, constant.ErrGroupTypeNotSupport.Wrap() } + user, err := relation.GetUserByUserID(tracelog.GetOpUserID(ctx)) + if err != nil { + return nil, err + } + groupMember := PbToDbGroupMember(user) + groupMember.GroupID = group.GroupID + groupMember.RoleLevel = constant.GroupOrdinaryUsers + 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 { + return nil, err + } + if err := s.GroupInterface.CreateGroupMember(ctx, []*relation2.GroupMemberModel{groupMember}); err != nil { + return nil, err + } + chat.MemberEnterDirectlyNotification(req.GroupID, tracelog.GetOpUserID(ctx), tracelog.GetOperationID(ctx)) + return resp, nil } - var groupRequest relation2.GroupRequestModel - groupRequest.UserID = tracelog.GetOpUserID(ctx) - groupRequest.ReqMsg = req.ReqMessage - groupRequest.GroupID = req.GroupID - groupRequest.JoinSource = req.JoinSource - err = relation.InsertIntoGroupRequest(groupRequest) - if err != nil { + groupRequest := relation2.GroupRequestModel{ + UserID: tracelog.GetOpUserID(ctx), + ReqMsg: req.ReqMessage, + GroupID: req.GroupID, + JoinSource: req.JoinSource, + ReqTime: time.Now(), + } + if err := s.GroupInterface.CreateGroupRequest(ctx, []*relation2.GroupRequestModel{&groupRequest}); err != nil { return nil, err } chat.JoinGroupApplicationNotification(ctx, req) @@ -777,170 +666,102 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbGroup.JoinGroupReq) func (s *groupServer) QuitGroup(ctx context.Context, req *pbGroup.QuitGroupReq) (*pbGroup.QuitGroupResp, error) { resp := &pbGroup.QuitGroupResp{} - - groupInfo, err := relation.GetGroupInfoByGroupID(req.GroupID) + group, err := s.GroupInterface.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } - if groupInfo.GroupType != constant.SuperGroup { - _, err = rocksCache.GetGroupMemberInfoFromCache(ctx, req.GroupID, tracelog.GetOpUserID(ctx)) - if err != nil { + if group.GroupType == constant.SuperGroup { + if err := s.GroupInterface.DeleteSuperGroupMember(ctx, req.GroupID, []string{tracelog.GetOpUserID(ctx)}); err != nil { return nil, err } - if err := s.DelGroupAndUserCache(ctx, req.GroupID, []string{tracelog.GetOpUserID(ctx)}); err != nil { - return nil, err - } - err = relation.DeleteGroupMemberByGroupIDAndUserID(req.GroupID, tracelog.GetOpUserID(ctx)) - if err != nil { - return nil, err - } - } else { - okUserIDList := []string{tracelog.GetOpUserID(ctx)} - if err := db.DB.RemoverUserFromSuperGroup(req.GroupID, okUserIDList); err != nil { - return nil, err - } - } - - if groupInfo.GroupType != constant.SuperGroup { - _ = rocksCache.DelGroupMemberInfoFromCache(ctx, req.GroupID, tracelog.GetOpUserID(ctx)) - chat.MemberQuitNotification(req) - } else { - _ = rocksCache.DelJoinedSuperGroupIDListFromCache(ctx, tracelog.GetOpUserID(ctx)) - _ = rocksCache.DelGroupMemberListHashFromCache(ctx, req.GroupID) chat.SuperGroupNotification(tracelog.GetOperationID(ctx), tracelog.GetOpUserID(ctx), tracelog.GetOpUserID(ctx)) + } else { + _, err := s.GroupInterface.TakeGroupMember(ctx, req.GroupID, tracelog.GetOpUserID(ctx)) + if err != nil { + return nil, err + } + chat.MemberQuitNotification(req) } return resp, nil } func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbGroup.SetGroupInfoReq) (*pbGroup.SetGroupInfoResp, error) { resp := &pbGroup.SetGroupInfoResp{} - - if !hasAccess(req) { - return nil, utils.Wrap(constant.ErrIdentity, "") + if !token_verify.IsAppManagerUid(ctx) { + groupMember, err := s.GroupInterface.TakeGroupMember(ctx, req.GroupInfoForSet.GroupID, tracelog.GetOpUserID(ctx)) + 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") + } } - group, err := relation.GetGroupInfoByGroupID(req.GroupInfoForSet.GroupID) + group, err := s.TakeGroup(ctx, req.GroupInfoForSet.GroupID) if err != nil { return nil, err } if group.Status == constant.GroupStatusDismissed { return nil, utils.Wrap(constant.ErrDismissedAlready, "") } - - var changedType int32 - groupName := "" - notification := "" - introduction := "" - faceURL := "" - if group.GroupName != req.GroupInfoForSet.GroupName && req.GroupInfoForSet.GroupName != "" { - changedType = 1 - groupName = req.GroupInfoForSet.GroupName + data := UpdateGroupInfoMap(req.GroupInfoForSet) + if len(data) > 0 { + return resp, nil } - if group.Notification != req.GroupInfoForSet.Notification && req.GroupInfoForSet.Notification != "" { - changedType = changedType | (1 << 1) - notification = req.GroupInfoForSet.Notification - } - if group.Introduction != req.GroupInfoForSet.Introduction && req.GroupInfoForSet.Introduction != "" { - changedType = changedType | (1 << 2) - introduction = req.GroupInfoForSet.Introduction - } - if group.FaceURL != req.GroupInfoForSet.FaceURL && req.GroupInfoForSet.FaceURL != "" { - changedType = changedType | (1 << 3) - faceURL = req.GroupInfoForSet.FaceURL - } - - if req.GroupInfoForSet.NeedVerification != nil { - changedType = changedType | (1 << 4) - m := make(map[string]interface{}) - m["need_verification"] = req.GroupInfoForSet.NeedVerification.Value - if err := relation.UpdateGroupInfoDefaultZero(req.GroupInfoForSet.GroupID, m); err != nil { - return nil, err - } - } - if req.GroupInfoForSet.LookMemberInfo != nil { - changedType = changedType | (1 << 5) - m := make(map[string]interface{}) - m["look_member_info"] = req.GroupInfoForSet.LookMemberInfo.Value - if err := relation.UpdateGroupInfoDefaultZero(req.GroupInfoForSet.GroupID, m); err != nil { - return nil, err - } - } - if req.GroupInfoForSet.ApplyMemberFriend != nil { - changedType = changedType | (1 << 6) - m := make(map[string]interface{}) - m["apply_member_friend"] = req.GroupInfoForSet.ApplyMemberFriend.Value - if err := relation.UpdateGroupInfoDefaultZero(req.GroupInfoForSet.GroupID, m); err != nil { - return nil, err - } - } - //only administrators can set group information - var groupInfo relation2.GroupModel - utils.CopyStructFields(&groupInfo, req.GroupInfoForSet) - if req.GroupInfoForSet.Notification != "" { - groupInfo.NotificationUserID = tracelog.GetOpUserID(ctx) - groupInfo.NotificationUpdateTime = time.Now() - } - if err := rocksCache.DelGroupInfoFromCache(ctx, req.GroupInfoForSet.GroupID); err != nil { + if err := s.GroupInterface.UpdateGroup(ctx, group.GroupID, data); err != nil { return nil, err } - err = relation.SetGroupInfo(groupInfo) + group, err = s.TakeGroup(ctx, req.GroupInfoForSet.GroupID) if err != nil { return nil, err } - if changedType != 0 { - chat.GroupInfoSetNotification(tracelog.GetOperationID(ctx), tracelog.GetOpUserID(ctx), req.GroupInfoForSet.GroupID, groupName, notification, introduction, faceURL, req.GroupInfoForSet.NeedVerification) - } + 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 != "" { - //get group member user id - var conversationReq pbConversation.ModifyConversationFieldReq - conversation := pbConversation.Conversation{ - OwnerUserID: tracelog.GetOpUserID(ctx), - ConversationID: utils.GetConversationIDBySessionType(req.GroupInfoForSet.GroupID, constant.GroupChatType), - ConversationType: constant.GroupChatType, - GroupID: req.GroupInfoForSet.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) + GroupNotification(ctx, group.GroupID) } return resp, nil } func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbGroup.TransferGroupOwnerReq) (*pbGroup.TransferGroupOwnerResp, error) { resp := &pbGroup.TransferGroupOwnerResp{} - - groupInfo, err := relation.GetGroupInfoByGroupID(req.GroupID) + group, err := s.GroupInterface.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } - if groupInfo.Status == constant.GroupStatusDismissed { + if group.Status == constant.GroupStatusDismissed { return nil, utils.Wrap(constant.ErrDismissedAlready, "") } - if req.OldOwnerUserID == req.NewOwnerUserID { - return nil, err + return nil, constant.ErrArgs.Wrap("OldOwnerUserID == NewOwnerUserID") } - err = rocksCache.DelGroupMemberInfoFromCache(ctx, req.GroupID, req.NewOwnerUserID) + members, err := s.GroupInterface.FindGroupMember(ctx, req.GroupID, []string{req.OldOwnerUserID, req.NewOwnerUserID}) if err != nil { return nil, err } - err = rocksCache.DelGroupMemberInfoFromCache(ctx, req.GroupID, req.OldOwnerUserID) - if err != nil { - return nil, err + memberMap := utils.SliceToMap(members, func(e *relation2.GroupMemberModel) string { return e.UserID }) + if ids := utils.Single([]string{req.OldOwnerUserID, req.NewOwnerUserID}, utils.Keys(memberMap)); len(ids) > 0 { + return nil, constant.ErrArgs.Wrap("user not in group " + strings.Join(ids, ",")) } - - groupMemberInfo := relation2.GroupMemberModel{GroupID: req.GroupID, UserID: req.OldOwnerUserID, RoleLevel: constant.GroupOrdinaryUsers} - err = relation.UpdateGroupMemberInfo(groupMemberInfo) - if err != nil { - return nil, err + newOwner := memberMap[req.NewOwnerUserID] + if newOwner == nil { + return nil, constant.ErrArgs.Wrap("NewOwnerUser not in group " + req.NewOwnerUserID) } - groupMemberInfo = relation2.GroupMemberModel{GroupID: req.GroupID, UserID: req.NewOwnerUserID, RoleLevel: constant.GroupOwner} - err = relation.UpdateGroupMemberInfo(groupMemberInfo) - if err != nil { + oldOwner := memberMap[req.OldOwnerUserID] + if token_verify.IsAppManagerUid(ctx) { + if oldOwner == nil { + oldOwner, err = s.GroupInterface.TakeGroupOwner(ctx, req.OldOwnerUserID) + if err != nil { + return nil, err + } + } + } else { + if oldOwner == nil { + return nil, constant.ErrArgs.Wrap("OldOwnerUser not in group " + req.NewOwnerUserID) + } + if oldOwner.GroupID != tracelog.GetOpUserID(ctx) { + 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 { return nil, err } chat.GroupOwnerTransferredNotification(req) @@ -948,194 +769,146 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbGroup.Trans } func (s *groupServer) GetGroups(ctx context.Context, req *pbGroup.GetGroupsReq) (*pbGroup.GetGroupsResp, error) { - resp := &pbGroup.GetGroupsResp{ - Groups: []*pbGroup.CMSGroup{}, - Pagination: &open_im_sdk.ResponsePagination{CurrentPage: req.Pagination.PageNumber, ShowNumber: req.Pagination.ShowNumber}, - } - + resp := &pbGroup.GetGroupsResp{} + var ( + groups []*relation2.GroupModel + err error + ) if req.GroupID != "" { - groupInfoDB, err := relation.GetGroupInfoByGroupID(req.GroupID) - if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - return resp, nil - } - return nil, err - } - resp.GroupNum = 1 - groupInfo := &open_im_sdk.GroupInfo{} - utils.CopyStructFields(groupInfo, groupInfoDB) - groupMember, err := relation.GetGroupOwnerInfoByGroupID(req.GroupID) - if err != nil { - return nil, err - } - memberNum, err := relation.GetGroupMembersCount(req.GroupID, "") - if err != nil { - return nil, err - } - groupInfo.MemberCount = uint32(memberNum) - groupInfo.CreateTime = uint32(groupInfoDB.CreateTime.Unix()) - resp.Groups = append(resp.Groups, &pbGroup.CMSGroup{GroupInfo: groupInfo, GroupOwnerUserName: groupMember.Nickname, GroupOwnerUserID: groupMember.UserID}) + groups, err = s.GroupInterface.FindGroup(ctx, []string{req.GroupID}) + resp.GroupNum = int32(len(groups)) } else { - groups, count, err := relation.GetGroupsByName(req.GroupName, req.Pagination.PageNumber, req.Pagination.ShowNumber) - if err != nil { - tracelog.SetCtxInfo(ctx, "GetGroupsByName", err, "GroupName", req.GroupName, "PageNumber", req.Pagination.PageNumber, "ShowNumber", req.Pagination.ShowNumber) - } - for _, v := range groups { - group := &pbGroup.CMSGroup{GroupInfo: &open_im_sdk.GroupInfo{}} - utils.CopyStructFields(group.GroupInfo, v) - groupMember, err := relation.GetGroupOwnerInfoByGroupID(v.GroupID) - if err != nil { - tracelog.SetCtxInfo(ctx, "GetGroupOwnerInfoByGroupID", err, "GroupID", v.GroupID) - continue - } - group.GroupInfo.CreateTime = uint32(v.CreateTime.Unix()) - group.GroupOwnerUserID = groupMember.UserID - group.GroupOwnerUserName = groupMember.Nickname - resp.Groups = append(resp.Groups, group) - } - resp.GroupNum = int32(count) + resp.GroupNum, groups, err = s.GroupInterface.SearchGroup(ctx, req.GroupName, req.Pagination.PageNumber, req.Pagination.ShowNumber) } + if err != nil { + return nil, err + } + groupIDs := utils.Slice(groups, func(e *relation2.GroupModel) string { + return e.GroupID + }) + ownerMembers, err := s.GroupInterface.FindGroupOwnerUser(ctx, groupIDs) + if err != nil { + return nil, err + } + ownerMemberMap := utils.SliceToMap(ownerMembers, func(e *relation2.GroupMemberModel) string { + return e.GroupID + }) + if ids := utils.Single(groupIDs, utils.Keys(ownerMemberMap)); len(ids) > 0 { + return nil, constant.ErrDB.Wrap("group not owner " + strings.Join(ids, ",")) + } + groupMemberNumMap, err := s.GroupInterface.MapGroupMemberNum(ctx, groupIDs) + if err != nil { + return nil, err + } + resp.Groups = utils.Slice(groups, func(group *relation2.GroupModel) *pbGroup.CMSGroup { + member := ownerMemberMap[group.GroupID] + return DbToPbCMSGroup(group, member.UserID, member.Nickname, uint32(groupMemberNumMap[group.GroupID])) + }) return resp, nil } func (s *groupServer) GetGroupMembersCMS(ctx context.Context, req *pbGroup.GetGroupMembersCMSReq) (*pbGroup.GetGroupMembersCMSResp, error) { resp := &pbGroup.GetGroupMembersCMSResp{} - groupMembers, err := relation.GetGroupMembersByGroupIdCMS(req.GroupID, req.UserName, req.Pagination.ShowNumber, req.Pagination.PageNumber) + total, members, err := s.GroupInterface.SearchGroupMember(ctx, req.GroupID, req.UserName, req.Pagination.PageNumber, req.Pagination.ShowNumber) if err != nil { return nil, err } - groupMembersCount, err := relation.GetGroupMembersCount(req.GroupID, req.UserName) - if err != nil { - return nil, err - } - log.NewInfo(tracelog.GetOperationID(ctx), groupMembersCount) - resp.MemberNums = int32(groupMembersCount) - for _, groupMember := range groupMembers { - member := open_im_sdk.GroupMemberFullInfo{} - utils.CopyStructFields(&member, groupMember) - member.JoinTime = int32(groupMember.JoinTime.Unix()) - member.MuteEndTime = uint32(groupMember.MuteEndTime.Unix()) - resp.Members = append(resp.Members, &member) - } - resp.Pagination = &open_im_sdk.ResponsePagination{ - CurrentPage: req.Pagination.PageNumber, - ShowNumber: req.Pagination.ShowNumber, - } + resp.MemberNums = total + resp.Members = utils.Slice(members, func(e *relation2.GroupMemberModel) *open_im_sdk.GroupMemberFullInfo { + return DbToPbGroupMembersCMSResp(e) + }) return resp, nil } func (s *groupServer) GetUserReqApplicationList(ctx context.Context, req *pbGroup.GetUserReqApplicationListReq) (*pbGroup.GetUserReqApplicationListResp, error) { resp := &pbGroup.GetUserReqApplicationListResp{} - groupRequests, err := relation.GetUserReqGroupByUserID(req.UserID) + user, err := GetPublicUserInfoOne(ctx, req.UserID) if err != nil { return nil, err } - for _, groupReq := range groupRequests { - node := open_im_sdk.GroupRequest{UserInfo: &open_im_sdk.PublicUserInfo{}, GroupInfo: &open_im_sdk.GroupInfo{}} - group, err := relation.GetGroupInfoByGroupID(groupReq.GroupID) - if err != nil { - tracelog.SetCtxInfo(ctx, "GetGroupInfoByGroupID", err, "GroupID", groupReq.GroupID) - continue - } - user, err := relation.GetUserByUserID(groupReq.UserID) - if err != nil { - tracelog.SetCtxInfo(ctx, "GetUserByUserID", err, "UserID", groupReq.UserID) - continue - } - cp.GroupRequestDBCopyOpenIM(&node, &groupReq) - cp.UserDBCopyOpenIMPublicUser(node.UserInfo, user) - cp.GroupDBCopyOpenIM(node.GroupInfo, group) - resp.GroupRequestList = append(resp.GroupRequestList, &node) + total, requests, err := s.GroupInterface.FindUserGroupRequest(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber) + if err != nil { + return nil, err } + resp.Total = total + if len(requests) == 0 { + return resp, nil + } + groupIDs := utils.Distinct(utils.Slice(requests, func(e *relation2.GroupRequestModel) string { + return e.GroupID + })) + groups, err := s.GroupInterface.FindGroup(ctx, groupIDs) + if err != nil { + return nil, err + } + groupMap := utils.SliceToMap(groups, func(e *relation2.GroupModel) string { + return e.GroupID + }) + if ids := utils.Single(groupIDs, utils.Keys(groupMap)); len(ids) > 0 { + return nil, constant.ErrGroupIDNotFound.Wrap(strings.Join(ids, ",")) + } + owners, err := s.GroupInterface.FindGroupOwnerUser(ctx, groupIDs) + if err != nil { + return nil, err + } + ownerMap := utils.SliceToMap(owners, func(e *relation2.GroupMemberModel) string { + return e.GroupID + }) + if ids := utils.Single(groupIDs, utils.Keys(ownerMap)); len(ids) > 0 { + return nil, constant.ErrData.Wrap("group no owner", strings.Join(ids, ",")) + } + groupMemberNum, err := s.GroupInterface.MapGroupMemberNum(ctx, groupIDs) + if err != nil { + return nil, err + } + resp.GroupRequests = utils.Slice(requests, func(e *relation2.GroupRequestModel) *open_im_sdk.GroupRequest { + return DbToPbGroupRequest(e, user, DbToPbGroupInfo(groupMap[e.GroupID], ownerMap[e.GroupID].UserID, uint32(groupMemberNum[e.GroupID]))) + }) return resp, nil } func (s *groupServer) DismissGroup(ctx context.Context, req *pbGroup.DismissGroupReq) (*pbGroup.DismissGroupResp, error) { resp := &pbGroup.DismissGroupResp{} - - if !token_verify.IsManagerUserID(tracelog.GetOpUserID(ctx)) && !relation.IsGroupOwnerAdmin(req.GroupID, tracelog.GetOpUserID(ctx)) { - return nil, utils.Wrap(constant.ErrIdentity, "") - } - - if err := rocksCache.DelGroupInfoFromCache(ctx, req.GroupID); err != nil { + if err := s.CheckGroupAdmin(ctx, req.GroupID); err != nil { return nil, err } - if err := s.DelGroupAndUserCache(ctx, req.GroupID, nil); err != nil { - return nil, err - } - - err := relation.OperateGroupStatus(req.GroupID, constant.GroupStatusDismissed) + group, err := s.GroupInterface.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } - groupInfo, err := relation.GetGroupInfoByGroupID(req.GroupID) - if err != nil { + if group.Status == constant.GroupStatusDismissed { + return nil, constant.ErrArgs.Wrap("group status is dismissed") + } + if err := s.GroupInterface.DismissGroup(ctx, req.GroupID); err != nil { return nil, err } - if groupInfo.GroupType != constant.SuperGroup { - memberList, err := relation.GetGroupMemberListByGroupID(req.GroupID) - if err != nil { - tracelog.SetCtxInfo(ctx, "GetGroupMemberListByGroupID", err, "groupID", req.GroupID) - } - //modify quitter conversation info - var reqPb pbUser.SetConversationReq - var c pbConversation.Conversation - for _, v := range memberList { - reqPb.OperationID = tracelog.GetOperationID(ctx) - c.OwnerUserID = v.UserID - c.ConversationID = utils.GetConversationIDBySessionType(req.GroupID, constant.GroupChatType) - c.ConversationType = constant.GroupChatType - c.GroupID = req.GroupID - c.IsNotInGroup = true - reqPb.Conversation = &c - etcdConn, err := getcdv3.GetConn(ctx, config.Config.RpcRegisterName.OpenImUserName) - client := pbUser.NewUserClient(etcdConn) - respPb, err := client.SetConversation(context.Background(), &reqPb) - tracelog.SetCtxInfo(ctx, "SetConversation", err, "req", &reqPb, "resp", respPb) - } - err = relation.DeleteGroupMemberByGroupID(req.GroupID) - if err != nil { + if group.GroupType == constant.SuperGroup { + if err := s.GroupInterface.DeleteSuperGroup(ctx, group.GroupID); err != nil { return nil, err } - chat.GroupDismissedNotification(req) } else { - err = db.DB.DeleteSuperGroup(req.GroupID) - if err != nil { - return nil, err - } + chat.GroupDismissedNotification(req) } return resp, nil } func (s *groupServer) MuteGroupMember(ctx context.Context, req *pbGroup.MuteGroupMemberReq) (*pbGroup.MuteGroupMemberResp, error) { resp := &pbGroup.MuteGroupMemberResp{} - - opFlag, err := s.getGroupUserLevel(req.GroupID, tracelog.GetOpUserID(ctx)) + member, err := s.GroupInterface.TakeGroupMember(ctx, req.GroupID, req.UserID) if err != nil { return nil, err } - if opFlag == 0 { - return nil, err + if !(tracelog.GetOpUserID(ctx) == req.UserID || token_verify.IsAppManagerUid(ctx)) { + opMember, err := s.GroupInterface.TakeGroupMember(ctx, req.GroupID, req.UserID) + if err != nil { + return nil, err + } + if opMember.RoleLevel <= member.RoleLevel { + return nil, constant.ErrNoPermission.Wrap(fmt.Sprintf("self RoleLevel %d target %d", opMember.RoleLevel, member.RoleLevel)) + } } - - mutedInfo, err := rocksCache.GetGroupMemberInfoFromCache(ctx, req.GroupID, req.UserID) - if err != nil { - return nil, err - } - if mutedInfo.RoleLevel == constant.GroupOwner && opFlag != 1 { - return nil, err - } - if mutedInfo.RoleLevel == constant.GroupAdmin && opFlag == 3 { - return nil, err - } - - if err := rocksCache.DelGroupMemberInfoFromCache(ctx, req.GroupID, req.UserID); err != nil { - return nil, err - } - groupMemberInfo := relation2.GroupMemberModel{GroupID: req.GroupID, UserID: req.UserID} - groupMemberInfo.MuteEndTime = time.Unix(int64(time.Now().Second())+int64(req.MutedSeconds), time.Now().UnixNano()) - err = relation.UpdateGroupMemberInfo(groupMemberInfo) - if err != nil { + data := UpdateGroupMemberMutedTimeMap(time.Now().Add(time.Second * time.Duration(req.MutedSeconds))) + if err := s.GroupInterface.UpdateGroupMember(ctx, member.GroupID, member.UserID, data); err != nil { return nil, err } chat.GroupMemberMutedNotification(tracelog.GetOperationID(ctx), tracelog.GetOpUserID(ctx), req.GroupID, req.UserID, req.MutedSeconds) @@ -1144,33 +917,21 @@ func (s *groupServer) MuteGroupMember(ctx context.Context, req *pbGroup.MuteGrou func (s *groupServer) CancelMuteGroupMember(ctx context.Context, req *pbGroup.CancelMuteGroupMemberReq) (*pbGroup.CancelMuteGroupMemberResp, error) { resp := &pbGroup.CancelMuteGroupMemberResp{} - - opFlag, err := s.getGroupUserLevel(req.GroupID, tracelog.GetOpUserID(ctx)) + member, err := s.GroupInterface.TakeGroupMember(ctx, req.GroupID, req.UserID) if err != nil { return nil, err } - if opFlag == 0 { - return nil, err + if !(tracelog.GetOpUserID(ctx) == req.UserID || token_verify.IsAppManagerUid(ctx)) { + opMember, err := s.GroupInterface.TakeGroupMember(ctx, req.GroupID, tracelog.GetOpUserID(ctx)) + if err != nil { + return nil, err + } + if opMember.RoleLevel <= member.RoleLevel { + return nil, constant.ErrNoPermission.Wrap(fmt.Sprintf("self RoleLevel %d target %d", opMember.RoleLevel, member.RoleLevel)) + } } - - mutedInfo, err := relation.GetGroupMemberInfoByGroupIDAndUserID(req.GroupID, req.UserID) - if err != nil { - return nil, err - } - if mutedInfo.RoleLevel == constant.GroupOwner && opFlag != 1 { - return nil, err - } - if mutedInfo.RoleLevel == constant.GroupAdmin && opFlag == 3 { - return nil, err - } - if err := rocksCache.DelGroupMemberInfoFromCache(ctx, req.GroupID, req.UserID); err != nil { - return nil, err - } - - groupMemberInfo := relation2.GroupMemberModel{GroupID: req.GroupID, UserID: req.UserID} - groupMemberInfo.MuteEndTime = time.Unix(0, 0) - err = relation.UpdateGroupMemberInfo(groupMemberInfo) - if err != nil { + data := UpdateGroupMemberMutedTimeMap(time.Unix(0, 0)) + if err := s.GroupInterface.UpdateGroupMember(ctx, member.GroupID, member.UserID, data); err != nil { return nil, err } chat.GroupMemberCancelMutedNotification(tracelog.GetOperationID(ctx), tracelog.GetOpUserID(ctx), req.GroupID, req.UserID) @@ -1179,73 +940,22 @@ func (s *groupServer) CancelMuteGroupMember(ctx context.Context, req *pbGroup.Ca func (s *groupServer) MuteGroup(ctx context.Context, req *pbGroup.MuteGroupReq) (*pbGroup.MuteGroupResp, error) { resp := &pbGroup.MuteGroupResp{} - - opFlag, err := s.getGroupUserLevel(req.GroupID, tracelog.GetOpUserID(ctx)) - if err != nil { + if err := s.CheckGroupAdmin(ctx, req.GroupID); err != nil { return nil, err } - if opFlag == 0 { - //errMsg := req.OperationID + "opFlag == 0 " + req.GroupID + req.OpUserID - //log.Error(req.OperationID, errMsg) - //return &pbGroup.MuteGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrAccess.ErrCode, ErrMsg: errMsg}}, nil - return nil, utils.Wrap(constant.ErrNoPermission, "") - } - - //mutedInfo, err := relation.GetGroupMemberInfoByGroupIDAndUserID(req.GroupID, req.UserID) - //if err != nil { - // errMsg := req.OperationID + " GetGroupMemberInfoByGroupIDAndUserID failed " + req.GroupID + req.OpUserID + err.Error() - // return &pbGroup.MuteGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrAccess.ErrCode, ErrMsg: errMsg}}, nil - //} - //if mutedInfo.RoleLevel == constant.GroupOwner && opFlag != 1 { - // errMsg := req.OperationID + " mutedInfo.RoleLevel == constant.GroupOwner " + req.GroupID + req.OpUserID + err.Error() - // return &pbGroup.MuteGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrAccess.ErrCode, ErrMsg: errMsg}}, nil - //} - //if mutedInfo.RoleLevel == constant.GroupAdmin && opFlag == 3 { - // errMsg := req.OperationID + " mutedInfo.RoleLevel == constant.GroupAdmin " + req.GroupID + req.OpUserID + err.Error() - // return &pbGroup.MuteGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrAccess.ErrCode, ErrMsg: errMsg}}, nil - //} - if err := rocksCache.DelGroupInfoFromCache(ctx, req.GroupID); err != nil { + if err := s.GroupInterface.UpdateGroup(ctx, req.GroupID, UpdateGroupStatusMap(constant.GroupStatusMuted)); err != nil { return nil, err } - - err = relation.OperateGroupStatus(req.GroupID, constant.GroupStatusMuted) - if err != nil { - return nil, err - } - chat.GroupMutedNotification(tracelog.GetOperationID(ctx), tracelog.GetOpUserID(ctx), req.GroupID) return resp, nil } func (s *groupServer) CancelMuteGroup(ctx context.Context, req *pbGroup.CancelMuteGroupReq) (*pbGroup.CancelMuteGroupResp, error) { resp := &pbGroup.CancelMuteGroupResp{} - - opFlag, err := s.getGroupUserLevel(req.GroupID, tracelog.GetOpUserID(ctx)) - if err != nil { + if err := s.CheckGroupAdmin(ctx, req.GroupID); err != nil { return nil, err } - if opFlag == 0 { - return nil, err - } - //mutedInfo, err := relation.GetGroupMemberInfoByGroupIDAndUserID(req.GroupID, req.) - //if err != nil { - // errMsg := req.OperationID + " GetGroupMemberInfoByGroupIDAndUserID failed " + req.GroupID + req.OpUserID + err.Error() - // return &pbGroup.CancelMuteGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrAccess.ErrCode, ErrMsg: errMsg}}, nil - //} - //if mutedInfo.RoleLevel == constant.GroupOwner && opFlag != 1 { - // errMsg := req.OperationID + " mutedInfo.RoleLevel == constant.GroupOwner " + req.GroupID + req.OpUserID + err.Error() - // return &pbGroup.CancelMuteGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrAccess.ErrCode, ErrMsg: errMsg}}, nil - //} - //if mutedInfo.RoleLevel == constant.GroupAdmin && opFlag == 3 { - // errMsg := req.OperationID + " mutedInfo.RoleLevel == constant.GroupAdmin " + req.GroupID + req.OpUserID + err.Error() - // return &pbGroup.CancelMuteGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrAccess.ErrCode, ErrMsg: errMsg}}, nil - //} - log.Debug(tracelog.GetOperationID(ctx), "UpdateGroupInfoDefaultZero ", req.GroupID, map[string]interface{}{"status": constant.GroupOk}) - if err := rocksCache.DelGroupInfoFromCache(ctx, req.GroupID); err != nil { - return nil, err - } - err = relation.UpdateGroupInfoDefaultZero(req.GroupID, map[string]interface{}{"status": constant.GroupOk}) - if err != nil { + if err := s.GroupInterface.UpdateGroup(ctx, req.GroupID, UpdateGroupStatusMap(constant.GroupOk)); err != nil { return nil, err } chat.GroupCancelMutedNotification(tracelog.GetOperationID(ctx), tracelog.GetOpUserID(ctx), req.GroupID) @@ -1253,141 +963,89 @@ func (s *groupServer) CancelMuteGroup(ctx context.Context, req *pbGroup.CancelMu } func (s *groupServer) SetGroupMemberNickname(ctx context.Context, req *pbGroup.SetGroupMemberNicknameReq) (*pbGroup.SetGroupMemberNicknameResp, error) { - resp := &pbGroup.SetGroupMemberNicknameResp{} - if tracelog.GetOpUserID(ctx) != req.UserID && !token_verify.IsManagerUserID(tracelog.GetOpUserID(ctx)) { - return nil, utils.Wrap(constant.ErrIdentity, "") - } - cbReq := &pbGroup.SetGroupMemberInfoReq{ - GroupID: req.GroupID, - UserID: req.UserID, - Nickname: &wrapperspb.StringValue{Value: req.Nickname}, - } - if err := CallbackBeforeSetGroupMemberInfo(ctx, cbReq); err != nil { + _, err := s.SetGroupMemberInfo(ctx, &pbGroup.SetGroupMemberInfoReq{GroupID: req.GroupID, UserID: req.UserID, Nickname: wrapperspb.String(req.Nickname)}) + if err != nil { return nil, err } - nickName := cbReq.Nickname.Value - groupMemberInfo := relation2.GroupMemberModel{} - groupMemberInfo.UserID = req.UserID - groupMemberInfo.GroupID = req.GroupID - if nickName == "" { - userNickname, err := relation.GetUserNameByUserID(groupMemberInfo.UserID) + return &pbGroup.SetGroupMemberNicknameResp{}, nil +} + +func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbGroup.SetGroupMemberInfoReq) (*pbGroup.SetGroupMemberInfoResp, error) { + resp := &pbGroup.SetGroupMemberInfoResp{} + if req.RoleLevel != nil && req.RoleLevel.Value == constant.GroupOwner { + return nil, constant.ErrNoPermission.Wrap("set group owner") + } + group, err := s.GroupInterface.TakeGroup(ctx, req.GroupID) + if err != nil { + return nil, err + } + if group.Status == constant.GroupStatusDismissed { + return nil, constant.ErrArgs.Wrap("group status is dismissed") + } + member, err := s.GroupInterface.TakeGroupMember(ctx, req.GroupID, req.UserID) + if err != nil { + return nil, err + } + if tracelog.GetOpUserID(ctx) == req.UserID { + if req.RoleLevel != nil { + return nil, constant.ErrArgs.Wrap("update role level") + } + } else if !token_verify.IsAppManagerUid(ctx) { + opMember, err := s.GroupInterface.TakeGroupMember(ctx, req.GroupID, tracelog.GetOpUserID(ctx)) if err != nil { return nil, err } - groupMemberInfo.Nickname = userNickname - } else { - groupMemberInfo.Nickname = nickName + if opMember.RoleLevel <= member.RoleLevel { + return nil, constant.ErrNoPermission.Wrap(fmt.Sprintf("self RoleLevel %d target %d", opMember.RoleLevel, member.RoleLevel)) + } } - - if err := rocksCache.DelGroupMemberInfoFromCache(ctx, req.GroupID, req.UserID); err != nil { + if err := CallbackBeforeSetGroupMemberInfo(ctx, req); err != nil { return nil, err } - - if err := relation.UpdateGroupMemberInfo(groupMemberInfo); err != nil { + if err := s.GroupInterface.UpdateGroupMember(ctx, req.GroupID, req.UserID, UpdateGroupMemberMap(req)); err != nil { return nil, err } chat.GroupMemberInfoSetNotification(tracelog.GetOperationID(ctx), tracelog.GetOpUserID(ctx), req.GroupID, req.UserID) return resp, nil } -func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbGroup.SetGroupMemberInfoReq) (*pbGroup.SetGroupMemberInfoResp, error) { - resp := &pbGroup.SetGroupMemberInfoResp{} - - if err := rocksCache.DelGroupMemberInfoFromCache(ctx, req.GroupID, req.UserID); err != nil { - return nil, err - } - if err := CallbackBeforeSetGroupMemberInfo(ctx, req); err != nil { - return nil, err - } - groupMember := relation2.GroupMemberModel{ - GroupID: req.GroupID, - UserID: req.UserID, - } - m := make(map[string]interface{}) - if req.RoleLevel != nil { - m["role_level"] = req.RoleLevel.Value - } - if req.FaceURL != nil { - m["user_group_face_url"] = req.FaceURL.Value - } - if req.Nickname != nil { - m["nickname"] = req.Nickname.Value - } - if req.Ex != nil { - m["ex"] = req.Ex.Value - } else { - m["ex"] = nil - } - if err := relation.UpdateGroupMemberInfoByMap(groupMember, m); err != nil { - return nil, err - } - if req.RoleLevel != nil { - switch req.RoleLevel.Value { - case constant.GroupOrdinaryUsers: - //msg.GroupMemberRoleLevelChangeNotification(req.OperationID, req.OpUserID, req.GroupID, req.UserID, constant.GroupMemberSetToOrdinaryUserNotification) - chat.GroupMemberInfoSetNotification(tracelog.GetOperationID(ctx), tracelog.GetOpUserID(ctx), req.GroupID, req.UserID) - case constant.GroupAdmin, constant.GroupOwner: - //msg.GroupMemberRoleLevelChangeNotification(req.OperationID, req.OpUserID, req.GroupID, req.UserID, constant.GroupMemberSetToAdminNotification) - chat.GroupMemberInfoSetNotification(tracelog.GetOperationID(ctx), tracelog.GetOpUserID(ctx), req.GroupID, req.UserID) - } - } else { - chat.GroupMemberInfoSetNotification(tracelog.GetOperationID(ctx), tracelog.GetOpUserID(ctx), req.GroupID, req.UserID) - } - return resp, nil -} - func (s *groupServer) GetGroupAbstractInfo(ctx context.Context, req *pbGroup.GetGroupAbstractInfoReq) (*pbGroup.GetGroupAbstractInfoResp, error) { resp := &pbGroup.GetGroupAbstractInfoResp{} - - hashCode, err := rocksCache.GetGroupMemberListHashFromCache(ctx, req.GroupID) + if len(req.GroupIDs) == 0 { + return nil, constant.ErrArgs.Wrap("groupIDs empty") + } + if utils.Duplicate(req.GroupIDs) { + return nil, constant.ErrArgs.Wrap("groupIDs duplicate") + } + groups, err := s.GroupInterface.FindGroup(ctx, req.GroupIDs) if err != nil { return nil, err } - resp.GroupMemberListHash = hashCode - num, err := rocksCache.GetGroupMemberNumFromCache(ctx, req.GroupID) + numMap, err := s.GroupInterface.MapGroupMemberNum(ctx, req.GroupIDs) if err != nil { return nil, err } - resp.GroupMemberNumber = int32(num) + hashMap, err := s.GroupInterface.MapGroupHash(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]) + }) return resp, nil } -func (s *groupServer) DelGroupAndUserCache(ctx context.Context, groupID string, userIDList []string) error { - operationID := tracelog.GetOperationID(ctx) - if groupID != "" { - etcdConn, err := getcdv3.GetConn(ctx, config.Config.RpcRegisterName.OpenImCacheName) - if err != nil { - return err - } - cacheClient := pbCache.NewCacheClient(etcdConn) - cacheResp, err := cacheClient.DelGroupMemberIDListFromCache(context.Background(), &pbCache.DelGroupMemberIDListFromCacheReq{ - GroupID: groupID, - OperationID: operationID, - }) - if err != nil { - log.NewError(operationID, "DelGroupMemberIDListFromCache rpc call failed ", err.Error()) - return utils.Wrap(err, "") - } - err = constant.CommonResp2Err(cacheResp.CommonResp) - err = rocksCache.DelGroupMemberListHashFromCache(ctx, groupID) - if err != nil { - log.NewError(operationID, utils.GetSelfFuncName(), groupID, err.Error()) - return utils.Wrap(err, "") - } - err = rocksCache.DelGroupMemberNumFromCache(ctx, groupID) - if err != nil { - log.NewError(operationID, utils.GetSelfFuncName(), err.Error(), groupID) - return utils.Wrap(err, "") - } +func (s *groupServer) GetUserInGroupMembers(ctx context.Context, req *pbGroup.GetUserInGroupMembersReq) (*pbGroup.GetUserInGroupMembersResp, error) { + resp := &pbGroup.GetUserInGroupMembersResp{} + if len(req.GroupIDs) == 0 { + return nil, constant.ErrArgs.Wrap("groupIDs empty") } - if userIDList != nil { - for _, userID := range userIDList { - err := rocksCache.DelJoinedGroupIDListFromCache(ctx, userID) - if err != nil { - log.NewError(operationID, utils.GetSelfFuncName(), err.Error()) - return utils.Wrap(err, "") - } - } + members, err := s.GroupInterface.FindGroupMember(ctx, req.UserID, req.GroupIDs) + if err != nil { + return nil, err } - return nil + resp.Members = utils.Slice(members, func(e *relation2.GroupMemberModel) *open_im_sdk.GroupMemberFullInfo { + return DbToPbGroupMembersCMSResp(e) + }) + return resp, nil } diff --git a/internal/rpc/group/super_group.go b/internal/rpc/group/super_group.go index 63a2ed058..f462b3f50 100644 --- a/internal/rpc/group/super_group.go +++ b/internal/rpc/group/super_group.go @@ -1,68 +1,64 @@ package group import ( - rocksCache "Open_IM/pkg/common/db/rocks_cache" - "Open_IM/pkg/common/log" - cp "Open_IM/pkg/common/utils" + "Open_IM/pkg/common/constant" + "Open_IM/pkg/common/db/table/relation" pbGroup "Open_IM/pkg/proto/group" - commonPb "Open_IM/pkg/proto/sdk_ws" + sdk_ws "Open_IM/pkg/proto/sdk_ws" "Open_IM/pkg/utils" "context" - - "github.com/go-redis/redis/v8" ) func (s *groupServer) GetJoinedSuperGroupList(ctx context.Context, req *pbGroup.GetJoinedSuperGroupListReq) (*pbGroup.GetJoinedSuperGroupListResp, error) { - log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String()) - resp := &pbGroup.GetJoinedSuperGroupListResp{CommonResp: &commonPb.CommonResp{}} - groupIDList, err := rocksCache.GetJoinedSuperGroupListFromCache(ctx, req.UserID) + resp := &pbGroup.GetJoinedSuperGroupListResp{} + total, groupIDs, err := s.GroupInterface.FindJoinSuperGroup(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber) if err != nil { - if err == redis.Nil { - log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetSuperGroupByUserID nil ", err.Error(), req.UserID) - return resp, nil - } - log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetSuperGroupByUserID failed ", err.Error(), req.UserID) - //resp.CommonResp.ErrCode = constant.ErrDB.ErrCode - //resp.CommonResp.ErrMsg = constant.ErrDB.ErrMsg + return nil, err + } + resp.Total = total + if len(groupIDs) == 0 { return resp, nil } - for _, groupID := range groupIDList { - groupInfoFromCache, err := rocksCache.GetGroupInfoFromCache(ctx, groupID) - if err != nil { - log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetGroupInfoByGroupID failed", groupID, err.Error()) - continue - } - groupInfo := &commonPb.GroupInfo{} - if err := utils.CopyStructFields(groupInfo, groupInfoFromCache); err != nil { - log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error()) - } - groupMemberIDList, err := rocksCache.GetGroupMemberIDListFromCache(ctx, groupID) - if err != nil { - log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetSuperGroup failed", groupID, err.Error()) - continue - } - groupInfo.MemberCount = uint32(len(groupMemberIDList)) - resp.GroupList = append(resp.GroupList, groupInfo) + numMap, err := s.GroupInterface.MapSuperGroupMemberNum(ctx, groupIDs) + if err != nil { + return nil, err } - log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String()) + ownerIdMap, err := s.GroupInterface.MapGroupOwnerUserID(ctx, groupIDs) + if err != nil { + return nil, err + } + groups, err := s.GroupInterface.FindGroup(ctx, groupIDs) + if err != nil { + return nil, err + } + groupMap := utils.SliceToMap(groups, func(e *relation.GroupModel) string { + return e.GroupID + }) + resp.Groups = utils.Slice(groupIDs, func(groupID string) *sdk_ws.GroupInfo { + return DbToPbGroupInfo(groupMap[groupID], ownerIdMap[groupID], numMap[groupID]) + }) return resp, nil } func (s *groupServer) GetSuperGroupsInfo(ctx context.Context, req *pbGroup.GetSuperGroupsInfoReq) (resp *pbGroup.GetSuperGroupsInfoResp, err error) { - log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String()) - resp = &pbGroup.GetSuperGroupsInfoResp{CommonResp: &commonPb.CommonResp{}} - groupsInfoList := make([]*commonPb.GroupInfo, 0) - for _, groupID := range req.GroupIDList { - groupInfoFromRedis, err := rocksCache.GetGroupInfoFromCache(ctx, groupID) - if err != nil { - log.NewError(req.OperationID, "GetGroupInfoByGroupID failed ", err.Error(), groupID) - continue - } - var groupInfo commonPb.GroupInfo - cp.GroupDBCopyOpenIM(&groupInfo, groupInfoFromRedis) - groupsInfoList = append(groupsInfoList, &groupInfo) + resp = &pbGroup.GetSuperGroupsInfoResp{} + if len(req.GroupIDs) == 0 { + return nil, constant.ErrArgs.Wrap("groupIDs empty") } - resp.GroupInfoList = groupsInfoList - log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String()) + groups, err := s.GroupInterface.FindGroup(ctx, req.GroupIDs) + if err != nil { + return nil, err + } + numMap, err := s.GroupInterface.MapSuperGroupMemberNum(ctx, req.GroupIDs) + if err != nil { + return nil, err + } + ownerIdMap, err := s.GroupInterface.MapGroupOwnerUserID(ctx, req.GroupIDs) + if err != nil { + return nil, err + } + resp.GroupInfos = utils.Slice(groups, func(e *relation.GroupModel) *sdk_ws.GroupInfo { + return DbToPbGroupInfo(e, ownerIdMap[e.GroupID], numMap[e.GroupID]) + }) 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/internal/rpc/msg/conversation_notification.go b/internal/rpc/msg/conversation_notification.go index 22e1dedc7..a62d48d4e 100644 --- a/internal/rpc/msg/conversation_notification.go +++ b/internal/rpc/msg/conversation_notification.go @@ -6,6 +6,7 @@ import ( "Open_IM/pkg/common/log" open_im_sdk "Open_IM/pkg/proto/sdk_ws" "Open_IM/pkg/utils" + "context" "github.com/golang/protobuf/jsonpb" "github.com/golang/protobuf/proto" ) @@ -59,7 +60,7 @@ func ConversationSetPrivateNotification(operationID, sendID, recvID string, isPr } // 会话改变 -func ConversationChangeNotification(operationID, userID string) { +func ConversationChangeNotification(ctx context.Context, userID string) { log.NewInfo(operationID, utils.GetSelfFuncName()) ConversationChangedTips := &open_im_sdk.ConversationUpdateTips{ UserID: userID, diff --git a/pkg/common/db/cache/conversation.go b/pkg/common/db/cache/conversation.go index df39a342c..28493d5a3 100644 --- a/pkg/common/db/cache/conversation.go +++ b/pkg/common/db/cache/conversation.go @@ -13,18 +13,22 @@ import ( "time" ) -const ( - conversationKey = "CONVERSATION:" - conversationIDsKey = "CONVERSATION_IDS:" - recvMsgOptKey = "RECV_MSG_OPT:" - superGroupRecvMsgNotNotifyUserIDsKey = "SUPER_GROUP_RECV_MSG_NOT_NOTIFY_USER_IDS:" - conversationExpireTime = time.Second * 60 * 60 * 12 -) +type DBFun func() (string, error) -type ConversationCache struct { - conversationDB *relation.ConversationGorm - expireTime time.Duration - rcClient *rockscache.Client +type ConversationCache interface { + GetUserConversationIDListFromCache(userID string, fn DBFun) ([]string, error) + DelUserConversationIDListFromCache(userID string) error + GetConversationFromCache(ownerUserID, conversationID string, fn DBFun) (*table.ConversationModel, error) + GetConversationsFromCache(ownerUserID string, conversationIDList []string, fn DBFun) ([]*table.ConversationModel, error) + GetUserAllConversationList(ownerUserID string, fn DBFun) ([]*table.ConversationModel, error) + DelConversationFromCache(ownerUserID, conversationID string) error +} +type ConversationRedis struct { + rcClient *rockscache.Client +} + +func NewConversationRedis(rcClient *rockscache.Client) *ConversationRedis { + return &ConversationRedis{rcClient: rcClient} } func NewConversationCache(rdb redis.UniversalClient, conversationDB *relation.ConversationGorm, options rockscache.Options) *ConversationCache { diff --git a/pkg/common/db/controller/conversation.go b/pkg/common/db/controller/conversation.go new file mode 100644 index 000000000..3ed221c45 --- /dev/null +++ b/pkg/common/db/controller/conversation.go @@ -0,0 +1,119 @@ +package controller + +import ( + "Open_IM/pkg/common/db/cache" + "Open_IM/pkg/common/db/relation" + "Open_IM/pkg/common/db/table" + "context" +) + +type ConversationInterface interface { + //GetUserIDExistConversation 获取拥有该会话的的用户ID列表 + GetUserIDExistConversation(ctx context.Context, userIDList []string, conversationID string) ([]string, error) + //UpdateUserConversationFiled 更新用户该会话的属性信息 + UpdateUsersConversationFiled(ctx context.Context, UserIDList []string, conversationID string, args map[string]interface{}) error + //CreateConversation 创建一批新的会话 + CreateConversation(ctx context.Context, conversations []*table.ConversationModel) error + //SyncPeerUserPrivateConversation 同步对端私聊会话内部保证事务操作 + SyncPeerUserPrivateConversationTx(ctx context.Context, conversation *table.ConversationModel) error + //FindConversations 根据会话ID获取某个用户的多个会话 + FindConversations(ctx context.Context, ownerUserID string, conversationID []string) ([]*table.ConversationModel, error) + //GetUserAllConversation 获取一个用户在服务器上所有的会话 + GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*table.ConversationModel, error) + //SetUserConversations 设置用户多个会话属性,如果会话不存在则创建,否则更新,内部保证原子性 + SetUserConversations(ctx context.Context, ownerUserID string, conversations []*table.ConversationModel) error +} +type ConversationController struct { + database ConversationDataBaseInterface +} + +func NewConversationController(database ConversationDataBaseInterface) *ConversationController { + return &ConversationController{database: database} +} + +func (c *ConversationController) GetUserIDExistConversation(ctx context.Context, userIDList []string, conversationID string) ([]string, error) { + return c.database.GetUserIDExistConversation(ctx, userIDList, conversationID) +} + +func (c ConversationController) UpdateUsersConversationFiled(ctx context.Context, UserIDList []string, conversationID string, args map[string]interface{}) error { + panic("implement me") +} + +func (c ConversationController) CreateConversation(ctx context.Context, conversations []*table.ConversationModel) error { + panic("implement me") +} + +func (c ConversationController) SyncPeerUserPrivateConversationTx(ctx context.Context, conversation *table.ConversationModel) error { + panic("implement me") +} + +func (c ConversationController) FindConversations(ctx context.Context, ownerUserID string, conversationID []string) ([]*table.ConversationModel, error) { + panic("implement me") +} + +func (c ConversationController) GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*table.ConversationModel, error) { + panic("implement me") +} +func (c ConversationController) SetUserConversations(ctx context.Context, ownerUserID string, conversations []*table.ConversationModel) error { + panic("implement me") +} + +var _ ConversationInterface = (*ConversationController)(nil) + +type ConversationDataBaseInterface interface { + //GetUserIDExistConversation 获取拥有该会话的的用户ID列表 + GetUserIDExistConversation(ctx context.Context, userIDList []string, conversationID string) ([]string, error) + //UpdateUserConversationFiled 更新用户该会话的属性信息 + UpdateUsersConversationFiled(ctx context.Context, UserIDList []string, conversationID string, args map[string]interface{}) error + //CreateConversation 创建一批新的会话 + CreateConversation(ctx context.Context, conversations []*table.ConversationModel) error + //SyncPeerUserPrivateConversation 同步对端私聊会话内部保证事务操作 + SyncPeerUserPrivateConversationTx(ctx context.Context, conversation *table.ConversationModel) error + //FindConversations 根据会话ID获取某个用户的多个会话 + FindConversations(ctx context.Context, ownerUserID string, conversationID []string) ([]*table.ConversationModel, error) + //GetUserAllConversation 获取一个用户在服务器上所有的会话 + GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*table.ConversationModel, error) + //SetUserConversations 设置用户多个会话属性,如果会话不存在则创建,否则更新,内部保证原子性 + SetUserConversations(ctx context.Context, ownerUserID string, conversations []*table.ConversationModel) error +} +type ConversationDataBase struct { + db relation.Conversation + cache cache.ConversationCache +} + +func (c ConversationDataBase) GetUserIDExistConversation(ctx context.Context, userIDList []string, conversationID string) ([]string, error) { + panic("implement me") +} + +func (c ConversationDataBase) UpdateUsersConversationFiled(ctx context.Context, UserIDList []string, conversationID string, args map[string]interface{}) error { + panic("implement me") +} + +func (c ConversationDataBase) CreateConversation(ctx context.Context, conversations []*table.ConversationModel) error { + panic("implement me") +} + +func (c ConversationDataBase) SyncPeerUserPrivateConversationTx(ctx context.Context, conversation *table.ConversationModel) error { + panic("implement me") +} + +func (c ConversationDataBase) FindConversations(ctx context.Context, ownerUserID string, conversationID []string) ([]*table.ConversationModel, error) { + panic("implement me") +} + +func (c ConversationDataBase) GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*table.ConversationModel, error) { + panic("implement me") +} + +func (c ConversationDataBase) SetUserConversations(ctx context.Context, ownerUserID string, conversations []*table.ConversationModel) error { + panic("implement me") +} + +func NewConversationDataBase(db relation.Conversation, cache cache.ConversationCache) *ConversationDataBase { + return &ConversationDataBase{db: db, cache: cache} +} + +//func NewConversationController(db *gorm.DB, rdb redis.UniversalClient) ConversationInterface { +// groupController := &ConversationController{database: newGroupDatabase(db, rdb, mgoClient)} +// return groupController +//} diff --git a/pkg/common/db/controller/friend.go b/pkg/common/db/controller/friend.go index 6fb764887..04bc180dd 100644 --- a/pkg/common/db/controller/friend.go +++ b/pkg/common/db/controller/friend.go @@ -2,8 +2,8 @@ package controller import ( "Open_IM/pkg/common/constant" - "Open_IM/pkg/common/db/relation" - "Open_IM/pkg/common/db/table" + relation1 "Open_IM/pkg/common/db/relation" + "Open_IM/pkg/common/db/table/relation" "Open_IM/pkg/utils" "context" "gorm.io/gorm" @@ -15,25 +15,25 @@ type FriendInterface interface { // AddFriendRequest 增加或者更新好友申请 AddFriendRequest(ctx context.Context, fromUserID, toUserID string, reqMsg string, ex string) (err error) // BecomeFriend 先判断是否在好友表,如果在则不插入 - BecomeFriend(ctx context.Context, friends []*table.FriendModel, revFriends []*table.FriendModel) (err error) + BecomeFriend(ctx context.Context, friends []*relation.FriendModel, revFriends []*relation.FriendModel) (err error) // RefuseFriendRequest 拒绝好友申请 - RefuseFriendRequest(ctx context.Context, friendRequest *table.FriendRequestModel) (err error) + RefuseFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) // AgreeFriendRequest 同意好友申请 - AgreeFriendRequest(ctx context.Context, friendRequest *table.FriendRequestModel) (err error) + AgreeFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) // Delete 删除好友 Delete(ctx context.Context, ownerUserID string, friendUserIDs string) (err error) // UpdateRemark 更新好友备注 UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) // FindOwnerFriends 获取ownerUserID的好友列表 - FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (friends []*table.FriendModel, total int64, err error) + FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (friends []*relation.FriendModel, total int64, err error) // FindInWhoseFriends friendUserID在哪些人的好友列表中 - FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32) (friends []*table.FriendModel, total int64, err error) + FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32) (friends []*relation.FriendModel, total int64, err error) // FindFriendRequestFromMe 获取我发出去的好友申请 - FindFriendRequestFromMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*table.FriendRequestModel, total int64, err error) + FindFriendRequestFromMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*relation.FriendRequestModel, total int64, err error) // FindFriendRequestToMe 获取我收到的的好友申请 - FindFriendRequestToMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*table.FriendRequestModel, total int64, err error) + FindFriendRequestToMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*relation.FriendRequestModel, total int64, err error) // FindFriends 获取某人指定好友的信息 如果有一个不存在也返回错误 - FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*table.FriendModel, err error) + FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*relation.FriendModel, err error) } type FriendController struct { @@ -55,17 +55,17 @@ func (f *FriendController) AddFriendRequest(ctx context.Context, fromUserID, toU } // BecomeFriend 先判断是否在好友表,如果在则不插入 -func (f *FriendController) BecomeFriend(ctx context.Context, ownerUserID string, friends []*table.FriendModel) (err error) { +func (f *FriendController) BecomeFriend(ctx context.Context, ownerUserID string, friends []*relation.FriendModel) (err error) { return f.database.BecomeFriend(ctx, ownerUserID, friends) } // RefuseFriendRequest 拒绝好友申请 -func (f *FriendController) RefuseFriendRequest(ctx context.Context, friendRequest *table.FriendRequestModel) (err error) { +func (f *FriendController) RefuseFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) { return f.database.RefuseFriendRequest(ctx, friendRequest) } // AgreeFriendRequest 同意好友申请 -func (f *FriendController) AgreeFriendRequest(ctx context.Context, friendRequest *table.FriendRequestModel) (err error) { +func (f *FriendController) AgreeFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) { return f.database.AgreeFriendRequest(ctx, friendRequest) } @@ -80,27 +80,27 @@ func (f *FriendController) UpdateRemark(ctx context.Context, ownerUserID, friend } // FindOwnerFriends 获取ownerUserID的好友列表 -func (f *FriendController) FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (friends []*table.FriendModel, total int64, err error) { +func (f *FriendController) FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (friends []*relation.FriendModel, total int64, err error) { return f.database.FindOwnerFriends(ctx, ownerUserID, pageNumber, showNumber) } // FindInWhoseFriends friendUserID在哪些人的好友列表中 -func (f *FriendController) FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32) (friends []*table.FriendModel, total int64, err error) { +func (f *FriendController) FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32) (friends []*relation.FriendModel, total int64, err error) { return f.database.FindInWhoseFriends(ctx, friendUserID, pageNumber, showNumber) } // FindFriendRequestFromMe 获取我发出去的好友申请 -func (f *FriendController) FindFriendRequestFromMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*table.FriendRequestModel, total int64, err error) { +func (f *FriendController) FindFriendRequestFromMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*relation.FriendRequestModel, total int64, err error) { return f.database.FindFriendRequestFromMe(ctx, userID, pageNumber, showNumber) } // FindFriendRequestToMe 获取我收到的的好友申请 -func (f *FriendController) FindFriendRequestToMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*table.FriendRequestModel, total int64, err error) { +func (f *FriendController) FindFriendRequestToMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*relation.FriendRequestModel, total int64, err error) { return f.database.FindFriendRequestToMe(ctx, userID, pageNumber, showNumber) } // FindFriends 获取某人指定好友的信息 -func (f *FriendController) FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*table.FriendModel, err error) { +func (f *FriendController) FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*relation.FriendModel, err error) { return f.database.FindFriends(ctx, ownerUserID, friendUserIDs) } @@ -111,34 +111,34 @@ type FriendDatabaseInterface interface { // AddFriendRequest 增加或者更新好友申请 AddFriendRequest(ctx context.Context, fromUserID, toUserID string, reqMsg string, ex string) (err error) // BecomeFriend 先判断是否在好友表,如果在则不插入 - BecomeFriend(ctx context.Context, ownerUserID string, friends []*table.FriendModel) (err error) + BecomeFriend(ctx context.Context, ownerUserID string, friends []*relation.FriendModel) (err error) // RefuseFriendRequest 拒绝好友申请 - RefuseFriendRequest(ctx context.Context, friendRequest *table.FriendRequestModel) (err error) + RefuseFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) // AgreeFriendRequest 同意好友申请 - AgreeFriendRequest(ctx context.Context, friendRequest *table.FriendRequestModel) (err error) + AgreeFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) // Delete 删除好友 Delete(ctx context.Context, ownerUserID string, friendUserIDs string) (err error) // UpdateRemark 更新好友备注 UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) // FindOwnerFriends 获取ownerUserID的好友列表 - FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (friends []*table.FriendModel, total int64, err error) + FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (friends []*relation.FriendModel, total int64, err error) // FindInWhoseFriends friendUserID在哪些人的好友列表中 - FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32) (friends []*table.FriendModel, total int64, err error) + FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32) (friends []*relation.FriendModel, total int64, err error) // FindFriendRequestFromMe 获取我发出去的好友申请 - FindFriendRequestFromMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*table.FriendRequestModel, total int64, err error) + FindFriendRequestFromMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*relation.FriendRequestModel, total int64, err error) // FindFriendRequestToMe 获取我收到的的好友申请 - FindFriendRequestToMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*table.FriendRequestModel, total int64, err error) + FindFriendRequestToMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*relation.FriendRequestModel, total int64, err error) // FindFriends 获取某人指定好友的信息 - FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*table.FriendModel, err error) + FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*relation.FriendModel, err error) } type FriendDatabase struct { - friend *relation.FriendGorm - friendRequest *relation.FriendRequestGorm + friend *relation1.FriendGorm + friendRequest *relation1.FriendRequestGorm } func NewFriendDatabase(db *gorm.DB) *FriendDatabase { - return &FriendDatabase{friend: relation.NewFriendGorm(db), friendRequest: relation.NewFriendRequestGorm(db)} + return &FriendDatabase{friend: relation1.NewFriendGorm(db), friendRequest: relation1.NewFriendRequestGorm(db)} } // CheckIn 检查user2是否在user1的好友列表中(inUser1Friends==true) 检查user1是否在user2的好友列表中(inUser2Friends==true) @@ -157,11 +157,31 @@ func (f *FriendDatabase) CheckIn(ctx context.Context, userID1, userID2 string) ( // AddFriendRequest 增加或者更新好友申请 func (f *FriendDatabase) AddFriendRequest(ctx context.Context, fromUserID, toUserID string, reqMsg string, ex string) (err error) { - + return f.friendRequest.DB.Transaction(func(tx *gorm.DB) error { + fq, err := f.friendRequest.Find(ctx, fromUserID, toUserID, tx) + if err != nil { + return err + } + if fq != nil { // + m := make(map[string]interface{}, 1) + m["handle_result"] = 0 + m["handle_msg"] = "" + m["req_msg"] = reqMsg + m["ex"] = ex + if err := f.friendRequest.UpdateByMap(ctx, fromUserID, toUserID, m, tx); err != nil { + return err + } + } else { + if err := f.friendRequest.Create(ctx, []*relation.FriendRequestModel{&relation.FriendRequestModel{FromUserID: fromUserID, ToUserID: toUserID, ReqMsg: reqMsg, Ex: ex}}, tx); err != nil { + return err + } + } + return nil + }) } // BecomeFriend 先判断是否在好友表,如果在则不插入 -func (f *FriendDatabase) BecomeFriend(ctx context.Context, ownerUserID string, friends []*table.FriendModel) (err error) { +func (f *FriendDatabase) BecomeFriend(ctx context.Context, ownerUserID string, friends []*relation.FriendModel) (err error) { return f.friend.DB.Transaction(func(tx *gorm.DB) error { //先find 找出重复的 去掉重复的 friendUserIDs := make([]string, 0, len(friends)) @@ -173,7 +193,7 @@ func (f *FriendDatabase) BecomeFriend(ctx context.Context, ownerUserID string, f return err } fs1 = append(fs1, friends...) - fs11 := utils.DistinctAny(fs1, func(e *table.FriendModel) string { + fs11 := utils.DistinctAny(fs1, func(e *relation.FriendModel) string { return utils.UniqueJoin(e.OwnerUserID, e.FriendUserID) }) err = f.friend.Create(ctx, fs11, tx) @@ -185,9 +205,9 @@ func (f *FriendDatabase) BecomeFriend(ctx context.Context, ownerUserID string, f return err } for _, v := range friends { - fs2 = append(fs2, &table.FriendModel{OwnerUserID: v.FriendUserID, FriendUserID: ownerUserID}) + fs2 = append(fs2, &relation.FriendModel{OwnerUserID: v.FriendUserID, FriendUserID: ownerUserID}) } - fs22 := utils.DistinctAny(fs2, func(e *table.FriendModel) string { + fs22 := utils.DistinctAny(fs2, func(e *relation.FriendModel) string { return utils.UniqueJoin(e.OwnerUserID, e.FriendUserID) }) err = f.friend.Create(ctx, fs22, tx) @@ -199,9 +219,9 @@ func (f *FriendDatabase) BecomeFriend(ctx context.Context, ownerUserID string, f } // RefuseFriendRequest 拒绝好友申请 -func (f *FriendDatabase) RefuseFriendRequest(ctx context.Context, friendRequest *table.FriendRequestModel) (err error) { +func (f *FriendDatabase) RefuseFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) { friendRequest.HandleResult = constant.FriendResponseRefuse - err = f.friendRequest.Update(ctx, []*table.FriendRequestModel{friendRequest}) + err = f.friendRequest.Update(ctx, []*relation.FriendRequestModel{friendRequest}) if err != nil { return err } @@ -209,7 +229,7 @@ func (f *FriendDatabase) RefuseFriendRequest(ctx context.Context, friendRequest } // AgreeFriendRequest 同意好友申请 -func (f *FriendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest *table.FriendRequestModel) (err error) { +func (f *FriendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) { return f.friend.DB.Transaction(func(tx *gorm.DB) error { //先find 找出重复的 去掉重复的 fs1, err := f.friend.FindFriends(ctx, friendRequest.FromUserID, []string{friendRequest.ToUserID}, tx) @@ -217,8 +237,8 @@ func (f *FriendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest * return err } if len(fs1) == 0 { - err = f.friend.Create(ctx, []*table.FriendModel{ - &table.FriendModel{ + err = f.friend.Create(ctx, []*relation.FriendModel{ + &relation.FriendModel{ OwnerUserID: friendRequest.FromUserID, FriendUserID: friendRequest.ToUserID, OperatorUserID: friendRequest.ToUserID, @@ -230,8 +250,8 @@ func (f *FriendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest * } fs2, err := f.friend.FindReversalFriends(ctx, friendRequest.ToUserID, []string{friendRequest.FromUserID}, tx) if len(fs2) == 0 { - err = f.friend.Create(ctx, []*table.FriendModel{ - &table.FriendModel{ + err = f.friend.Create(ctx, []*relation.FriendModel{ + &relation.FriendModel{ OwnerUserID: friendRequest.ToUserID, FriendUserID: friendRequest.FromUserID, OperatorUserID: friendRequest.ToUserID, @@ -242,7 +262,7 @@ func (f *FriendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest * } } friendRequest.HandleResult = constant.FriendResponseAgree - err = f.friendRequest.Update(ctx, []*table.FriendRequestModel{friendRequest}, tx) + err = f.friendRequest.Update(ctx, []*relation.FriendRequestModel{friendRequest}, tx) if err != nil { return err } @@ -261,27 +281,27 @@ func (f *FriendDatabase) UpdateRemark(ctx context.Context, ownerUserID, friendUs } // FindOwnerFriends 获取ownerUserID的好友列表 -func (f *FriendDatabase) FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (friends []*table.FriendModel, total int64, err error) { +func (f *FriendDatabase) FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (friends []*relation.FriendModel, total int64, err error) { return f.friend.FindOwnerFriends(ctx, ownerUserID, pageNumber, showNumber) } // FindInWhoseFriends friendUserID在哪些人的好友列表中 -func (f *FriendDatabase) FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32) (friends []*table.FriendModel, total int64, err error) { +func (f *FriendDatabase) FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32) (friends []*relation.FriendModel, total int64, err error) { return f.friend.FindInWhoseFriends(ctx, friendUserID, pageNumber, showNumber) } // FindFriendRequestFromMe 获取我发出去的好友申请 -func (f *FriendDatabase) FindFriendRequestFromMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*table.FriendRequestModel, total int64, err error) { +func (f *FriendDatabase) FindFriendRequestFromMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*relation.FriendRequestModel, total int64, err error) { return f.friendRequest.FindFromUserID(ctx, userID, pageNumber, showNumber) } // FindFriendRequestToMe 获取我收到的的好友申请 -func (f *FriendDatabase) FindFriendRequestToMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*table.FriendRequestModel, total int64, err error) { +func (f *FriendDatabase) FindFriendRequestToMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*relation.FriendRequestModel, total int64, err error) { return f.friendRequest.FindToUserID(ctx, userID, pageNumber, showNumber) } // FindFriends 获取某人指定好友的信息 如果有一个不存在,也返回错误 -func (f *FriendDatabase) FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*table.FriendModel, err error) { +func (f *FriendDatabase) FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*relation.FriendModel, err error) { friends, err = f.friend.FindFriends(ctx, ownerUserID, friendUserIDs) if err != nil { return diff --git a/pkg/common/db/controller/group.go b/pkg/common/db/controller/group.go index 0a1cd5f77..f5931e0aa 100644 --- a/pkg/common/db/controller/group.go +++ b/pkg/common/db/controller/group.go @@ -1,10 +1,13 @@ package controller import ( + "Open_IM/pkg/common/constant" "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" + "Open_IM/pkg/utils" "context" "github.com/dtm-labs/rockscache" _ "github.com/dtm-labs/rockscache" @@ -14,29 +17,43 @@ import ( ) type GroupInterface interface { - FindGroupsByID(ctx context.Context, groupIDs []string) (groups []*relation2.GroupModel, err error) + // group + FindGroup(ctx context.Context, groupIDs []string) (groups []*relation2.GroupModel, err error) + SearchGroup(ctx context.Context, name string, pageNumber, showNumber int32) (int32, []*relation2.GroupModel, error) + TakeGroup(ctx context.Context, groupID string) (group *relation2.GroupModel, err error) + FindJoinedGroup(ctx context.Context, userID 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 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) - 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) - GetGroupMemberFilterList(ctx context.Context, groupID string, filter int32, begin int32, maxNumber int32) ([]*relation2.GroupModel, error) // relation.GetGroupMemberByGroupID(req.GroupID, req.Filter, req.NextSeq, 30) - FindGroupMembersByID(ctx context.Context, groupID string, userIDs []string) (groups []*relation2.GroupMemberModel, err error) - DelGroupMember(ctx context.Context, groupID string, userIDs []string) error - GetGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]int, error) - GetGroupOwnerUserID(ctx context.Context, groupIDs []string) (map[string]string, error) - GetGroupRecvApplicationList(ctx context.Context, userID string) ([]*relation2.GroupRequestModel, error) - + TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relation2.GroupMemberModel, err error) + FindGroupMember(ctx context.Context, groupID string, userIDs []string) ([]*relation2.GroupMemberModel, error) + FindGroupMemberAll(ctx context.Context, groupID string) ([]*relation2.GroupMemberModel, error) + FindGroupMemberFilterList(ctx context.Context, groupID string, filter int32, begin int32, maxNumber int32) ([]*relation2.GroupMemberModel, error) // relation.GetGroupMemberByGroupID(req.GroupID, req.Filter, req.NextSeq, 30) + SearchGroupMember(ctx context.Context, groupID, name string, pageNumber, showNumber int32) (int32, []*relation2.GroupMemberModel, error) + TakeGroupOwner(ctx context.Context, groupID string) (*relation2.GroupMemberModel, error) + FindGroupOwnerUser(ctx context.Context, groupID []string) ([]*relation2.GroupMemberModel, error) 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 + 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) + MapGroupOwnerUserID(ctx context.Context, groupIDs []string) (map[string]string, error) + TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string) error // 转让群 + UpdateGroupMember(ctx context.Context, groupID, userID string, data map[string]any) error - //mongo + CreateGroupRequest(ctx context.Context, requests []*relation2.GroupRequestModel) error + GetGroupRecvApplicationList(ctx context.Context, userID string) ([]*relation2.GroupRequestModel, error) // ? + TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relation2.GroupRequestModel, error) + FindUserGroupRequest(ctx context.Context, userID string, pageNumber, showNumber int32) (int32, []*relation2.GroupRequestModel, error) + // superGroup + TakeSuperGroup(ctx context.Context, groupID string) (superGroup *unrelation2.SuperGroupModel, err error) CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string) error - DelSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error + DeleteSuperGroup(ctx context.Context, groupID string) error + DeleteSuperGroupMember(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) + FindJoinSuperGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (total int32, groupIDs []string, err error) + MapSuperGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) } var _ GroupInterface = (*GroupController)(nil) @@ -45,82 +62,112 @@ type GroupController struct { database GroupDataBaseInterface } -func (g *GroupController) TakeGroupMemberByID(ctx context.Context, groupID string, userID string) (groupMember *relation2.GroupModel, err error) { +func (g *GroupController) FindGroup(ctx context.Context, groupIDs []string) (groups []*relation2.GroupModel, err error) { //TODO implement me panic("implement me") } -func (g *GroupController) FindGroupMembersByID(ctx context.Context, groupID string, userIDs []string) (groups []*relation2.GroupModel, err error) { +func (g *GroupController) SearchGroup(ctx context.Context, name string, pageNumber, showNumber int32) (int32, []*relation2.GroupModel, error) { //TODO implement me panic("implement me") } -func (g *GroupController) DelGroupMember(ctx context.Context, groupID string, userIDs []string) error { +func (g *GroupController) TakeGroup(ctx context.Context, groupID string) (group *relation2.GroupModel, err error) { //TODO implement me panic("implement me") } -func (g *GroupController) GetGroupRecvApplicationList(ctx context.Context, userID string) ([]*relation2.GroupRequestModel, error) { - /* - var groupRequestList []db.GroupRequest - memberList, err := GetGroupMemberListByUserID(userID) - if err != nil { - return nil, err - } - for _, v := range memberList { - if v.RoleLevel > constant.GroupOrdinaryUsers { - list, err := GetGroupRequestByGroupID(v.GroupID) - if err != nil { - // fmt.Println("111 GetGroupRequestByGroupID failed ", err.Error()) - continue - } - // fmt.Println("222 GetGroupRequestByGroupID ok ", list) - groupRequestList = append(groupRequestList, list...) - // fmt.Println("333 GetGroupRequestByGroupID ok ", groupRequestList) - } - } - return groupRequestList, nil - */ +func (g *GroupController) FindJoinedGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (int32, []*relation2.GroupModel, error) { //TODO implement me panic("implement me") } -func (g *GroupController) DelSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error { +func (g *GroupController) UpdateGroup(ctx context.Context, groupID string, data map[string]any) error { //TODO implement me panic("implement me") } -func (g *GroupController) GetJoinedGroupList(ctx context.Context, userID string) ([]*relation2.GroupModel, error) { +func (g *GroupController) DismissGroup(ctx context.Context, groupID string) error { //TODO implement me panic("implement me") } -func (g *GroupController) GetGroupMemberList(ctx context.Context, groupID string) ([]*relation2.GroupModel, error) { +func (g *GroupController) CreateGroup(ctx context.Context, groups []*relation2.GroupModel, groupMember []*relation2.GroupMemberModel) error { //TODO implement me panic("implement me") } -func (g *GroupController) GetGroupMemberListByUserID(ctx context.Context, groupID string, userIDs []string) ([]*relation2.GroupModel, error) { +func (g *GroupController) TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relation2.GroupMemberModel, err error) { //TODO implement me panic("implement me") } -func (g *GroupController) GetGroupMemberFilterList(ctx context.Context, groupID string, filter int32, begin int32, maxNumber int32) ([]*relation2.GroupModel, error) { +func (g *GroupController) FindGroupMember(ctx context.Context, groupID string, userIDs []string) ([]*relation2.GroupMemberModel, error) { //TODO implement me panic("implement me") } -func (g *GroupController) GetGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]int, error) { +func (g *GroupController) FindGroupMemberAll(ctx context.Context, groupID string) ([]*relation2.GroupMemberModel, error) { //TODO implement me panic("implement me") } -func (g *GroupController) GetGroupOwnerUserID(ctx context.Context, groupIDs []string) (map[string]string, error) { +func (g *GroupController) FindGroupMemberFilterList(ctx context.Context, groupID string, filter int32, begin int32, maxNumber int32) ([]*relation2.GroupMemberModel, error) { //TODO implement me panic("implement me") } -func (g *GroupController) CreateGroupMember(ctx context.Context, groupMember []*relation2.GroupModel) error { +func (g *GroupController) SearchGroupMember(ctx context.Context, groupID, name string, pageNumber, showNumber int32) (int32, []*relation2.GroupMemberModel, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) TakeGroupOwner(ctx context.Context, groupID string) (*relation2.GroupMemberModel, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) FindGroupOwnerUser(ctx context.Context, groupID []string) ([]*relation2.GroupMemberModel, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) CreateGroupMember(ctx context.Context, groupMember []*relation2.GroupMemberModel) error { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relation2.GroupMemberModel) error { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) MapGroupHash(ctx context.Context, groupIDs []string) (map[string]uint64, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]int, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) MapGroupOwnerUserID(ctx context.Context, groupIDs []string) (map[string]string, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string) error { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) UpdateGroupMember(ctx context.Context, groupID, userID string, data map[string]any) error { //TODO implement me panic("implement me") } @@ -130,49 +177,98 @@ func (g *GroupController) CreateGroupRequest(ctx context.Context, requests []*re panic("implement me") } +func (g *GroupController) GetGroupRecvApplicationList(ctx context.Context, userID string) ([]*relation2.GroupRequestModel, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relation2.GroupRequestModel, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) FindUserGroupRequest(ctx context.Context, userID string, pageNumber, showNumber int32) (int32, []*relation2.GroupRequestModel, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) TakeSuperGroup(ctx context.Context, groupID string) (superGroup *unrelation2.SuperGroupModel, err error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string) error { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) DeleteSuperGroup(ctx context.Context, groupID string) error { + //TODO implement me + panic("implement me") +} + +func (g *GroupController) DeleteSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error { + //TODO implement me + panic("implement me") +} + func (g *GroupController) AddUserToSuperGroup(ctx context.Context, groupID string, userIDs []string) error { //TODO implement me panic("implement me") } -func NewGroupController(db *gorm.DB, rdb redis.UniversalClient, mgoClient *mongo.Client) GroupInterface { - groupController := &GroupController{database: newGroupDatabase(db, rdb, mgoClient)} - return groupController +func (g *GroupController) FindJoinSuperGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (total int32, groupIDs []string, err error) { + //TODO implement me + panic("implement me") } -func (g *GroupController) FindGroupsByID(ctx context.Context, groupIDs []string) (groups []*relation2.GroupModel, err error) { - return g.database.FindGroupsByID(ctx, groupIDs) -} - -func (g *GroupController) CreateGroup(ctx context.Context, groups []*relation2.GroupModel, groupMember []*relation2.GroupModel) error { - return g.database.CreateGroup(ctx, groups, groupMember) -} - -func (g *GroupController) DeleteGroupByIDs(ctx context.Context, groupIDs []string) error { - return g.database.DeleteGroupByIDs(ctx, groupIDs) -} - -func (g *GroupController) TakeGroupByID(ctx context.Context, groupID string) (group *relation2.GroupModel, err error) { - return g.database.TakeGroupByID(ctx, groupID) -} - -func (g *GroupController) GetSuperGroupByID(ctx context.Context, groupID string) (superGroup *unrelation.SuperGroup, err error) { - return g.database.GetSuperGroupByID(ctx, groupID) -} - -func (g *GroupController) CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string) error { - return g.database.CreateSuperGroup(ctx, groupID, initMemberIDList) +func (g *GroupController) MapSuperGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) { + //TODO implement me + panic("implement me") } type GroupDataBaseInterface interface { - FindGroupsByID(ctx context.Context, groupIDs []string) (groups []*relation2.GroupModel, err error) - CreateGroup(ctx context.Context, groups []*relation2.GroupModel, groupMember []*relation2.GroupModel) error - DeleteGroupByIDs(ctx context.Context, groupIDs []string) error - TakeGroupByID(ctx context.Context, groupID string) (group *relation2.GroupModel, err error) - GetSuperGroupByID(ctx context.Context, groupID string) (superGroup *unrelation.SuperGroup, err error) + // group + FindGroup(ctx context.Context, groupIDs []string) (groups []*relation2.GroupModel, err error) + SearchGroup(ctx context.Context, name string, pageNumber, showNumber int32) (int32, []*relation2.GroupModel, error) + TakeGroup(ctx context.Context, groupID string) (group *relation2.GroupModel, err error) + FindJoinedGroup(ctx context.Context, userID 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 + CreateGroup(ctx context.Context, groups []*relation2.GroupModel, groupMember []*relation2.GroupMemberModel) error + TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relation2.GroupMemberModel, err error) + FindGroupMember(ctx context.Context, groupID string, userIDs []string) ([]*relation2.GroupMemberModel, error) + FindGroupMemberAll(ctx context.Context, groupID string) ([]*relation2.GroupMemberModel, error) + FindGroupMemberFilterList(ctx context.Context, groupID string, filter int32, begin int32, maxNumber int32) ([]*relation2.GroupMemberModel, error) // relation.GetGroupMemberByGroupID(req.GroupID, req.Filter, req.NextSeq, 30) + SearchGroupMember(ctx context.Context, groupID, name string, pageNumber, showNumber int32) (int32, []*relation2.GroupMemberModel, error) + TakeGroupOwner(ctx context.Context, groupID string) (*relation2.GroupMemberModel, error) + FindGroupOwnerUser(ctx context.Context, groupID []string) ([]*relation2.GroupMemberModel, error) + CreateGroupMember(ctx context.Context, groupMember []*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) + MapGroupOwnerUserID(ctx context.Context, groupIDs []string) (map[string]string, error) + TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string) error // 转让群 + UpdateGroupMember(ctx context.Context, groupID, userID string, data map[string]any) error + + CreateGroupRequest(ctx context.Context, requests []*relation2.GroupRequestModel) error + GetGroupRecvApplicationList(ctx context.Context, userID string) ([]*relation2.GroupRequestModel, error) // ? + TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relation2.GroupRequestModel, error) + FindUserGroupRequest(ctx context.Context, userID string, pageNumber, showNumber int32) (int32, []*relation2.GroupRequestModel, error) + // superGroup + TakeSuperGroup(ctx context.Context, groupID string) (superGroup *unrelation2.SuperGroupModel, 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 + AddUserToSuperGroup(ctx context.Context, groupID string, userIDs []string) error + FindJoinSuperGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (total int32, groupIDs []string, err error) + MapSuperGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) } +var _ *GroupDataBase = (GroupDataBaseInterface)(nil) + type GroupDataBase struct { groupDB *relation.GroupGorm groupMemberDB *relation.GroupMemberGorm @@ -205,82 +301,270 @@ func newGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, mgoClient *mongo.C return database } -func (g *GroupDataBase) FindGroupsByID(ctx context.Context, groupIDs []string) (groups []*relation2.GroupModel, err error) { - return g.cache.GetGroupsInfo(ctx, groupIDs) +//func (g *GroupDataBase) FindGroupsByID(ctx context.Context, groupIDs []string) (groups []*relation2.GroupModel, err error) { +// return g.cache.GetGroupsInfo(ctx, groupIDs) +//} +// +//func (g *GroupDataBase) CreateGroup(ctx context.Context, groups []*relation2.GroupModel, groupMembers []*relation2.GroupMemberModel) 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 +// } +// } +// if len(groupMembers) > 0 { +// if err := g.groupMemberDB.Create(ctx, groupMembers, tx); err != nil { +// return err +// } +// } +// return nil +// }) +//} +// +//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 { - return g.db.Transaction(func(tx *gorm.DB) error { - if len(groups) > 0 { + 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 } - } - if len(groupMembers) > 0 { - if err := g.groupMemberDB.Create(ctx, groupMembers, tx); err != nil { - return err - } - } - return nil - }) + 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) 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) TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relation2.GroupMemberModel, err error) { + return g.groupMemberDB.Take(ctx, groupID, userID) } -func (g *GroupDataBase) TakeGroupByID(ctx context.Context, groupID string) (group *relation2.GroupModel, err error) { - return g.cache.GetGroupInfo(ctx, groupID) +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) 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) FindGroupMemberAll(ctx context.Context, groupID string) ([]*relation2.GroupMemberModel, error) { + return g.groupMemberDB.FindGroupUser(ctx, []string{groupID}, nil, nil) } -func (g *GroupDataBase) GetJoinedGroupList(ctx context.Context, userID string) ([]*relation2.GroupModel, error) { +func (g *GroupDataBase) FindGroupMemberFilterList(ctx context.Context, groupID string, filter int32, begin int32, maxNumber int32) ([]*relation2.GroupMemberModel, error) { + //TODO implement me + panic("implement me") +} - return 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}) +} + +func (g *GroupDataBase) CreateGroupMember(ctx context.Context, groupMember []*relation2.GroupMemberModel) error { + //TODO implement me + panic("implement me") +} + +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") +} + +func (g *GroupDataBase) DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) MapGroupHash(ctx context.Context, groupIDs []string) (map[string]uint64, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]int, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) MapGroupOwnerUserID(ctx context.Context, groupIDs []string) (map[string]string, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string) error { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) UpdateGroupMember(ctx context.Context, groupID, userID string, data map[string]any) error { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) CreateGroupRequest(ctx context.Context, requests []*relation2.GroupRequestModel) error { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) GetGroupRecvApplicationList(ctx context.Context, userID string) ([]*relation2.GroupRequestModel, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relation2.GroupRequestModel, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) FindUserGroupRequest(ctx context.Context, userID string, pageNumber, showNumber int32) (int32, []*relation2.GroupRequestModel, error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) TakeSuperGroup(ctx context.Context, groupID string) (superGroup *unrelation2.SuperGroupModel, err error) { + //TODO implement me + panic("implement me") } 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) + //TODO implement me + panic("implement me") } -func (g *GroupDataBase) GetSuperGroupByID(ctx context.Context, groupID string) (superGroup *unrelation.SuperGroup, err error) { - return g.mongoDB.GetSuperGroup(ctx, groupID) +func (g *GroupDataBase) DeleteSuperGroup(ctx context.Context, groupID string) error { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) DeleteSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) AddUserToSuperGroup(ctx context.Context, groupID string, userIDs []string) error { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) FindJoinSuperGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (total int32, groupIDs []string, err error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupDataBase) MapSuperGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) { + //TODO implement me + panic("implement me") } diff --git a/pkg/common/db/relation/conversation_model.go b/pkg/common/db/relation/conversation_model.go index d8c730607..1071e26af 100644 --- a/pkg/common/db/relation/conversation_model.go +++ b/pkg/common/db/relation/conversation_model.go @@ -1,15 +1,35 @@ package relation import ( - "Open_IM/pkg/common/db/table/relation" "gorm.io/gorm" ) -type ConversationGorm struct { - DB *gorm.DB +var ConversationDB *gorm.DB + +//type Conversation struct { +// OwnerUserID string `gorm:"column:owner_user_id;primary_key;type:char(128)" json:"OwnerUserID"` +// ConversationID string `gorm:"column:conversation_id;primary_key;type:char(128)" json:"conversationID"` +// ConversationType int32 `gorm:"column:conversation_type" json:"conversationType"` +// UserID string `gorm:"column:user_id;type:char(64)" json:"userID"` +// GroupID string `gorm:"column:group_id;type:char(128)" json:"groupID"` +// RecvMsgOpt int32 `gorm:"column:recv_msg_opt" json:"recvMsgOpt"` +// UnreadCount int32 `gorm:"column:unread_count" json:"unreadCount"` +// DraftTextTime int64 `gorm:"column:draft_text_time" json:"draftTextTime"` +// IsPinned bool `gorm:"column:is_pinned" json:"isPinned"` +// IsPrivateChat bool `gorm:"column:is_private_chat" json:"isPrivateChat"` +// BurnDuration int32 `gorm:"column:burn_duration;default:30" json:"burnDuration"` +// GroupAtType int32 `gorm:"column:group_at_type" json:"groupAtType"` +// IsNotInGroup bool `gorm:"column:is_not_in_group" json:"isNotInGroup"` +// UpdateUnreadCountTime int64 `gorm:"column:update_unread_count_time" json:"updateUnreadCountTime"` +// AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"` +// Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"` +//} + +func (Conversation) TableName() string { + return "conversations" } -func SetConversation(conversation relation.ConversationModel) (bool, error) { +func SetConversation(conversation Conversation) (bool, error) { var isUpdate bool newConversation := conversation if ConversationDB.Model(&Conversation{}).Find(&newConversation).RowsAffected == 0 { @@ -73,7 +93,7 @@ func GetExistConversationUserIDList(ownerUserIDList []string, conversationID str return resultArr, nil } -func GetConversation(OwnerUserID, conversationID string) (relation.ConversationModel, error) { +func GetConversation(OwnerUserID, conversationID string) (Conversation, error) { var conversation Conversation err := ConversationDB.Table("conversations").Where("owner_user_id=? and conversation_id=?", OwnerUserID, conversationID).Take(&conversation).Error return conversation, err @@ -96,7 +116,7 @@ func UpdateColumnsConversations(ownerUserIDList []string, conversationID string, } -func GetConversationIDsByUserID(userID string) ([]string, error) { +func GetConversationIDListByUserID(userID string) ([]string, error) { var IDList []string err := ConversationDB.Model(&Conversation{}).Where("owner_user_id=?", userID).Pluck("conversation_id", &IDList).Error return IDList, err diff --git a/pkg/common/db/relation/conversation_model_g.go b/pkg/common/db/relation/conversation_model_g.go new file mode 100644 index 000000000..37882940d --- /dev/null +++ b/pkg/common/db/relation/conversation_model_g.go @@ -0,0 +1,73 @@ +package relation + +import ( + "Open_IM/pkg/common/db/table" + "Open_IM/pkg/common/tracelog" + "Open_IM/pkg/utils" + "context" + "gorm.io/gorm" +) + +type Conversation interface { + TableName() string + Create(ctx context.Context, conversations []*table.ConversationModel) (err error) + Delete(ctx context.Context, groupIDs []string) (err error) + UpdateByMap(ctx context.Context, groupID string, args map[string]interface{}) (err error) + Update(ctx context.Context, groups []*table.ConversationModel) (err error) + Find(ctx context.Context, groupIDs []string) (groups []*table.ConversationModel, err error) + Take(ctx context.Context, groupID string) (group *table.ConversationModel, err error) +} +type ConversationGorm struct { + DB *gorm.DB +} + +func (c *ConversationGorm) TableName() string { + panic("implement me") +} + +func NewConversationGorm(DB *gorm.DB) Conversation { + return &ConversationGorm{DB: DB} +} + +func (c *ConversationGorm) Create(ctx context.Context, conversations []*table.ConversationModel) (err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "conversations", conversations) + }() + return utils.Wrap(getDBConn(g.DB, tx).Create(&conversations).Error, "") +} + +func (c *ConversationGorm) Delete(ctx context.Context, groupIDs []string) (err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupIDs", groupIDs) + }() + return utils.Wrap(getDBConn(g.DB, tx).Where("group_id in (?)", groupIDs).Delete(&table.ConversationModel{}).Error, "") +} + +func (c *ConversationGorm) UpdateByMap(ctx context.Context, groupID string, args map[string]interface{}) (err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "args", args) + }() + return utils.Wrap(getDBConn(g.DB, tx).Where("group_id = ?", groupID).Model(g).Updates(args).Error, "") +} + +func (c *ConversationGorm) Update(ctx context.Context, groups []*table.ConversationModel) (err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groups", groups) + }() + return utils.Wrap(getDBConn(g.DB, tx).Updates(&groups).Error, "") +} + +func (c *ConversationGorm) Find(ctx context.Context, groupIDs []string) (groups []*table.ConversationModel, err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupIDs", groupIDs, "groups", groups) + }() + return groups, utils.Wrap(getDBConn(g.DB, tx).Where("group_id in (?)", groupIDs).Find(&groups).Error, "") +} + +func (c *ConversationGorm) Take(ctx context.Context, groupID string) (group *table.ConversationModel, err error) { + group = &Group{} + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "group", *group) + }() + return group, utils.Wrap(getDBConn(g.DB, tx).Where("group_id = ?", groupID).Take(group).Error, "") +} diff --git a/pkg/common/db/relation/friend_model_k.go b/pkg/common/db/relation/friend_model_k.go index f61c28e6e..03c642cc4 100644 --- a/pkg/common/db/relation/friend_model_k.go +++ b/pkg/common/db/relation/friend_model_k.go @@ -1,7 +1,7 @@ package relation import ( - "Open_IM/pkg/common/db/table" + "Open_IM/pkg/common/db/table/relation" "Open_IM/pkg/common/tracelog" "Open_IM/pkg/utils" "context" @@ -9,12 +9,12 @@ import ( ) type FriendDB interface { - Create(ctx context.Context, friends []*table.FriendModel) (err error) + Create(ctx context.Context, friends []*relation.FriendModel) (err error) Delete(ctx context.Context, ownerUserID string, friendUserIDs string) (err error) UpdateByMap(ctx context.Context, ownerUserID string, args map[string]interface{}) (err error) - Update(ctx context.Context, friends []*table.FriendModel) (err error) + Update(ctx context.Context, friends []*relation.FriendModel) (err error) UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) - FindOwnerUserID(ctx context.Context, ownerUserID string) (friends []*table.FriendModel, err error) + FindOwnerUserID(ctx context.Context, ownerUserID string) (friends []*relation.FriendModel, err error) } type FriendGorm struct { @@ -30,7 +30,7 @@ type FriendUser struct { Nickname string `gorm:"column:name;size:255"` } -func (f *FriendGorm) Create(ctx context.Context, friends []*table.FriendModel, tx ...*gorm.DB) (err error) { +func (f *FriendGorm) Create(ctx context.Context, friends []*relation.FriendModel, tx ...*gorm.DB) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "friends", friends) }() @@ -52,7 +52,7 @@ func (f *FriendGorm) UpdateByMap(ctx context.Context, ownerUserID string, args m return utils.Wrap(f.DB.Model(&table.FriendModel{}).Where("owner_user_id = ?", ownerUserID).Updates(args).Error, "") } -func (f *FriendGorm) Update(ctx context.Context, friends []*table.FriendModel, tx ...*gorm.DB) (err error) { +func (f *FriendGorm) Update(ctx context.Context, friends []*relation.FriendModel, tx ...*gorm.DB) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "friends", friends) }() @@ -66,27 +66,27 @@ func (f *FriendGorm) UpdateRemark(ctx context.Context, ownerUserID, friendUserID return utils.Wrap(f.DB.Model(&table.FriendModel{}).Where("owner_user_id = ? and friend_user_id = ?", ownerUserID, friendUserID).Update("remark", remark).Error, "") } -func (f *FriendGorm) FindOwnerUserID(ctx context.Context, ownerUserID string) (friends []*table.FriendModel, err error) { +func (f *FriendGorm) FindOwnerUserID(ctx context.Context, ownerUserID string) (friends []*relation.FriendModel, err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "ownerUserID", ownerUserID, "friends", friends) }() return friends, utils.Wrap(f.DB.Model(&table.FriendModel{}).Where("owner_user_id = ?", ownerUserID).Find(&friends).Error, "") } -func (f *FriendGorm) FindFriendUserID(ctx context.Context, friendUserID string) (friends []*table.FriendModel, err error) { +func (f *FriendGorm) FindFriendUserID(ctx context.Context, friendUserID string) (friends []*relation.FriendModel, err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "friendUserID", friendUserID, "friends", friends) }() return friends, utils.Wrap(f.DB.Model(&table.FriendModel{}).Where("friend_user_id = ?", friendUserID).Find(&friends).Error, "") } -func (f *FriendGorm) Take(ctx context.Context, ownerUserID, friendUserID string) (friend *table.FriendModel, err error) { +func (f *FriendGorm) Take(ctx context.Context, ownerUserID, friendUserID string) (friend *relation.FriendModel, err error) { friend = &table.FriendModel{} defer tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "ownerUserID", ownerUserID, "friendUserID", friendUserID, "friend", friend) return friend, utils.Wrap(f.DB.Model(&table.FriendModel{}).Where("owner_user_id = ? and friend_user_id", ownerUserID, friendUserID).Take(friend).Error, "") } -func (f *FriendGorm) FindUserState(ctx context.Context, userID1, userID2 string) (friends []*table.FriendModel, err error) { +func (f *FriendGorm) FindUserState(ctx context.Context, userID1, userID2 string) (friends []*relation.FriendModel, err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "userID1", userID1, "userID2", userID2) }() @@ -94,7 +94,7 @@ func (f *FriendGorm) FindUserState(ctx context.Context, userID1, userID2 string) } // 获取 owner的好友列表 如果不存在也不返回错误 -func (f *FriendGorm) FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, tx ...*gorm.DB) (friends []*table.FriendModel, err error) { +func (f *FriendGorm) FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, tx ...*gorm.DB) (friends []*relation.FriendModel, err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "friendUserIDs", friendUserIDs, "friends", friends) }() @@ -102,14 +102,14 @@ func (f *FriendGorm) FindFriends(ctx context.Context, ownerUserID string, friend } // 获取哪些人添加了friendUserID 如果不存在也不返回错误 -func (f *FriendGorm) FindReversalFriends(ctx context.Context, friendUserID string, ownerUserIDs []string, tx ...*gorm.DB) (friends []*table.FriendModel, err error) { +func (f *FriendGorm) FindReversalFriends(ctx context.Context, friendUserID string, ownerUserIDs []string, tx ...*gorm.DB) (friends []*relation.FriendModel, err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "friendUserID", friendUserID, "friends", friends) }() return friends, utils.Wrap(getDBConn(f.DB, tx).Where("friend_user_id = ? AND owner_user_id in (?)", friendUserID, ownerUserIDs).Find(&friends).Error, "") } -func (f *FriendGorm) FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32, tx ...*gorm.DB) (friends []*table.FriendModel, total int64, err error) { +func (f *FriendGorm) FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32, tx ...*gorm.DB) (friends []*relation.FriendModel, total int64, err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "ownerUserID", ownerUserID, "pageNumber", pageNumber, "showNumber", showNumber, "friends", friends, "total", total) }() @@ -121,7 +121,7 @@ func (f *FriendGorm) FindOwnerFriends(ctx context.Context, ownerUserID string, p return } -func (f *FriendGorm) FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32, tx ...*gorm.DB) (friends []*table.FriendModel, total int64, err error) { +func (f *FriendGorm) FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32, tx ...*gorm.DB) (friends []*relation.FriendModel, total int64, err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "friendUserID", friendUserID, "pageNumber", pageNumber, "showNumber", showNumber, "friends", friends, "total", total) }() diff --git a/pkg/common/db/relation/friend_request_model.go b/pkg/common/db/relation/friend_request_model.go index 878c6cb81..9a2fa3365 100644 --- a/pkg/common/db/relation/friend_request_model.go +++ b/pkg/common/db/relation/friend_request_model.go @@ -1,7 +1,7 @@ package relation import ( - "Open_IM/pkg/common/db/table" + "Open_IM/pkg/common/db/table/relation" "Open_IM/pkg/common/tracelog" "Open_IM/pkg/utils" "context" @@ -20,69 +20,68 @@ type FriendRequestGorm struct { DB *gorm.DB `gorm:"-"` } -func (f *FriendRequestGorm) Create(ctx context.Context, friends []*table.FriendRequestModel) (err error) { +func (f *FriendRequestGorm) Create(ctx context.Context, friends []*relation.FriendRequestModel, tx ...*gorm.DB) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "friends", friends) }() - return utils.Wrap(f.DB.Model(&table.FriendRequestModel{}).Create(&friends).Error, "") + return utils.Wrap(f.DB.Model(&relation.FriendRequestModel{}).Create(&friends).Error, "") } func (f *FriendRequestGorm) Delete(ctx context.Context, fromUserID, toUserID string) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "fromUserID", fromUserID, "toUserID", toUserID) }() - return utils.Wrap(f.DB.Model(&table.FriendRequestModel{}).Where("from_user_id = ? and to_user_id = ?", fromUserID, toUserID).Delete(&table.FriendRequestModel{}).Error, "") + return utils.Wrap(f.DB.Model(&relation.FriendRequestModel{}).Where("from_user_id = ? and to_user_id = ?", fromUserID, toUserID).Delete(&relation.FriendRequestModel{}).Error, "") } -func (f *FriendRequestGorm) UpdateByMap(ctx context.Context, ownerUserID string, args map[string]interface{}) (err error) { +func (f *FriendRequestGorm) UpdateByMap(ctx context.Context, formUserID string, toUserID string, args map[string]interface{}, tx ...*gorm.DB) (err error) { defer func() { - tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "ownerUserID", ownerUserID, "args", args) + tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "formUserID", formUserID, "toUserID", toUserID, "args", args) }() - return utils.Wrap(f.DB.Model(&table.FriendRequestModel{}).Where("owner_user_id = ?", ownerUserID).Updates(args).Error, "") + return utils.Wrap(getDBConn(f.DB, tx).Model(&relation.FriendRequestModel{}).Where("from_user_id = ? AND to_user_id ", formUserID, toUserID).Updates(args).Error, "") } -func (f *FriendRequestGorm) Update(ctx context.Context, friendRequests []*table.FriendRequestModel, tx ...*gorm.DB) (err error) { +func (f *FriendRequestGorm) Update(ctx context.Context, friendRequests []*relation.FriendRequestModel, tx ...*gorm.DB) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "friendRequests", friendRequests) }() - return utils.Wrap(getDBConn(f.DB, tx).Model(&table.FriendRequestModel{}).Updates(&friendRequests).Error, "") + return utils.Wrap(getDBConn(f.DB, tx).Model(&relation.FriendRequestModel{}).Updates(&friendRequests).Error, "") } -func (f *FriendRequestGorm) Find(ctx context.Context, ownerUserID string) (friends []*table.FriendRequestModel, err error) { - defer func() { - tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "ownerUserID", ownerUserID, "friends", friends) - }() - return friends, utils.Wrap(f.DB.Model(&table.FriendRequestModel{}).Where("owner_user_id = ?", ownerUserID).Find(&friends).Error, "") -} - -func (f *FriendRequestGorm) Take(ctx context.Context, fromUserID, toUserID string) (friend *table.FriendRequestModel, err error) { - friend = &table.FriendRequestModel{} +func (f *FriendRequestGorm) Take(ctx context.Context, fromUserID, toUserID string) (friend *relation.FriendRequestModel, err error) { + friend = &relation.FriendRequestModel{} defer tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "fromUserID", fromUserID, "toUserID", toUserID, "friend", friend) - return friend, utils.Wrap(f.DB.Model(&table.FriendRequestModel{}).Where("from_user_id = ? and to_user_id", fromUserID, toUserID).Take(friend).Error, "") + return friend, utils.Wrap(f.DB.Model(&relation.FriendRequestModel{}).Where("from_user_id = ? and to_user_id", fromUserID, toUserID).Take(friend).Error, "") } -func (f *FriendRequestGorm) FindToUserID(ctx context.Context, toUserID string, pageNumber, showNumber int32, tx ...*gorm.DB) (friends []*table.FriendRequestModel, total int64, err error) { +func (f *FriendRequestGorm) Find(ctx context.Context, fromUserID, toUserID string, tx ...*gorm.DB) (friend *relation.FriendRequestModel, err error) { + friend = &relation.FriendRequestModel{} + defer tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "fromUserID", fromUserID, "toUserID", toUserID, "friend", friend) + return friend, utils.Wrap(getDBConn(f.DB, tx).Model(&relation.FriendRequestModel{}).Where("from_user_id = ? and to_user_id", fromUserID, toUserID).Find(friend).Error, "") +} + +func (f *FriendRequestGorm) FindToUserID(ctx context.Context, toUserID string, pageNumber, showNumber int32, tx ...*gorm.DB) (friends []*relation.FriendRequestModel, total int64, err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "toUserID", toUserID, "friends", friends) }() - err = getDBConn(f.DB, tx).Model(&table.FriendRequestModel{}).Where("to_user_id = ? ", toUserID).Count(&total).Error + err = getDBConn(f.DB, tx).Model(&relation.FriendRequestModel{}).Where("to_user_id = ? ", toUserID).Count(&total).Error if err != nil { return nil, 0, utils.Wrap(err, "") } - err = utils.Wrap(getDBConn(f.DB, tx).Model(&table.FriendRequestModel{}).Where("to_user_id = ? ", toUserID).Limit(int(showNumber)).Offset(int(pageNumber*showNumber)).Find(&friends).Error, "") + err = utils.Wrap(getDBConn(f.DB, tx).Model(&relation.FriendRequestModel{}).Where("to_user_id = ? ", toUserID).Limit(int(showNumber)).Offset(int(pageNumber*showNumber)).Find(&friends).Error, "") return } -func (f *FriendRequestGorm) FindFromUserID(ctx context.Context, fromUserID string, pageNumber, showNumber int32, tx ...*gorm.DB) (friends []*table.FriendRequestModel, total int64, err error) { +func (f *FriendRequestGorm) FindFromUserID(ctx context.Context, fromUserID string, pageNumber, showNumber int32, tx ...*gorm.DB) (friends []*relation.FriendRequestModel, total int64, err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "fromUserID", fromUserID, "friends", friends) }() - err = getDBConn(f.DB, tx).Model(&table.FriendRequestModel{}).Where("from_user_id = ? ", fromUserID).Count(&total).Error + err = getDBConn(f.DB, tx).Model(&relation.FriendRequestModel{}).Where("from_user_id = ? ", fromUserID).Count(&total).Error if err != nil { return nil, 0, utils.Wrap(err, "") } - err = utils.Wrap(getDBConn(f.DB, tx).Model(&table.FriendRequestModel{}).Where("from_user_id = ? ", fromUserID).Limit(int(showNumber)).Offset(int(pageNumber*showNumber)).Find(&friends).Error, "") + err = utils.Wrap(getDBConn(f.DB, tx).Model(&relation.FriendRequestModel{}).Where("from_user_id = ? ", fromUserID).Limit(int(showNumber)).Offset(int(pageNumber*showNumber)).Find(&friends).Error, "") return } diff --git a/pkg/common/db/relation/group_member_model.go b/pkg/common/db/relation/group_member_model.go index 959d29bc4..0cd76f9ce 100644 --- a/pkg/common/db/relation/group_member_model.go +++ b/pkg/common/db/relation/group_member_model.go @@ -37,7 +37,7 @@ package relation // //} // -//func GetGroupMemberListByUserID(userID string) ([]GroupMember, error) { +//func FindGroupMember(userID string) ([]GroupMember, error) { // var groupMemberList []GroupMember // err := DB.DB.MysqlDB.DefaultGormDB().Table("group_members").Where("user_id=?", userID).Find(&groupMemberList).Error // if err != nil { @@ -167,7 +167,7 @@ package relation //} // //func GetJoinedGroupIDListByUserID(userID string) ([]string, error) { -// memberList, err := GetGroupMemberListByUserID(userID) +// memberList, err := FindGroupMember(userID) // if err != nil { // return nil, err // } diff --git a/pkg/common/db/relation/group_member_model_k.go b/pkg/common/db/relation/group_member_model_k.go index 75c06ecd7..e137464b7 100644 --- a/pkg/common/db/relation/group_member_model_k.go +++ b/pkg/common/db/relation/group_member_model_k.go @@ -31,6 +31,13 @@ func (g *GroupMemberGorm) Delete(ctx context.Context, groupMembers []*relation.G 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) + }() + return utils.Wrap(getDBConn(g.DB, tx).Where("group_id in (?)", groupIDs).Delete(&relation.GroupMemberModel{}).Error, "") +} + func (g *GroupMemberGorm) UpdateByMap(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) @@ -54,6 +61,23 @@ func (g *GroupMemberGorm) Find(ctx context.Context, groupMembers []*relation.Gro 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) + }() + db := getDBConn(g.DB, tx) + if len(groupList) > 0 { + db = db.Where("group_id in (?)", groupIDs) + } + if len(userIDs) > 0 { + db = db.Where("user_id in (?)", userIDs) + } + if len(roleLevels) > 0 { + db = db.Where("role_level in (?)", roleLevels) + } + return groupList, utils.Wrap(db.Find(&groupList).Error, "") +} + func (g *GroupMemberGorm) Take(ctx context.Context, groupID string, userID string, tx ...*gorm.DB) (groupMember *relation.GroupMemberModel, err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID, "groupMember", *groupMember) @@ -62,7 +86,7 @@ func (g *GroupMemberGorm) Take(ctx context.Context, groupID string, userID strin return groupMember, utils.Wrap(getDBConn(g.DB, tx).Where("group_id = ? and user_id = ?", groupID, userID).Take(groupMember).Error, "") } -func (g *GroupMemberGorm) TakeOwnerInfo(ctx context.Context, groupID string, tx ...*gorm.DB) (groupMember *relation.GroupMemberModel, err error) { +func (g *GroupMemberGorm) TakeOwner(ctx context.Context, groupID string, tx ...*gorm.DB) (groupMember *relation.GroupMemberModel, err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "groupMember", *groupMember) }() @@ -70,214 +94,16 @@ func (g *GroupMemberGorm) TakeOwnerInfo(ctx context.Context, groupID string, tx return groupMember, utils.Wrap(getDBConn(g.DB, tx).Where("group_id = ? and role_level = ?", groupID, constant.GroupOwner).Take(groupMember).Error, "") } -//func InsertIntoGroupMember(toInsertInfo GroupMemberModel) error { -// toInsertInfo.JoinTime = time.Now() -// if toInsertInfo.RoleLevel == 0 { -// toInsertInfo.RoleLevel = constant.GroupOrdinaryUsers -// } -// toInsertInfo.MuteEndTime = time.Unix(int64(time.Now().Second()), 0) -// err := GroupMemberDB.Table("group_members").Create(toInsertInfo).Error -// if err != nil { -// return err -// } -// return nil -//} -// -//func BatchInsertIntoGroupMember(toInsertInfoList []*GroupMemberModel) error { -// for _, toInsertInfo := range toInsertInfoList { -// toInsertInfo.JoinTime = time.Now() -// if toInsertInfo.RoleLevel == 0 { -// toInsertInfo.RoleLevel = constant.GroupOrdinaryUsers -// } -// toInsertInfo.MuteEndTime = time.Unix(int64(time.Now().Second()), 0) -// } -// return GroupMemberDB.Create(toInsertInfoList).Error -// -//} -// -//func GetGroupMemberListByUserID(userID string) ([]GroupMemberModel, error) { -// var groupMemberList []GroupMemberModel -// err := GroupMemberDB.Table("group_members").Where("user_id=?", userID).Find(&groupMemberList).Error -// if err != nil { -// return nil, err -// } -// return groupMemberList, nil -//} -// -//func GetGroupMemberListByGroupID(groupID string) ([]GroupMemberModel, error) { -// var groupMemberList []GroupMemberModel -// err := GroupMemberDB.Table("group_members").Where("group_id=?", groupID).Find(&groupMemberList).Error -// if err != nil { -// return nil, err -// } -// return groupMemberList, nil -//} -// -//func GetGroupMemberIDListByGroupID(groupID string) ([]string, error) { -// var groupMemberIDList []string -// err := GroupMemberDB.Table("group_members").Where("group_id=?", groupID).Pluck("user_id", &groupMemberIDList).Error -// if err != nil { -// return nil, err -// } -// return groupMemberIDList, nil -//} -// -//func GetGroupMemberListByGroupIDAndRoleLevel(groupID string, roleLevel int32) ([]GroupMemberModel, error) { -// var groupMemberList []GroupMemberModel -// err := GroupMemberDB.Table("group_members").Where("group_id=? and role_level=?", groupID, roleLevel).Find(&groupMemberList).Error -// if err != nil { -// return nil, err -// } -// return groupMemberList, nil -//} -// -//func GetGroupMemberInfoByGroupIDAndUserID(groupID, userID string) (*GroupMemberModel, error) { -// var groupMember GroupMemberModel -// err := GroupMemberDB.Table("group_members").Where("group_id=? and user_id=? ", groupID, userID).Limit(1).Take(&groupMember).Error -// if err != nil { -// return nil, err -// } -// return &groupMember, nil -//} -// -//func DeleteGroupMemberByGroupIDAndUserID(groupID, userID string) error { -// return GroupMemberDB.Table("group_members").Where("group_id=? and user_id=? ", groupID, userID).Delete(GroupMemberModel{}).Error -//} -// -//func DeleteGroupMemberByGroupID(groupID string) error { -// return GroupMemberDB.Table("group_members").Where("group_id=? ", groupID).Delete(GroupMemberModel{}).Error -//} -// -//func UpdateGroupMemberInfo(groupMemberInfo GroupMemberModel) error { -// return GroupMemberDB.Table("group_members").Where("group_id=? and user_id=?", groupMemberInfo.GroupID, groupMemberInfo.UserID).Updates(&groupMemberInfo).Error -//} -// -//func UpdateGroupMemberInfoByMap(groupMemberInfo GroupMemberModel, m map[string]interface{}) error { -// return GroupMemberDB.Table("group_members").Where("group_id=? and user_id=?", groupMemberInfo.GroupID, groupMemberInfo.UserID).Updates(m).Error -//} -// -//func GetOwnerManagerByGroupID(groupID string) ([]GroupMemberModel, error) { -// var groupMemberList []GroupMemberModel -// err := GroupMemberDB.Table("group_members").Where("group_id=? and role_level>?", groupID, constant.GroupOrdinaryUsers).Find(&groupMemberList).Error -// if err != nil { -// return nil, err -// } -// return groupMemberList, nil -//} -// -//func GetGroupMemberNumByGroupID(groupID string) (int64, error) { -// var number int64 -// err := GroupMemberDB.Table("group_members").Where("group_id=?", groupID).Count(&number).Error -// if err != nil { -// return 0, utils.Wrap(err, "") -// } -// return number, nil -//} -// -//func GetGroupOwnerInfoByGroupID(groupID string) (*GroupMemberModel, error) { -// omList, err := GetOwnerManagerByGroupID(groupID) -// if err != nil { -// return nil, err -// } -// for _, v := range omList { -// if v.RoleLevel == constant.GroupOwner { -// return &v, nil -// } -// } -// return nil, utils.Wrap(constant.ErrGroupNoOwner, "") -//} -// -//func IsExistGroupMember(groupID, userID string) bool { -// var number int64 -// err := GroupMemberDB.Table("group_members").Where("group_id = ? and user_id = ?", groupID, userID).Count(&number).Error -// if err != nil { -// return false -// } -// if number != 1 { -// return false -// } -// return true -//} -// -//func CheckIsExistGroupMember(ctx context.Context, groupID, userID string) error { -// var number int64 -// err := GroupMemberDB.Table("group_members").Where("group_id = ? and user_id = ?", groupID, userID).Count(&number).Error -// if err != nil { -// return constant.ErrDB.Wrap() -// } -// if number != 1 { -// return constant.ErrData.Wrap() -// } -// return nil -//} -// -//func GetGroupMemberByGroupID(groupID string, filter int32, begin int32, maxNumber int32) ([]GroupMember, error) { -// var memberList []GroupMember -// var err error -// if filter >= 0 { -// memberList, err = GetGroupMemberListByGroupIDAndRoleLevel(groupID, filter) //sorted by join time -// } else { -// memberList, err = GetGroupMemberListByGroupID(groupID) -// } -// -// if err != nil { -// return nil, err -// } -// if begin >= int32(len(memberList)) { -// return nil, nil -// } -// -// var end int32 -// if begin+int32(maxNumber) < int32(len(memberList)) { -// end = begin + maxNumber -// } else { -// end = int32(len(memberList)) -// } -// return memberList[begin:end], nil -//} -// -//func GetJoinedGroupIDListByUserID(userID string) ([]string, error) { -// memberList, err := GetGroupMemberListByUserID(userID) -// if err != nil { -// return nil, err -// } -// var groupIDList []string -// for _, v := range memberList { -// groupIDList = append(groupIDList, v.GroupID) -// } -// return groupIDList, nil -//} -// -//func IsGroupOwnerAdmin(groupID, UserID string) bool { -// groupMemberList, err := GetOwnerManagerByGroupID(groupID) -// if err != nil { -// return false -// } -// for _, v := range groupMemberList { -// if v.UserID == UserID && v.RoleLevel > constant.GroupOrdinaryUsers { -// return true -// } -// } -// return false -//} -// -//func GetGroupMembersByGroupIdCMS(groupId string, userName string, showNumber, pageNumber int32) ([]GroupMember, error) { -// var groupMembers []GroupMember -// err := GroupMemberDB.Table("group_members").Where("group_id=?", groupId).Where(fmt.Sprintf(" nickname like '%%%s%%' ", userName)).Limit(int(showNumber)).Offset(int(showNumber * (pageNumber - 1))).Find(&groupMembers).Error -// if err != nil { -// return nil, err -// } -// return groupMembers, nil -//} -// -//func GetGroupMembersCount(groupID, userName string) (int64, error) { -// var count int64 -// if err := GroupMemberDB.Table("group_members").Where("group_id=?", groupID).Where(fmt.Sprintf(" nickname like '%%%s%%' ", userName)).Count(&count).Error; err != nil { -// return count, err -// } -// return count, nil -//} -// -//func UpdateGroupMemberInfoDefaultZero(groupMemberInfo GroupMember, args map[string]interface{}) error { -// return GroupMemberDB.Model(groupMemberInfo).Updates(args).Error -//} +func (g *GroupMemberGorm) PageByUser(ctx context.Context, userID string, pageNumber, showNumber int32, tx ...*gorm.DB) (total int32, groupList []*relation.GroupMemberModel, err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID, "total", total, "groupList", groupList) + }() + return gormPage[relation.GroupMemberModel](getDBConn(g.DB, tx).Where("user_id = ?", userID), pageNumber, showNumber) +} + +func (g *GroupMemberGorm) SearchMember(ctx context.Context, groupID string, name string, pageNumber, showNumber int32, tx ...*gorm.DB) (total int32, groupList []*relation.GroupMemberModel, err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "name", name, "pageNumber", pageNumber, "showNumber", showNumber, "total", total, "groupList", groupList) + }() + return gormSearch[relation.GroupMemberModel](getDBConn(g.DB, tx).Where("group_id = ?", groupID), "nickname", name, pageNumber, showNumber) +} diff --git a/pkg/common/db/relation/group_model_k.go b/pkg/common/db/relation/group_model_k.go index dbd820e0b..011632976 100644 --- a/pkg/common/db/relation/group_model_k.go +++ b/pkg/common/db/relation/group_model_k.go @@ -30,20 +30,27 @@ func (g *GroupGorm) Delete(ctx context.Context, groupIDs []string, tx ...*gorm.D return utils.Wrap(getDBConn(g.DB, tx).Where("group_id in (?)", groupIDs).Delete(&relation.GroupModel{}).Error, "") } -func (g *GroupGorm) UpdateByMap(ctx context.Context, groupID string, args map[string]interface{}, tx ...*gorm.DB) (err error) { +func (g *GroupGorm) UpdateMap(ctx context.Context, groupID string, args map[string]interface{}, tx ...*gorm.DB) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "args", args) }() - return utils.Wrap(getDBConn(g.DB, tx).Where("group_id = ?", groupID).Model(g).Updates(args).Error, "") + return utils.Wrap(getDBConn(g.DB, tx).Where("group_id = ?", groupID).Model(&relation.GroupModel{}).Updates(args).Error, "") } -func (g *GroupGorm) Update(ctx context.Context, groups []*relation.GroupModel, tx ...*gorm.DB) (err error) { +func (g *GroupGorm) UpdateStatus(ctx context.Context, groupID string, status int32, tx ...*gorm.DB) (err error) { defer func() { - tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groups", groups) + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "status", status) }() - return utils.Wrap(getDBConn(g.DB, tx).Updates(&groups).Error, "") + return utils.Wrap(getDBConn(g.DB, tx).Where("group_id = ?", groupID).Model(&relation.GroupModel{}).Updates(map[string]any{"status": status}).Error, "") } +//func (g *GroupGorm) Update(ctx context.Context, groups []*relation.GroupModel, tx ...*gorm.DB) (err error) { +// defer func() { +// tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groups", groups) +// }() +// return utils.Wrap(getDBConn(g.DB, tx).Updates(&groups).Error, "") +//} + func (g *GroupGorm) Find(ctx context.Context, groupIDs []string, tx ...*gorm.DB) (groups []*relation.GroupModel, err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupIDs", groupIDs, "groups", groups) @@ -54,7 +61,14 @@ func (g *GroupGorm) Find(ctx context.Context, groupIDs []string, tx ...*gorm.DB) func (g *GroupGorm) Take(ctx context.Context, groupID string, tx ...*gorm.DB) (group *relation.GroupModel, err error) { group = &relation.GroupModel{} defer func() { - tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "group", *group) + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "group", group) }() return group, utils.Wrap(getDBConn(g.DB, tx).Where("group_id = ?", groupID).Take(group).Error, "") } + +func (g *GroupGorm) Search(ctx context.Context, name string, pageNumber, showNumber int32, tx ...*gorm.DB) (total int32, groups []*relation.GroupModel, err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "name", name, "pageNumber", pageNumber, "showNumber", showNumber, "total", total, "groups", groups) + }() + return gormSearch[relation.GroupModel](getDBConn(g.DB, tx), "name", name, pageNumber, showNumber) +} diff --git a/pkg/common/db/relation/group_request_model.go b/pkg/common/db/relation/group_request_model.go index ef54d8037..46b4a7543 100644 --- a/pkg/common/db/relation/group_request_model.go +++ b/pkg/common/db/relation/group_request_model.go @@ -55,7 +55,7 @@ package relation //received //func GetRecvGroupApplicationList(userID string) ([]GroupRequest, error) { // var groupRequestList []GroupRequest -// memberList, err := GetGroupMemberListByUserID(userID) +// memberList, err := FindGroupMember(userID) // if err != nil { // return nil, utils.Wrap(err, utils.GetSelfFuncName()) // } diff --git a/pkg/common/db/relation/utils.go b/pkg/common/db/relation/utils.go new file mode 100644 index 000000000..89ccb6552 --- /dev/null +++ b/pkg/common/db/relation/utils.go @@ -0,0 +1,25 @@ +package relation + +import ( + "Open_IM/pkg/utils" + "gorm.io/gorm" +) + +func gormPage[E any](db *gorm.DB, pageNumber, showNumber int32) (int32, []*E, error) { + var count int64 + if err := db.Model(new(E)).Count(&count).Error; err != nil { + return 0, nil, utils.Wrap(err, "") + } + var es []*E + if err := db.Limit(int(showNumber)).Offset(int(pageNumber * showNumber)).Find(&es).Error; err != nil { + return 0, nil, utils.Wrap(err, "") + } + return int32(count), es, nil +} + +func gormSearch[E any](db *gorm.DB, field string, value string, pageNumber, showNumber int32) (int32, []*E, error) { + if field != "" && value != "" { + db = db.Where(field+" like ?", "%"+value+"%") + } + return gormPage[E](db, pageNumber, showNumber) +} diff --git a/pkg/common/db/table/relation/group.go b/pkg/common/db/table/relation/group.go index 70c2d3681..1306eded4 100644 --- a/pkg/common/db/table/relation/group.go +++ b/pkg/common/db/table/relation/group.go @@ -12,7 +12,7 @@ type GroupModel struct { Notification string `gorm:"column:notification;size:255" json:"notification"` Introduction string `gorm:"column:introduction;size:255" json:"introduction"` FaceURL string `gorm:"column:face_url;size:255" json:"faceURL"` - CreateTime time.Time `gorm:"column:create_time;index:create_time"` + CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"` Ex string `gorm:"column:ex" json:"ex;size:1024" json:"ex"` Status int32 `gorm:"column:status"` CreatorUserID string `gorm:"column:creator_user_id;size:64"` diff --git a/pkg/proto/group/group.pb.go b/pkg/proto/group/group.pb.go index 99c71e277..ad028a12a 100644 --- a/pkg/proto/group/group.pb.go +++ b/pkg/proto/group/group.pb.go @@ -39,7 +39,7 @@ func (m *CreateGroupReq) Reset() { *m = CreateGroupReq{} } func (m *CreateGroupReq) String() string { return proto.CompactTextString(m) } func (*CreateGroupReq) ProtoMessage() {} func (*CreateGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{0} + return fileDescriptor_group_d88c7f5350508ce3, []int{0} } func (m *CreateGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreateGroupReq.Unmarshal(m, b) @@ -98,7 +98,7 @@ func (m *CreateGroupResp) Reset() { *m = CreateGroupResp{} } func (m *CreateGroupResp) String() string { return proto.CompactTextString(m) } func (*CreateGroupResp) ProtoMessage() {} func (*CreateGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{1} + return fileDescriptor_group_d88c7f5350508ce3, []int{1} } func (m *CreateGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreateGroupResp.Unmarshal(m, b) @@ -136,7 +136,7 @@ func (m *GetGroupsInfoReq) Reset() { *m = GetGroupsInfoReq{} } func (m *GetGroupsInfoReq) String() string { return proto.CompactTextString(m) } func (*GetGroupsInfoReq) ProtoMessage() {} func (*GetGroupsInfoReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{2} + return fileDescriptor_group_d88c7f5350508ce3, []int{2} } func (m *GetGroupsInfoReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupsInfoReq.Unmarshal(m, b) @@ -174,7 +174,7 @@ func (m *GetGroupsInfoResp) Reset() { *m = GetGroupsInfoResp{} } func (m *GetGroupsInfoResp) String() string { return proto.CompactTextString(m) } func (*GetGroupsInfoResp) ProtoMessage() {} func (*GetGroupsInfoResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{3} + return fileDescriptor_group_d88c7f5350508ce3, []int{3} } func (m *GetGroupsInfoResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupsInfoResp.Unmarshal(m, b) @@ -212,7 +212,7 @@ func (m *SetGroupInfoReq) Reset() { *m = SetGroupInfoReq{} } func (m *SetGroupInfoReq) String() string { return proto.CompactTextString(m) } func (*SetGroupInfoReq) ProtoMessage() {} func (*SetGroupInfoReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{4} + return fileDescriptor_group_d88c7f5350508ce3, []int{4} } func (m *SetGroupInfoReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetGroupInfoReq.Unmarshal(m, b) @@ -249,7 +249,7 @@ func (m *SetGroupInfoResp) Reset() { *m = SetGroupInfoResp{} } func (m *SetGroupInfoResp) String() string { return proto.CompactTextString(m) } func (*SetGroupInfoResp) ProtoMessage() {} func (*SetGroupInfoResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{5} + return fileDescriptor_group_d88c7f5350508ce3, []int{5} } func (m *SetGroupInfoResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetGroupInfoResp.Unmarshal(m, b) @@ -281,7 +281,7 @@ func (m *GetGroupApplicationListReq) Reset() { *m = GetGroupApplicationL func (m *GetGroupApplicationListReq) String() string { return proto.CompactTextString(m) } func (*GetGroupApplicationListReq) ProtoMessage() {} func (*GetGroupApplicationListReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{6} + return fileDescriptor_group_d88c7f5350508ce3, []int{6} } func (m *GetGroupApplicationListReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupApplicationListReq.Unmarshal(m, b) @@ -327,7 +327,7 @@ func (m *GetGroupApplicationListResp) Reset() { *m = GetGroupApplication func (m *GetGroupApplicationListResp) String() string { return proto.CompactTextString(m) } func (*GetGroupApplicationListResp) ProtoMessage() {} func (*GetGroupApplicationListResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{7} + return fileDescriptor_group_d88c7f5350508ce3, []int{7} } func (m *GetGroupApplicationListResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupApplicationListResp.Unmarshal(m, b) @@ -373,7 +373,7 @@ func (m *GetUserReqApplicationListReq) Reset() { *m = GetUserReqApplicat func (m *GetUserReqApplicationListReq) String() string { return proto.CompactTextString(m) } func (*GetUserReqApplicationListReq) ProtoMessage() {} func (*GetUserReqApplicationListReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{8} + return fileDescriptor_group_d88c7f5350508ce3, []int{8} } func (m *GetUserReqApplicationListReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetUserReqApplicationListReq.Unmarshal(m, b) @@ -419,7 +419,7 @@ func (m *GetUserReqApplicationListResp) Reset() { *m = GetUserReqApplica func (m *GetUserReqApplicationListResp) String() string { return proto.CompactTextString(m) } func (*GetUserReqApplicationListResp) ProtoMessage() {} func (*GetUserReqApplicationListResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{9} + return fileDescriptor_group_d88c7f5350508ce3, []int{9} } func (m *GetUserReqApplicationListResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetUserReqApplicationListResp.Unmarshal(m, b) @@ -466,7 +466,7 @@ func (m *TransferGroupOwnerReq) Reset() { *m = TransferGroupOwnerReq{} } func (m *TransferGroupOwnerReq) String() string { return proto.CompactTextString(m) } func (*TransferGroupOwnerReq) ProtoMessage() {} func (*TransferGroupOwnerReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{10} + return fileDescriptor_group_d88c7f5350508ce3, []int{10} } func (m *TransferGroupOwnerReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TransferGroupOwnerReq.Unmarshal(m, b) @@ -517,7 +517,7 @@ func (m *TransferGroupOwnerResp) Reset() { *m = TransferGroupOwnerResp{} func (m *TransferGroupOwnerResp) String() string { return proto.CompactTextString(m) } func (*TransferGroupOwnerResp) ProtoMessage() {} func (*TransferGroupOwnerResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{11} + return fileDescriptor_group_d88c7f5350508ce3, []int{11} } func (m *TransferGroupOwnerResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TransferGroupOwnerResp.Unmarshal(m, b) @@ -551,7 +551,7 @@ func (m *JoinGroupReq) Reset() { *m = JoinGroupReq{} } func (m *JoinGroupReq) String() string { return proto.CompactTextString(m) } func (*JoinGroupReq) ProtoMessage() {} func (*JoinGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{12} + return fileDescriptor_group_d88c7f5350508ce3, []int{12} } func (m *JoinGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_JoinGroupReq.Unmarshal(m, b) @@ -609,7 +609,7 @@ func (m *JoinGroupResp) Reset() { *m = JoinGroupResp{} } func (m *JoinGroupResp) String() string { return proto.CompactTextString(m) } func (*JoinGroupResp) ProtoMessage() {} func (*JoinGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{13} + return fileDescriptor_group_d88c7f5350508ce3, []int{13} } func (m *JoinGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_JoinGroupResp.Unmarshal(m, b) @@ -643,7 +643,7 @@ func (m *GroupApplicationResponseReq) Reset() { *m = GroupApplicationRes func (m *GroupApplicationResponseReq) String() string { return proto.CompactTextString(m) } func (*GroupApplicationResponseReq) ProtoMessage() {} func (*GroupApplicationResponseReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{14} + return fileDescriptor_group_d88c7f5350508ce3, []int{14} } func (m *GroupApplicationResponseReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GroupApplicationResponseReq.Unmarshal(m, b) @@ -701,7 +701,7 @@ func (m *GroupApplicationResponseResp) Reset() { *m = GroupApplicationRe func (m *GroupApplicationResponseResp) String() string { return proto.CompactTextString(m) } func (*GroupApplicationResponseResp) ProtoMessage() {} func (*GroupApplicationResponseResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{15} + return fileDescriptor_group_d88c7f5350508ce3, []int{15} } func (m *GroupApplicationResponseResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GroupApplicationResponseResp.Unmarshal(m, b) @@ -732,7 +732,7 @@ func (m *QuitGroupReq) Reset() { *m = QuitGroupReq{} } func (m *QuitGroupReq) String() string { return proto.CompactTextString(m) } func (*QuitGroupReq) ProtoMessage() {} func (*QuitGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{16} + return fileDescriptor_group_d88c7f5350508ce3, []int{16} } func (m *QuitGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QuitGroupReq.Unmarshal(m, b) @@ -769,7 +769,7 @@ func (m *QuitGroupResp) Reset() { *m = QuitGroupResp{} } func (m *QuitGroupResp) String() string { return proto.CompactTextString(m) } func (*QuitGroupResp) ProtoMessage() {} func (*QuitGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{17} + return fileDescriptor_group_d88c7f5350508ce3, []int{17} } func (m *QuitGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QuitGroupResp.Unmarshal(m, b) @@ -802,7 +802,7 @@ func (m *GetGroupMemberListReq) Reset() { *m = GetGroupMemberListReq{} } func (m *GetGroupMemberListReq) String() string { return proto.CompactTextString(m) } func (*GetGroupMemberListReq) ProtoMessage() {} func (*GetGroupMemberListReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{18} + return fileDescriptor_group_d88c7f5350508ce3, []int{18} } func (m *GetGroupMemberListReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMemberListReq.Unmarshal(m, b) @@ -855,7 +855,7 @@ func (m *GetGroupMemberListResp) Reset() { *m = GetGroupMemberListResp{} func (m *GetGroupMemberListResp) String() string { return proto.CompactTextString(m) } func (*GetGroupMemberListResp) ProtoMessage() {} func (*GetGroupMemberListResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{19} + return fileDescriptor_group_d88c7f5350508ce3, []int{19} } func (m *GetGroupMemberListResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMemberListResp.Unmarshal(m, b) @@ -901,7 +901,7 @@ func (m *GetGroupMembersInfoReq) Reset() { *m = GetGroupMembersInfoReq{} func (m *GetGroupMembersInfoReq) String() string { return proto.CompactTextString(m) } func (*GetGroupMembersInfoReq) ProtoMessage() {} func (*GetGroupMembersInfoReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{20} + return fileDescriptor_group_d88c7f5350508ce3, []int{20} } func (m *GetGroupMembersInfoReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMembersInfoReq.Unmarshal(m, b) @@ -946,7 +946,7 @@ func (m *GetGroupMembersInfoResp) Reset() { *m = GetGroupMembersInfoResp func (m *GetGroupMembersInfoResp) String() string { return proto.CompactTextString(m) } func (*GetGroupMembersInfoResp) ProtoMessage() {} func (*GetGroupMembersInfoResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{21} + return fileDescriptor_group_d88c7f5350508ce3, []int{21} } func (m *GetGroupMembersInfoResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMembersInfoResp.Unmarshal(m, b) @@ -986,7 +986,7 @@ func (m *KickGroupMemberReq) Reset() { *m = KickGroupMemberReq{} } func (m *KickGroupMemberReq) String() string { return proto.CompactTextString(m) } func (*KickGroupMemberReq) ProtoMessage() {} func (*KickGroupMemberReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{22} + return fileDescriptor_group_d88c7f5350508ce3, []int{22} } func (m *KickGroupMemberReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_KickGroupMemberReq.Unmarshal(m, b) @@ -1037,7 +1037,7 @@ func (m *KickGroupMemberResp) Reset() { *m = KickGroupMemberResp{} } func (m *KickGroupMemberResp) String() string { return proto.CompactTextString(m) } func (*KickGroupMemberResp) ProtoMessage() {} func (*KickGroupMemberResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{23} + return fileDescriptor_group_d88c7f5350508ce3, []int{23} } func (m *KickGroupMemberResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_KickGroupMemberResp.Unmarshal(m, b) @@ -1069,7 +1069,7 @@ func (m *GetJoinedGroupListReq) Reset() { *m = GetJoinedGroupListReq{} } func (m *GetJoinedGroupListReq) String() string { return proto.CompactTextString(m) } func (*GetJoinedGroupListReq) ProtoMessage() {} func (*GetJoinedGroupListReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{24} + return fileDescriptor_group_d88c7f5350508ce3, []int{24} } func (m *GetJoinedGroupListReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetJoinedGroupListReq.Unmarshal(m, b) @@ -1115,7 +1115,7 @@ func (m *GetJoinedGroupListResp) Reset() { *m = GetJoinedGroupListResp{} func (m *GetJoinedGroupListResp) String() string { return proto.CompactTextString(m) } func (*GetJoinedGroupListResp) ProtoMessage() {} func (*GetJoinedGroupListResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{25} + return fileDescriptor_group_d88c7f5350508ce3, []int{25} } func (m *GetJoinedGroupListResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetJoinedGroupListResp.Unmarshal(m, b) @@ -1162,7 +1162,7 @@ func (m *InviteUserToGroupReq) Reset() { *m = InviteUserToGroupReq{} } func (m *InviteUserToGroupReq) String() string { return proto.CompactTextString(m) } func (*InviteUserToGroupReq) ProtoMessage() {} func (*InviteUserToGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{26} + return fileDescriptor_group_d88c7f5350508ce3, []int{26} } func (m *InviteUserToGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InviteUserToGroupReq.Unmarshal(m, b) @@ -1213,7 +1213,7 @@ func (m *InviteUserToGroupResp) Reset() { *m = InviteUserToGroupResp{} } func (m *InviteUserToGroupResp) String() string { return proto.CompactTextString(m) } func (*InviteUserToGroupResp) ProtoMessage() {} func (*InviteUserToGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{27} + return fileDescriptor_group_d88c7f5350508ce3, []int{27} } func (m *InviteUserToGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InviteUserToGroupResp.Unmarshal(m, b) @@ -1245,7 +1245,7 @@ func (m *GetGroupAllMemberReq) Reset() { *m = GetGroupAllMemberReq{} } func (m *GetGroupAllMemberReq) String() string { return proto.CompactTextString(m) } func (*GetGroupAllMemberReq) ProtoMessage() {} func (*GetGroupAllMemberReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{28} + return fileDescriptor_group_d88c7f5350508ce3, []int{28} } func (m *GetGroupAllMemberReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupAllMemberReq.Unmarshal(m, b) @@ -1290,7 +1290,7 @@ func (m *GetGroupAllMemberResp) Reset() { *m = GetGroupAllMemberResp{} } func (m *GetGroupAllMemberResp) String() string { return proto.CompactTextString(m) } func (*GetGroupAllMemberResp) ProtoMessage() {} func (*GetGroupAllMemberResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{29} + return fileDescriptor_group_d88c7f5350508ce3, []int{29} } func (m *GetGroupAllMemberResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupAllMemberResp.Unmarshal(m, b) @@ -1330,7 +1330,7 @@ func (m *CMSGroup) Reset() { *m = CMSGroup{} } func (m *CMSGroup) String() string { return proto.CompactTextString(m) } func (*CMSGroup) ProtoMessage() {} func (*CMSGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{30} + return fileDescriptor_group_d88c7f5350508ce3, []int{30} } func (m *CMSGroup) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CMSGroup.Unmarshal(m, b) @@ -1384,7 +1384,7 @@ func (m *GetGroupsReq) Reset() { *m = GetGroupsReq{} } func (m *GetGroupsReq) String() string { return proto.CompactTextString(m) } func (*GetGroupsReq) ProtoMessage() {} func (*GetGroupsReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{31} + return fileDescriptor_group_d88c7f5350508ce3, []int{31} } func (m *GetGroupsReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupsReq.Unmarshal(m, b) @@ -1437,7 +1437,7 @@ func (m *GetGroupsResp) Reset() { *m = GetGroupsResp{} } func (m *GetGroupsResp) String() string { return proto.CompactTextString(m) } func (*GetGroupsResp) ProtoMessage() {} func (*GetGroupsResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{32} + return fileDescriptor_group_d88c7f5350508ce3, []int{32} } func (m *GetGroupsResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupsResp.Unmarshal(m, b) @@ -1482,7 +1482,7 @@ func (m *GetGroupMemberReq) Reset() { *m = GetGroupMemberReq{} } func (m *GetGroupMemberReq) String() string { return proto.CompactTextString(m) } func (*GetGroupMemberReq) ProtoMessage() {} func (*GetGroupMemberReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{33} + return fileDescriptor_group_d88c7f5350508ce3, []int{33} } func (m *GetGroupMemberReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMemberReq.Unmarshal(m, b) @@ -1522,7 +1522,7 @@ func (m *GetGroupMembersCMSReq) Reset() { *m = GetGroupMembersCMSReq{} } func (m *GetGroupMembersCMSReq) String() string { return proto.CompactTextString(m) } func (*GetGroupMembersCMSReq) ProtoMessage() {} func (*GetGroupMembersCMSReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{34} + return fileDescriptor_group_d88c7f5350508ce3, []int{34} } func (m *GetGroupMembersCMSReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMembersCMSReq.Unmarshal(m, b) @@ -1565,8 +1565,7 @@ func (m *GetGroupMembersCMSReq) GetPagination() *sdk_ws.RequestPagination { type GetGroupMembersCMSResp struct { Members []*sdk_ws.GroupMemberFullInfo `protobuf:"bytes,1,rep,name=members" json:"members,omitempty"` - Pagination *sdk_ws.ResponsePagination `protobuf:"bytes,2,opt,name=pagination" json:"pagination,omitempty"` - MemberNums int32 `protobuf:"varint,3,opt,name=memberNums" json:"memberNums,omitempty"` + MemberNums int32 `protobuf:"varint,2,opt,name=memberNums" json:"memberNums,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1576,7 +1575,7 @@ func (m *GetGroupMembersCMSResp) Reset() { *m = GetGroupMembersCMSResp{} func (m *GetGroupMembersCMSResp) String() string { return proto.CompactTextString(m) } func (*GetGroupMembersCMSResp) ProtoMessage() {} func (*GetGroupMembersCMSResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{35} + return fileDescriptor_group_d88c7f5350508ce3, []int{35} } func (m *GetGroupMembersCMSResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupMembersCMSResp.Unmarshal(m, b) @@ -1603,13 +1602,6 @@ func (m *GetGroupMembersCMSResp) GetMembers() []*sdk_ws.GroupMemberFullInfo { return nil } -func (m *GetGroupMembersCMSResp) GetPagination() *sdk_ws.ResponsePagination { - if m != nil { - return m.Pagination - } - return nil -} - func (m *GetGroupMembersCMSResp) GetMemberNums() int32 { if m != nil { return m.MemberNums @@ -1628,7 +1620,7 @@ func (m *DismissGroupReq) Reset() { *m = DismissGroupReq{} } func (m *DismissGroupReq) String() string { return proto.CompactTextString(m) } func (*DismissGroupReq) ProtoMessage() {} func (*DismissGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{36} + return fileDescriptor_group_d88c7f5350508ce3, []int{36} } func (m *DismissGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DismissGroupReq.Unmarshal(m, b) @@ -1665,7 +1657,7 @@ func (m *DismissGroupResp) Reset() { *m = DismissGroupResp{} } func (m *DismissGroupResp) String() string { return proto.CompactTextString(m) } func (*DismissGroupResp) ProtoMessage() {} func (*DismissGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{37} + return fileDescriptor_group_d88c7f5350508ce3, []int{37} } func (m *DismissGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DismissGroupResp.Unmarshal(m, b) @@ -1698,7 +1690,7 @@ func (m *MuteGroupMemberReq) Reset() { *m = MuteGroupMemberReq{} } func (m *MuteGroupMemberReq) String() string { return proto.CompactTextString(m) } func (*MuteGroupMemberReq) ProtoMessage() {} func (*MuteGroupMemberReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{38} + return fileDescriptor_group_d88c7f5350508ce3, []int{38} } func (m *MuteGroupMemberReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MuteGroupMemberReq.Unmarshal(m, b) @@ -1749,7 +1741,7 @@ func (m *MuteGroupMemberResp) Reset() { *m = MuteGroupMemberResp{} } func (m *MuteGroupMemberResp) String() string { return proto.CompactTextString(m) } func (*MuteGroupMemberResp) ProtoMessage() {} func (*MuteGroupMemberResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{39} + return fileDescriptor_group_d88c7f5350508ce3, []int{39} } func (m *MuteGroupMemberResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MuteGroupMemberResp.Unmarshal(m, b) @@ -1781,7 +1773,7 @@ func (m *CancelMuteGroupMemberReq) Reset() { *m = CancelMuteGroupMemberR func (m *CancelMuteGroupMemberReq) String() string { return proto.CompactTextString(m) } func (*CancelMuteGroupMemberReq) ProtoMessage() {} func (*CancelMuteGroupMemberReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{40} + return fileDescriptor_group_d88c7f5350508ce3, []int{40} } func (m *CancelMuteGroupMemberReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CancelMuteGroupMemberReq.Unmarshal(m, b) @@ -1825,7 +1817,7 @@ func (m *CancelMuteGroupMemberResp) Reset() { *m = CancelMuteGroupMember func (m *CancelMuteGroupMemberResp) String() string { return proto.CompactTextString(m) } func (*CancelMuteGroupMemberResp) ProtoMessage() {} func (*CancelMuteGroupMemberResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{41} + return fileDescriptor_group_d88c7f5350508ce3, []int{41} } func (m *CancelMuteGroupMemberResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CancelMuteGroupMemberResp.Unmarshal(m, b) @@ -1856,7 +1848,7 @@ func (m *MuteGroupReq) Reset() { *m = MuteGroupReq{} } func (m *MuteGroupReq) String() string { return proto.CompactTextString(m) } func (*MuteGroupReq) ProtoMessage() {} func (*MuteGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{42} + return fileDescriptor_group_d88c7f5350508ce3, []int{42} } func (m *MuteGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MuteGroupReq.Unmarshal(m, b) @@ -1893,7 +1885,7 @@ func (m *MuteGroupResp) Reset() { *m = MuteGroupResp{} } func (m *MuteGroupResp) String() string { return proto.CompactTextString(m) } func (*MuteGroupResp) ProtoMessage() {} func (*MuteGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{43} + return fileDescriptor_group_d88c7f5350508ce3, []int{43} } func (m *MuteGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MuteGroupResp.Unmarshal(m, b) @@ -1924,7 +1916,7 @@ func (m *CancelMuteGroupReq) Reset() { *m = CancelMuteGroupReq{} } func (m *CancelMuteGroupReq) String() string { return proto.CompactTextString(m) } func (*CancelMuteGroupReq) ProtoMessage() {} func (*CancelMuteGroupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{44} + return fileDescriptor_group_d88c7f5350508ce3, []int{44} } func (m *CancelMuteGroupReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CancelMuteGroupReq.Unmarshal(m, b) @@ -1961,7 +1953,7 @@ func (m *CancelMuteGroupResp) Reset() { *m = CancelMuteGroupResp{} } func (m *CancelMuteGroupResp) String() string { return proto.CompactTextString(m) } func (*CancelMuteGroupResp) ProtoMessage() {} func (*CancelMuteGroupResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{45} + return fileDescriptor_group_d88c7f5350508ce3, []int{45} } func (m *CancelMuteGroupResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CancelMuteGroupResp.Unmarshal(m, b) @@ -1994,7 +1986,7 @@ func (m *SetGroupMemberNicknameReq) Reset() { *m = SetGroupMemberNicknam func (m *SetGroupMemberNicknameReq) String() string { return proto.CompactTextString(m) } func (*SetGroupMemberNicknameReq) ProtoMessage() {} func (*SetGroupMemberNicknameReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{46} + return fileDescriptor_group_d88c7f5350508ce3, []int{46} } func (m *SetGroupMemberNicknameReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetGroupMemberNicknameReq.Unmarshal(m, b) @@ -2045,7 +2037,7 @@ func (m *SetGroupMemberNicknameResp) Reset() { *m = SetGroupMemberNickna func (m *SetGroupMemberNicknameResp) String() string { return proto.CompactTextString(m) } func (*SetGroupMemberNicknameResp) ProtoMessage() {} func (*SetGroupMemberNicknameResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{47} + return fileDescriptor_group_d88c7f5350508ce3, []int{47} } func (m *SetGroupMemberNicknameResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetGroupMemberNicknameResp.Unmarshal(m, b) @@ -2077,7 +2069,7 @@ func (m *GetJoinedSuperGroupListReq) Reset() { *m = GetJoinedSuperGroupL func (m *GetJoinedSuperGroupListReq) String() string { return proto.CompactTextString(m) } func (*GetJoinedSuperGroupListReq) ProtoMessage() {} func (*GetJoinedSuperGroupListReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{48} + return fileDescriptor_group_d88c7f5350508ce3, []int{48} } func (m *GetJoinedSuperGroupListReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetJoinedSuperGroupListReq.Unmarshal(m, b) @@ -2123,7 +2115,7 @@ func (m *GetJoinedSuperGroupListResp) Reset() { *m = GetJoinedSuperGroup func (m *GetJoinedSuperGroupListResp) String() string { return proto.CompactTextString(m) } func (*GetJoinedSuperGroupListResp) ProtoMessage() {} func (*GetJoinedSuperGroupListResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{49} + return fileDescriptor_group_d88c7f5350508ce3, []int{49} } func (m *GetJoinedSuperGroupListResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetJoinedSuperGroupListResp.Unmarshal(m, b) @@ -2168,7 +2160,7 @@ func (m *GetSuperGroupsInfoReq) Reset() { *m = GetSuperGroupsInfoReq{} } func (m *GetSuperGroupsInfoReq) String() string { return proto.CompactTextString(m) } func (*GetSuperGroupsInfoReq) ProtoMessage() {} func (*GetSuperGroupsInfoReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{50} + return fileDescriptor_group_d88c7f5350508ce3, []int{50} } func (m *GetSuperGroupsInfoReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSuperGroupsInfoReq.Unmarshal(m, b) @@ -2206,7 +2198,7 @@ func (m *GetSuperGroupsInfoResp) Reset() { *m = GetSuperGroupsInfoResp{} func (m *GetSuperGroupsInfoResp) String() string { return proto.CompactTextString(m) } func (*GetSuperGroupsInfoResp) ProtoMessage() {} func (*GetSuperGroupsInfoResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{51} + return fileDescriptor_group_d88c7f5350508ce3, []int{51} } func (m *GetSuperGroupsInfoResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSuperGroupsInfoResp.Unmarshal(m, b) @@ -2249,7 +2241,7 @@ func (m *SetGroupMemberInfoReq) Reset() { *m = SetGroupMemberInfoReq{} } func (m *SetGroupMemberInfoReq) String() string { return proto.CompactTextString(m) } func (*SetGroupMemberInfoReq) ProtoMessage() {} func (*SetGroupMemberInfoReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{52} + return fileDescriptor_group_d88c7f5350508ce3, []int{52} } func (m *SetGroupMemberInfoReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetGroupMemberInfoReq.Unmarshal(m, b) @@ -2321,7 +2313,7 @@ func (m *SetGroupMemberInfoResp) Reset() { *m = SetGroupMemberInfoResp{} func (m *SetGroupMemberInfoResp) String() string { return proto.CompactTextString(m) } func (*SetGroupMemberInfoResp) ProtoMessage() {} func (*SetGroupMemberInfoResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{53} + return fileDescriptor_group_d88c7f5350508ce3, []int{53} } func (m *SetGroupMemberInfoResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetGroupMemberInfoResp.Unmarshal(m, b) @@ -2352,7 +2344,7 @@ func (m *GetGroupAbstractInfoReq) Reset() { *m = GetGroupAbstractInfoReq func (m *GetGroupAbstractInfoReq) String() string { return proto.CompactTextString(m) } func (*GetGroupAbstractInfoReq) ProtoMessage() {} func (*GetGroupAbstractInfoReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{54} + return fileDescriptor_group_d88c7f5350508ce3, []int{54} } func (m *GetGroupAbstractInfoReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupAbstractInfoReq.Unmarshal(m, b) @@ -2392,7 +2384,7 @@ func (m *GroupAbstractInfo) Reset() { *m = GroupAbstractInfo{} } func (m *GroupAbstractInfo) String() string { return proto.CompactTextString(m) } func (*GroupAbstractInfo) ProtoMessage() {} func (*GroupAbstractInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{55} + return fileDescriptor_group_d88c7f5350508ce3, []int{55} } func (m *GroupAbstractInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GroupAbstractInfo.Unmarshal(m, b) @@ -2444,7 +2436,7 @@ func (m *GetGroupAbstractInfoResp) Reset() { *m = GetGroupAbstractInfoRe func (m *GetGroupAbstractInfoResp) String() string { return proto.CompactTextString(m) } func (*GetGroupAbstractInfoResp) ProtoMessage() {} func (*GetGroupAbstractInfoResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{56} + return fileDescriptor_group_d88c7f5350508ce3, []int{56} } func (m *GetGroupAbstractInfoResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetGroupAbstractInfoResp.Unmarshal(m, b) @@ -2483,7 +2475,7 @@ func (m *GetUserInGroupMembersReq) Reset() { *m = GetUserInGroupMembersR func (m *GetUserInGroupMembersReq) String() string { return proto.CompactTextString(m) } func (*GetUserInGroupMembersReq) ProtoMessage() {} func (*GetUserInGroupMembersReq) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{57} + return fileDescriptor_group_d88c7f5350508ce3, []int{57} } func (m *GetUserInGroupMembersReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetUserInGroupMembersReq.Unmarshal(m, b) @@ -2528,7 +2520,7 @@ func (m *GetUserInGroupMembersResp) Reset() { *m = GetUserInGroupMembers func (m *GetUserInGroupMembersResp) String() string { return proto.CompactTextString(m) } func (*GetUserInGroupMembersResp) ProtoMessage() {} func (*GetUserInGroupMembersResp) Descriptor() ([]byte, []int) { - return fileDescriptor_group_5c8d3aafef0e7d21, []int{58} + return fileDescriptor_group_d88c7f5350508ce3, []int{58} } func (m *GetUserInGroupMembersResp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetUserInGroupMembersResp.Unmarshal(m, b) @@ -3166,7 +3158,7 @@ func _Group_GetGroupMemberList_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/group.group/GetGroupMemberList", + FullMethod: "/group.group/FindGroupMemberAll", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GroupServer).GetGroupMemberList(ctx, req.(*GetGroupMemberListReq)) @@ -3220,7 +3212,7 @@ func _Group_GetJoinedGroupList_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/group.group/GetJoinedGroupList", + FullMethod: "/group.group/FindJoinedGroup", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GroupServer).GetJoinedGroupList(ctx, req.(*GetJoinedGroupListReq)) @@ -3597,124 +3589,123 @@ var _Group_serviceDesc = grpc.ServiceDesc{ Metadata: "group/group.proto", } -func init() { proto.RegisterFile("group/group.proto", fileDescriptor_group_5c8d3aafef0e7d21) } +func init() { proto.RegisterFile("group/group.proto", fileDescriptor_group_d88c7f5350508ce3) } -var fileDescriptor_group_5c8d3aafef0e7d21 = []byte{ - // 1851 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x5f, 0x53, 0xe4, 0xc6, - 0x11, 0x2f, 0x2d, 0x07, 0x77, 0xf4, 0x81, 0xe1, 0x06, 0x16, 0x74, 0x82, 0x03, 0x3c, 0x26, 0x0e, - 0x95, 0xf8, 0x96, 0xd4, 0x5d, 0xe2, 0xca, 0x1f, 0x57, 0x39, 0x36, 0xd8, 0x98, 0x84, 0x85, 0x9c, - 0x16, 0x3b, 0x15, 0xa7, 0x5c, 0x44, 0xec, 0x0e, 0xb2, 0x0e, 0xad, 0x34, 0x68, 0xb4, 0xe0, 0x72, - 0x39, 0x0f, 0xc9, 0x73, 0xfe, 0x3c, 0xe4, 0x31, 0x6f, 0xa9, 0x7c, 0x84, 0x7c, 0x81, 0x7c, 0x95, - 0x7c, 0x92, 0x94, 0x66, 0x46, 0xb3, 0x23, 0x69, 0xb4, 0xbb, 0xc1, 0x9b, 0x97, 0xad, 0x52, 0x4f, - 0xf7, 0x4c, 0x4f, 0xff, 0x9b, 0x5f, 0xf7, 0xc2, 0x13, 0x3f, 0x89, 0x07, 0x74, 0x9f, 0xff, 0xb6, - 0x68, 0x12, 0xa7, 0x31, 0x9a, 0xe5, 0x1f, 0xce, 0xde, 0x19, 0x25, 0xd1, 0xf3, 0xe3, 0xf6, 0xf3, - 0x0e, 0x49, 0x6e, 0x49, 0xb2, 0x4f, 0xaf, 0xfd, 0x7d, 0xce, 0xb0, 0xcf, 0x7a, 0xd7, 0x17, 0x77, - 0x6c, 0xff, 0x8e, 0x09, 0x01, 0xa7, 0x35, 0x96, 0x33, 0xf1, 0x28, 0x25, 0x89, 0xe4, 0xc7, 0xff, - 0xb2, 0xe0, 0x8d, 0x83, 0x84, 0x78, 0x29, 0x39, 0xca, 0x4e, 0x72, 0xc9, 0x0d, 0xda, 0x81, 0xc7, - 0x41, 0x14, 0xa4, 0x6d, 0xd2, 0xbf, 0x24, 0x09, 0xb3, 0xad, 0x9d, 0x99, 0xbd, 0x79, 0x57, 0x27, - 0xa1, 0x9f, 0xc2, 0x3c, 0xd7, 0xeb, 0x38, 0xba, 0x8a, 0xed, 0xc6, 0x8e, 0xb5, 0xf7, 0xf8, 0xc5, - 0x66, 0x8b, 0xf1, 0x03, 0x2f, 0x3c, 0x1a, 0x5c, 0x50, 0x2f, 0xf1, 0xfa, 0xac, 0x75, 0x94, 0xf3, - 0xb8, 0x43, 0x76, 0x84, 0x61, 0xc1, 0xeb, 0xf5, 0x83, 0xe8, 0x53, 0x46, 0x92, 0xe3, 0x43, 0x66, - 0xcf, 0xf0, 0xed, 0x0b, 0xb4, 0x4c, 0x83, 0xf8, 0x2e, 0x22, 0x89, 0xf8, 0xb6, 0x1f, 0xec, 0x58, - 0x99, 0x06, 0x1a, 0x09, 0xb7, 0x61, 0xa9, 0xa0, 0x35, 0xa3, 0x45, 0xa5, 0xac, 0xff, 0x49, 0x29, - 0xdc, 0x82, 0xe5, 0x23, 0x92, 0xf2, 0x25, 0xc6, 0xd7, 0xc8, 0x0d, 0x72, 0xe0, 0x91, 0x60, 0x38, - 0xcc, 0x6d, 0xa0, 0xbe, 0xf1, 0x2b, 0x78, 0x52, 0xe2, 0x67, 0x14, 0xbd, 0x07, 0xa0, 0x76, 0x14, - 0x22, 0xe3, 0x34, 0xd0, 0xf8, 0xf1, 0x05, 0x2c, 0x75, 0xe4, 0x96, 0xb9, 0x06, 0x27, 0xb0, 0xa4, - 0x18, 0x3e, 0x8e, 0x93, 0x0e, 0x49, 0xe5, 0xbd, 0xf0, 0xa8, 0x5d, 0x05, 0xa7, 0x5b, 0x16, 0xc5, - 0x08, 0x96, 0x8b, 0x07, 0x30, 0x8a, 0xff, 0x68, 0x81, 0x93, 0x5f, 0xe4, 0x03, 0x4a, 0xc3, 0xa0, - 0xeb, 0xa5, 0x41, 0x1c, 0x9d, 0x04, 0x2c, 0xcd, 0x14, 0x38, 0x04, 0xa0, 0x9e, 0x1f, 0x44, 0x9c, - 0x28, 0xcf, 0xde, 0x35, 0x9c, 0xed, 0x92, 0x9b, 0x01, 0x61, 0xe9, 0xaf, 0x14, 0xaf, 0xab, 0xc9, - 0xa1, 0x2d, 0x80, 0xab, 0x24, 0xee, 0x4b, 0x67, 0x36, 0xb8, 0x33, 0x35, 0x0a, 0xfe, 0x1a, 0x36, - 0x6a, 0x75, 0x60, 0x14, 0xad, 0xc2, 0x6c, 0x1a, 0xa7, 0x5e, 0xc8, 0xcf, 0x9f, 0x75, 0xc5, 0x07, - 0xfa, 0x08, 0x16, 0x7d, 0x19, 0xb0, 0xd9, 0xd1, 0xcc, 0x6e, 0x70, 0x7b, 0x6f, 0xd7, 0x59, 0x46, - 0xf2, 0xb9, 0x45, 0x29, 0xfc, 0x0d, 0x6c, 0x1e, 0x91, 0x34, 0x53, 0xc4, 0x25, 0x37, 0x06, 0x0b, - 0xac, 0xc1, 0xdc, 0x40, 0xe8, 0x6d, 0x71, 0xbd, 0xe5, 0x57, 0xc9, 0x32, 0x8d, 0xfb, 0x59, 0x06, - 0x7f, 0x03, 0xcf, 0x46, 0x9c, 0xfe, 0xff, 0xbe, 0xfb, 0x1f, 0x2c, 0x68, 0x9e, 0x27, 0x5e, 0xc4, - 0xae, 0x48, 0xc2, 0xf9, 0xce, 0xb2, 0x04, 0xcb, 0x6e, 0x6d, 0xc3, 0x43, 0x19, 0xea, 0xf2, 0xda, - 0xf9, 0x27, 0x7a, 0x1b, 0xde, 0x88, 0xc3, 0xde, 0x99, 0x96, 0x9c, 0xc2, 0x9f, 0x25, 0x6a, 0xc6, - 0x17, 0x91, 0x3b, 0x9d, 0x6f, 0x46, 0xf0, 0x15, 0xa9, 0xd8, 0x86, 0x35, 0x93, 0x0a, 0x8c, 0xe2, - 0xbf, 0x58, 0xb0, 0xf0, 0x8b, 0x38, 0x88, 0x54, 0x59, 0xaa, 0x57, 0x6a, 0x0b, 0x20, 0x21, 0x37, - 0x6d, 0xc2, 0x98, 0xe7, 0x93, 0x3c, 0xc0, 0x86, 0x94, 0x6c, 0xfd, 0x75, 0x1c, 0x44, 0x9d, 0x78, - 0x90, 0x74, 0x09, 0x57, 0x64, 0xd6, 0xd5, 0x28, 0x68, 0x17, 0x16, 0x83, 0xe8, 0x36, 0x48, 0x4b, - 0x05, 0xa7, 0x48, 0xc4, 0x4b, 0xb0, 0xa8, 0xe9, 0xc3, 0x28, 0xfe, 0xbb, 0x05, 0x1b, 0xe5, 0xa8, - 0xcd, 0x16, 0xe2, 0x88, 0x91, 0xb1, 0x0a, 0x8f, 0xca, 0x88, 0x6c, 0xfd, 0x4b, 0x2f, 0xea, 0x85, - 0xa4, 0xd7, 0x66, 0xbe, 0xb4, 0x9c, 0x46, 0xc9, 0x6a, 0xa8, 0xf8, 0x72, 0x09, 0x1b, 0x84, 0x29, - 0xd7, 0x77, 0xd6, 0x2d, 0xd0, 0xf0, 0x16, 0x6c, 0xd6, 0x2b, 0xc7, 0x28, 0xde, 0x83, 0x85, 0x57, - 0x83, 0x20, 0x1d, 0x6f, 0xde, 0xec, 0xe2, 0x1a, 0x27, 0xa3, 0xf8, 0xaf, 0x16, 0x34, 0xf3, 0x8c, - 0x15, 0x4f, 0x42, 0x9e, 0x2e, 0xf5, 0x57, 0x5e, 0x83, 0xb9, 0xab, 0x20, 0x4c, 0x49, 0xc2, 0xaf, - 0x3b, 0xeb, 0xca, 0xaf, 0x52, 0x22, 0x3d, 0xb8, 0x67, 0x22, 0x51, 0x58, 0x33, 0x29, 0x54, 0x9b, - 0x41, 0x3f, 0x87, 0x87, 0x7d, 0xf9, 0xbc, 0x89, 0xdc, 0x79, 0xbb, 0x2e, 0x77, 0xc4, 0x76, 0x1f, - 0x0f, 0xc2, 0x90, 0x17, 0xcd, 0x5c, 0x0c, 0x9f, 0x94, 0x4f, 0x54, 0xef, 0x46, 0xbd, 0x0d, 0xec, - 0xe2, 0xa9, 0xf3, 0xc3, 0xdd, 0x7e, 0x0b, 0xeb, 0xc6, 0xdd, 0x18, 0xd5, 0x55, 0xb5, 0xee, 0xa7, - 0x6a, 0x08, 0xe8, 0x97, 0x41, 0xf7, 0x5a, 0xe3, 0x19, 0xad, 0xe6, 0x2e, 0x2c, 0x5e, 0x07, 0xdd, - 0x6b, 0xd2, 0xcb, 0x9f, 0x68, 0xa1, 0x6c, 0x91, 0x98, 0x39, 0x34, 0x21, 0x1e, 0x8b, 0x23, 0x19, - 0x9f, 0xf2, 0x0b, 0x37, 0x61, 0xa5, 0x72, 0x1a, 0xa3, 0xf8, 0xf7, 0x3c, 0x64, 0xb2, 0x04, 0x22, - 0x3d, 0xbe, 0x96, 0x87, 0x4c, 0x31, 0x17, 0xac, 0x4a, 0x2e, 0x4c, 0xa7, 0xd2, 0xf6, 0xb8, 0xbb, - 0x2a, 0xc7, 0xd7, 0x06, 0xc8, 0x0f, 0x61, 0x8e, 0x9b, 0x23, 0x8f, 0x8f, 0xd1, 0xef, 0xb8, 0xe4, - 0xc5, 0x14, 0x56, 0x8f, 0x79, 0xcd, 0xc8, 0x74, 0x3f, 0x8f, 0x27, 0x28, 0x5d, 0x43, 0x2b, 0x36, - 0x74, 0x2b, 0x66, 0xf5, 0x53, 0x54, 0x9f, 0x5e, 0x11, 0x27, 0x95, 0xa8, 0x78, 0x1d, 0x9a, 0x86, - 0x13, 0x19, 0xc5, 0xb7, 0xb0, 0xaa, 0x1e, 0xd5, 0x30, 0x9c, 0xc4, 0xed, 0xd3, 0x31, 0xf4, 0x6f, - 0x86, 0xa5, 0x41, 0x3b, 0x77, 0x2a, 0x71, 0xfc, 0x0f, 0x0b, 0x1e, 0x1d, 0xb4, 0x3b, 0x9c, 0xe7, - 0xdb, 0xa0, 0x3d, 0xd4, 0x02, 0xe4, 0xab, 0xc7, 0x26, 0x33, 0xdc, 0xa9, 0xd7, 0xcf, 0xdf, 0x0d, - 0xc3, 0x0a, 0xfa, 0x1e, 0x2c, 0x17, 0xa9, 0xea, 0x39, 0xab, 0xd0, 0xf1, 0x9f, 0x2c, 0x58, 0x50, - 0xd0, 0x70, 0x7a, 0x18, 0x6a, 0x53, 0x5e, 0x57, 0xd3, 0x74, 0x48, 0xd0, 0x9d, 0x3a, 0x53, 0xac, - 0xdd, 0xe7, 0xb0, 0xa8, 0x69, 0xc3, 0x28, 0xfa, 0xae, 0x0a, 0x6c, 0xe1, 0x85, 0xa5, 0x96, 0x68, - 0x37, 0x72, 0xc3, 0xe6, 0xb1, 0x9c, 0xc1, 0x5f, 0x4e, 0x38, 0x1d, 0xf4, 0x65, 0xc9, 0x56, 0xdf, - 0xf8, 0xf9, 0x10, 0xfe, 0x4e, 0x10, 0x59, 0xf8, 0x6f, 0x95, 0xf7, 0x82, 0x1d, 0xb4, 0x3b, 0xa3, - 0xa3, 0xd1, 0x81, 0x47, 0x83, 0xa2, 0x67, 0xd4, 0x77, 0xc9, 0xa4, 0x33, 0xf7, 0x8c, 0xd4, 0x7f, - 0x5b, 0x95, 0x12, 0xce, 0xb5, 0x9a, 0x46, 0xac, 0xa2, 0x8f, 0x0c, 0xc9, 0xf4, 0x1d, 0xa3, 0x8a, - 0xe2, 0x49, 0xae, 0x87, 0xce, 0x62, 0xc7, 0xd3, 0x41, 0x9f, 0xe5, 0xc8, 0x65, 0x48, 0xc1, 0xdf, - 0x87, 0xa5, 0xc3, 0x80, 0xf5, 0x03, 0xc6, 0x26, 0x78, 0xc7, 0x11, 0x2c, 0x17, 0x99, 0x19, 0xc5, - 0xaf, 0x01, 0xb5, 0x07, 0xb2, 0x8b, 0x9a, 0xa4, 0x48, 0x0c, 0xf1, 0x70, 0xa3, 0x80, 0x87, 0x31, - 0x2c, 0xf4, 0x07, 0x29, 0xe9, 0x75, 0x48, 0x37, 0x8e, 0x7a, 0x42, 0xd5, 0x45, 0xb7, 0x40, 0xcb, - 0x5e, 0x86, 0xca, 0x59, 0x8c, 0xe2, 0x13, 0xb0, 0x0f, 0xbc, 0xa8, 0x4b, 0xc2, 0x69, 0x28, 0x82, - 0x37, 0xe0, 0x69, 0xcd, 0x6e, 0x02, 0xf3, 0x28, 0xf2, 0x58, 0xcc, 0xa3, 0x71, 0x32, 0x8a, 0x5b, - 0x80, 0x4a, 0xfb, 0x8e, 0xde, 0xa0, 0x09, 0x2b, 0x15, 0x7e, 0x46, 0x71, 0x00, 0x4f, 0x3b, 0x85, - 0x98, 0x3b, 0x0d, 0xba, 0xd7, 0x91, 0xd7, 0x27, 0x63, 0xb3, 0x21, 0x92, 0x8c, 0x79, 0x36, 0xe4, - 0xdf, 0x9a, 0x25, 0x66, 0x0a, 0x96, 0xd8, 0x04, 0xa7, 0xee, 0x28, 0x46, 0xf1, 0xd7, 0xbc, 0xf1, - 0x13, 0x0f, 0x62, 0x67, 0x40, 0x25, 0xfc, 0x9e, 0x6e, 0xe3, 0x57, 0xe7, 0xa3, 0x80, 0x37, 0x7c, - 0xe6, 0xb3, 0xa7, 0xfc, 0x22, 0xbf, 0xe4, 0x95, 0x67, 0x78, 0xc8, 0x44, 0xdd, 0xfd, 0x67, 0xbc, - 0x30, 0x54, 0x84, 0xbe, 0x75, 0x8b, 0xff, 0xcf, 0x06, 0x34, 0x8b, 0x2e, 0x19, 0x8f, 0x19, 0xeb, - 0x12, 0xee, 0xc7, 0x5a, 0x44, 0xcc, 0xc8, 0xe7, 0xcf, 0x8f, 0x63, 0x3f, 0x24, 0x62, 0xb0, 0x73, - 0x39, 0xb8, 0x6a, 0x75, 0xd2, 0x24, 0x88, 0xfc, 0xcf, 0xbc, 0x70, 0x40, 0xb4, 0x78, 0x79, 0x17, - 0x1e, 0x5e, 0x79, 0x5d, 0xf2, 0xa9, 0x7b, 0x22, 0xe1, 0xf6, 0x68, 0xc1, 0x9c, 0x19, 0xfd, 0x04, - 0xe6, 0x93, 0x38, 0x24, 0x27, 0xe4, 0x96, 0x84, 0xf6, 0x2c, 0x97, 0xdc, 0xa8, 0x48, 0x1e, 0x47, - 0xe9, 0xcb, 0x17, 0x42, 0x70, 0xc8, 0x8d, 0xde, 0x81, 0x06, 0xf9, 0xca, 0x9e, 0x9b, 0xe0, 0xb4, - 0x06, 0xf9, 0x2a, 0xeb, 0x09, 0x4d, 0x56, 0x62, 0x14, 0xff, 0x68, 0x08, 0x93, 0x3f, 0xb8, 0x64, - 0x69, 0xe2, 0x75, 0xd3, 0x49, 0xfc, 0xf9, 0x67, 0x0b, 0x9e, 0x54, 0x84, 0x46, 0xd8, 0xfc, 0x1d, - 0x39, 0x89, 0x6b, 0xe7, 0x85, 0xf6, 0x52, 0xb5, 0x2d, 0xd5, 0x05, 0xf4, 0x03, 0x58, 0xf1, 0x8b, - 0x8d, 0xc7, 0x27, 0x1e, 0xfb, 0x92, 0x3b, 0xe5, 0x81, 0x6b, 0x5a, 0xc2, 0x3d, 0xb0, 0xcd, 0xd7, - 0x60, 0x14, 0x7d, 0x22, 0xb1, 0x89, 0xbe, 0x90, 0x47, 0x9a, 0x2d, 0xdf, 0xea, 0xaa, 0xa4, 0x41, - 0x06, 0x9f, 0x82, 0xed, 0x8b, 0xe1, 0xc2, 0x71, 0xa4, 0x3f, 0x72, 0xa3, 0xc6, 0x1a, 0xba, 0x15, - 0x1b, 0x25, 0x2b, 0x7e, 0x01, 0x4f, 0x6b, 0xf6, 0x9b, 0xc6, 0x8b, 0xf9, 0xe2, 0x3f, 0xcb, 0x20, - 0x86, 0x9d, 0xe8, 0x3d, 0x78, 0xdc, 0x1d, 0xce, 0xf6, 0x50, 0x33, 0x47, 0x28, 0x85, 0x29, 0xa5, - 0xb3, 0x66, 0x22, 0x33, 0x8a, 0xde, 0x85, 0xf9, 0xd7, 0x79, 0x9b, 0x8e, 0x56, 0x24, 0x93, 0x3e, - 0x48, 0x70, 0x56, 0xab, 0x44, 0x21, 0x77, 0x93, 0x77, 0xb9, 0x4a, 0x4e, 0xef, 0x90, 0x95, 0x5c, - 0xa1, 0x19, 0x46, 0x1f, 0xc2, 0xa2, 0xaf, 0x8f, 0x02, 0xd1, 0x7a, 0xee, 0xa5, 0xd2, 0x40, 0xd1, - 0xb1, 0xcd, 0x0b, 0x8c, 0xa2, 0xf7, 0x61, 0x81, 0x69, 0xa3, 0x39, 0x94, 0xdf, 0xad, 0x34, 0x10, - 0x74, 0xd6, 0x8d, 0x74, 0x46, 0xd1, 0xef, 0x60, 0xdd, 0x37, 0x8f, 0xd0, 0xd0, 0x9b, 0xa5, 0x53, - 0xab, 0x43, 0x2e, 0x07, 0x8f, 0x63, 0x61, 0x14, 0x5d, 0x29, 0xef, 0x57, 0x47, 0x55, 0xe8, 0xad, - 0xe1, 0x06, 0xb5, 0xa3, 0x34, 0x67, 0x77, 0x3c, 0x13, 0xa3, 0xe8, 0x15, 0xa0, 0xb4, 0x32, 0x10, - 0x42, 0x9b, 0x52, 0xd6, 0x38, 0xae, 0x72, 0x9e, 0x8d, 0x58, 0x65, 0x14, 0x75, 0xc1, 0xf6, 0x6b, - 0x26, 0x21, 0x08, 0x17, 0x52, 0xca, 0x38, 0xc7, 0x71, 0xde, 0x1a, 0xcb, 0x23, 0xf4, 0xf6, 0x2b, - 0x13, 0x08, 0xa5, 0xb7, 0x71, 0x5a, 0xa2, 0xf4, 0xae, 0x19, 0x5d, 0x9c, 0xc3, 0x8a, 0x5f, 0x1d, - 0x0a, 0x20, 0xb3, 0x94, 0x8a, 0xb2, 0xad, 0x51, 0xcb, 0xbc, 0xc0, 0x2c, 0x5d, 0x17, 0xfb, 0x73, - 0xf4, 0x54, 0x8a, 0x54, 0xa7, 0x04, 0x8e, 0x53, 0xb7, 0xa4, 0xae, 0x5c, 0xea, 0xa9, 0xf5, 0x2b, - 0x57, 0xbb, 0x7d, 0xfd, 0xca, 0xa6, 0x66, 0xfc, 0x14, 0x9e, 0x04, 0xe5, 0x76, 0x16, 0x6d, 0x48, - 0x19, 0x53, 0x6b, 0xed, 0x6c, 0xd6, 0x2f, 0x8a, 0xa4, 0x56, 0xc9, 0xa9, 0x92, 0x5a, 0x6f, 0xcf, - 0x54, 0x52, 0x17, 0xbb, 0xa4, 0x8a, 0x37, 0xb3, 0xd6, 0xa0, 0xc6, 0x9b, 0xb2, 0x97, 0xa9, 0xf1, - 0xa6, 0xea, 0x29, 0xde, 0x87, 0x85, 0x9e, 0x86, 0xbe, 0x55, 0x8e, 0x97, 0xf0, 0xbb, 0xca, 0xf1, - 0x32, 0x54, 0xcf, 0x1c, 0xd7, 0x2f, 0x62, 0x5a, 0xe5, 0xb8, 0x2a, 0x72, 0x56, 0x8e, 0x33, 0xc0, - 0x60, 0xf4, 0x39, 0x34, 0xbb, 0x26, 0x8c, 0x8c, 0xb6, 0xf3, 0x9a, 0x5a, 0x83, 0xc7, 0x9d, 0x9d, - 0xd1, 0x0c, 0xc2, 0xe2, 0x4a, 0x4b, 0x65, 0x71, 0x1d, 0x33, 0x2b, 0x8b, 0x17, 0x80, 0x71, 0x76, - 0xbb, 0x92, 0x4e, 0xea, 0x76, 0x55, 0xdc, 0xad, 0x6e, 0x67, 0x80, 0xd8, 0xb2, 0x16, 0x9a, 0xd0, - 0xa5, 0x5e, 0x0b, 0x6b, 0x90, 0xaf, 0x5e, 0x0b, 0x6b, 0x01, 0xaa, 0x88, 0x8e, 0x12, 0x3e, 0xd4, - 0xa3, 0xa3, 0x8a, 0x37, 0xf5, 0xe8, 0x30, 0x01, 0xcb, 0x2f, 0x60, 0x8d, 0x19, 0xc1, 0x3a, 0xda, - 0x29, 0xd5, 0xfc, 0x4a, 0xdb, 0xe0, 0xbc, 0x39, 0x86, 0x43, 0x68, 0xcc, 0x2a, 0x90, 0x4a, 0x69, - 0x6c, 0xc4, 0xa4, 0x4a, 0x63, 0x33, 0x16, 0x43, 0xbf, 0x86, 0x55, 0xdf, 0x00, 0x62, 0x50, 0xb9, - 0xfe, 0x94, 0x80, 0x9a, 0xb3, 0x3d, 0x72, 0x5d, 0x44, 0xa7, 0x11, 0x67, 0xa8, 0xe8, 0xac, 0x43, - 0x35, 0x2a, 0x3a, 0x6b, 0x61, 0xca, 0x87, 0xdb, 0x9f, 0x3f, 0x3b, 0xa3, 0x24, 0xba, 0x38, 0x6e, - 0x6b, 0x7f, 0x8c, 0x72, 0xa1, 0x9f, 0xf1, 0xdf, 0xcb, 0x39, 0x4e, 0x7a, 0xf9, 0xdf, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x4a, 0x6c, 0x49, 0xeb, 0x8b, 0x1d, 0x00, 0x00, +var fileDescriptor_group_d88c7f5350508ce3 = []byte{ + // 1835 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x5f, 0x53, 0xdc, 0xc8, + 0x11, 0x2f, 0x2d, 0x06, 0x9b, 0x36, 0x1c, 0x30, 0xb0, 0x20, 0x04, 0x06, 0x6e, 0x8e, 0xba, 0x50, + 0xc9, 0x79, 0x49, 0xd9, 0xc9, 0x55, 0xfe, 0x5c, 0xd5, 0xc5, 0x86, 0x18, 0x93, 0xb0, 0x10, 0x6b, + 0xb1, 0x53, 0x71, 0xca, 0x45, 0xc4, 0xee, 0x20, 0xcb, 0x68, 0xa5, 0x41, 0xa3, 0x05, 0x97, 0xcb, + 0x79, 0x48, 0x9e, 0xf3, 0xe7, 0x21, 0x8f, 0x79, 0x4b, 0xe5, 0x23, 0xe4, 0x13, 0xe5, 0x93, 0xa4, + 0x34, 0x1a, 0xcd, 0x8e, 0xa4, 0xd1, 0xee, 0x06, 0xef, 0xbd, 0x6c, 0xa1, 0x9e, 0xee, 0x99, 0x9e, + 0xfe, 0x37, 0xbf, 0x6e, 0x60, 0xc1, 0x8d, 0xc2, 0x1e, 0xdd, 0xe5, 0xbf, 0x0d, 0x1a, 0x85, 0x71, + 0x88, 0x26, 0xf9, 0x87, 0xb5, 0x73, 0x42, 0x49, 0xf0, 0xf0, 0xb0, 0xf9, 0xb0, 0x45, 0xa2, 0x6b, + 0x12, 0xed, 0xd2, 0x4b, 0x77, 0x97, 0x33, 0xec, 0xb2, 0xce, 0xe5, 0xd9, 0x0d, 0xdb, 0xbd, 0x61, + 0xa9, 0x80, 0xd5, 0x18, 0xca, 0x19, 0x39, 0x94, 0x92, 0x48, 0xf0, 0xe3, 0xff, 0x18, 0xf0, 0xd9, + 0x5e, 0x44, 0x9c, 0x98, 0x1c, 0x24, 0x27, 0xd9, 0xe4, 0x0a, 0x6d, 0xc1, 0x7d, 0x2f, 0xf0, 0xe2, + 0x26, 0xe9, 0x9e, 0x93, 0x88, 0x99, 0xc6, 0xd6, 0xc4, 0xce, 0xb4, 0xad, 0x92, 0xd0, 0xcf, 0x60, + 0x9a, 0xeb, 0x75, 0x18, 0x5c, 0x84, 0x66, 0x6d, 0xcb, 0xd8, 0xb9, 0xff, 0x68, 0xbd, 0xc1, 0xf8, + 0x81, 0x67, 0x0e, 0xf5, 0xce, 0xa8, 0x13, 0x39, 0x5d, 0xd6, 0x38, 0xc8, 0x78, 0xec, 0x3e, 0x3b, + 0xc2, 0x30, 0xe3, 0x74, 0xba, 0x5e, 0xf0, 0x92, 0x91, 0xe8, 0x70, 0x9f, 0x99, 0x13, 0x7c, 0xfb, + 0x1c, 0x2d, 0xd1, 0x20, 0xbc, 0x09, 0x48, 0x94, 0x7e, 0x9b, 0x77, 0xb6, 0x8c, 0x44, 0x03, 0x85, + 0x84, 0x9b, 0x30, 0x97, 0xd3, 0x9a, 0xd1, 0xbc, 0x52, 0xc6, 0xff, 0xa5, 0x14, 0x6e, 0xc0, 0xfc, + 0x01, 0x89, 0xf9, 0x12, 0xe3, 0x6b, 0xe4, 0x0a, 0x59, 0x70, 0x2f, 0x65, 0xd8, 0xcf, 0x6c, 0x20, + 0xbf, 0xf1, 0x0b, 0x58, 0x28, 0xf0, 0x33, 0x8a, 0xbe, 0x01, 0x90, 0x3b, 0xa6, 0x22, 0xc3, 0x34, + 0x50, 0xf8, 0xf1, 0x19, 0xcc, 0xb5, 0xc4, 0x96, 0x99, 0x06, 0x47, 0x30, 0x27, 0x19, 0x9e, 0x85, + 0x51, 0x8b, 0xc4, 0xe2, 0x5e, 0x78, 0xd0, 0xae, 0x29, 0xa7, 0x5d, 0x14, 0xc5, 0x08, 0xe6, 0xf3, + 0x07, 0x30, 0x8a, 0xff, 0x6c, 0x80, 0x95, 0x5d, 0xe4, 0x09, 0xa5, 0xbe, 0xd7, 0x76, 0x62, 0x2f, + 0x0c, 0x8e, 0x3c, 0x16, 0x27, 0x0a, 0xec, 0x03, 0x50, 0xc7, 0xf5, 0x02, 0x4e, 0x14, 0x67, 0x6f, + 0x6b, 0xce, 0xb6, 0xc9, 0x55, 0x8f, 0xb0, 0xf8, 0x37, 0x92, 0xd7, 0x56, 0xe4, 0xd0, 0x06, 0xc0, + 0x45, 0x14, 0x76, 0x85, 0x33, 0x6b, 0xdc, 0x99, 0x0a, 0x05, 0x7f, 0x80, 0xb5, 0x4a, 0x1d, 0x18, + 0x45, 0x4b, 0x30, 0x19, 0x87, 0xb1, 0xe3, 0xf3, 0xf3, 0x27, 0xed, 0xf4, 0x03, 0xfd, 0x12, 0x66, + 0x5d, 0x11, 0xb0, 0xc9, 0xd1, 0xcc, 0xac, 0x71, 0x7b, 0x6f, 0x56, 0x59, 0x46, 0xf0, 0xd9, 0x79, + 0x29, 0xfc, 0x11, 0xd6, 0x0f, 0x48, 0x9c, 0x28, 0x62, 0x93, 0x2b, 0x8d, 0x05, 0x96, 0x61, 0xaa, + 0x97, 0xea, 0x6d, 0x70, 0xbd, 0xc5, 0x57, 0xc1, 0x32, 0xb5, 0xdb, 0x59, 0x06, 0x7f, 0x84, 0x07, + 0x03, 0x4e, 0xff, 0xae, 0xef, 0xfe, 0x27, 0x03, 0xea, 0xa7, 0x91, 0x13, 0xb0, 0x0b, 0x12, 0x71, + 0xbe, 0x93, 0x24, 0xc1, 0x92, 0x5b, 0x9b, 0x70, 0x57, 0x84, 0xba, 0xb8, 0x76, 0xf6, 0x89, 0xbe, + 0x84, 0xcf, 0x42, 0xbf, 0x73, 0xa2, 0x24, 0x67, 0xea, 0xcf, 0x02, 0x35, 0xe1, 0x0b, 0xc8, 0x8d, + 0xca, 0x37, 0x91, 0xf2, 0xe5, 0xa9, 0xd8, 0x84, 0x65, 0x9d, 0x0a, 0x8c, 0xe2, 0xbf, 0x19, 0x30, + 0xf3, 0xab, 0xd0, 0x0b, 0x64, 0x59, 0xaa, 0x56, 0x6a, 0x03, 0x20, 0x22, 0x57, 0x4d, 0xc2, 0x98, + 0xe3, 0x92, 0x2c, 0xc0, 0xfa, 0x94, 0x64, 0xfd, 0x5d, 0xe8, 0x05, 0xad, 0xb0, 0x17, 0xb5, 0x09, + 0x57, 0x64, 0xd2, 0x56, 0x28, 0x68, 0x1b, 0x66, 0xbd, 0xe0, 0xda, 0x8b, 0x0b, 0x05, 0x27, 0x4f, + 0xc4, 0x73, 0x30, 0xab, 0xe8, 0xc3, 0x28, 0xfe, 0xa7, 0x01, 0x6b, 0xc5, 0xa8, 0x4d, 0x16, 0xc2, + 0x80, 0x91, 0xa1, 0x0a, 0x0f, 0xca, 0x88, 0x64, 0xfd, 0xad, 0x13, 0x74, 0x7c, 0xd2, 0x69, 0x32, + 0x57, 0x58, 0x4e, 0xa1, 0x24, 0x35, 0x34, 0xfd, 0xb2, 0x09, 0xeb, 0xf9, 0x31, 0xd7, 0x77, 0xd2, + 0xce, 0xd1, 0xf0, 0x06, 0xac, 0x57, 0x2b, 0xc7, 0x28, 0xde, 0x81, 0x99, 0x17, 0x3d, 0x2f, 0x1e, + 0x6e, 0xde, 0xe4, 0xe2, 0x0a, 0x27, 0xa3, 0xf8, 0xef, 0x06, 0xd4, 0xb3, 0x8c, 0x4d, 0x9f, 0x84, + 0x2c, 0x5d, 0xaa, 0xaf, 0xbc, 0x0c, 0x53, 0x17, 0x9e, 0x1f, 0x93, 0x88, 0x5f, 0x77, 0xd2, 0x16, + 0x5f, 0x85, 0x44, 0xba, 0x73, 0xcb, 0x44, 0xa2, 0xb0, 0xac, 0x53, 0xa8, 0x32, 0x83, 0x7e, 0x01, + 0x77, 0xbb, 0xe2, 0x79, 0x4b, 0x73, 0xe7, 0xcb, 0xaa, 0xdc, 0x49, 0xb7, 0x7b, 0xd6, 0xf3, 0x7d, + 0x5e, 0x34, 0x33, 0x31, 0x7c, 0x54, 0x3c, 0x51, 0xbe, 0x1b, 0xd5, 0x36, 0x30, 0xf3, 0xa7, 0x4e, + 0xf7, 0x77, 0xfb, 0x3d, 0xac, 0x68, 0x77, 0x63, 0x54, 0x55, 0xd5, 0xb8, 0x9d, 0xaa, 0x3e, 0xa0, + 0x5f, 0x7b, 0xed, 0x4b, 0x85, 0x67, 0xb0, 0x9a, 0xdb, 0x30, 0x7b, 0xe9, 0xb5, 0x2f, 0x49, 0x27, + 0x7b, 0xa2, 0x53, 0x65, 0xf3, 0xc4, 0xc4, 0xa1, 0x11, 0x71, 0x58, 0x18, 0x88, 0xf8, 0x14, 0x5f, + 0xb8, 0x0e, 0x8b, 0xa5, 0xd3, 0x18, 0xc5, 0x7f, 0xe4, 0x21, 0x93, 0x24, 0x10, 0xe9, 0xf0, 0xb5, + 0x2c, 0x64, 0xf2, 0xb9, 0x60, 0x94, 0x72, 0x61, 0x3c, 0x95, 0xb6, 0xc3, 0xdd, 0x55, 0x3a, 0xbe, + 0x32, 0x40, 0x7e, 0x04, 0x53, 0xdc, 0x1c, 0x59, 0x7c, 0x0c, 0x7e, 0xc7, 0x05, 0x2f, 0xa6, 0xb0, + 0x74, 0xc8, 0x6b, 0x46, 0xa2, 0xfb, 0x69, 0x38, 0x42, 0xe9, 0xea, 0x5b, 0xb1, 0xa6, 0x5a, 0x31, + 0xa9, 0x9f, 0x69, 0xf5, 0xe9, 0xe4, 0x71, 0x52, 0x81, 0x8a, 0x57, 0xa0, 0xae, 0x39, 0x91, 0x51, + 0x7c, 0x0d, 0x4b, 0xf2, 0x51, 0xf5, 0xfd, 0x51, 0xdc, 0x3e, 0x1e, 0x43, 0xff, 0xae, 0x5f, 0x1a, + 0x94, 0x73, 0xc7, 0x12, 0xc7, 0xff, 0x32, 0xe0, 0xde, 0x5e, 0xb3, 0xc5, 0x79, 0x3e, 0x05, 0xed, + 0xa1, 0x06, 0x20, 0x57, 0x3e, 0x36, 0x89, 0xe1, 0x8e, 0x9d, 0x6e, 0xf6, 0x6e, 0x68, 0x56, 0xd0, + 0xf7, 0x61, 0x3e, 0x4f, 0x95, 0xcf, 0x59, 0x89, 0x8e, 0xff, 0x62, 0xc0, 0x8c, 0x84, 0x86, 0xe3, + 0xc3, 0x50, 0xeb, 0xe2, 0xba, 0x8a, 0xa6, 0x7d, 0x82, 0xea, 0xd4, 0x89, 0x7c, 0xed, 0x3e, 0x85, + 0x59, 0x45, 0x1b, 0x46, 0xd1, 0xf7, 0x64, 0x60, 0xa7, 0x5e, 0x98, 0x6b, 0xa4, 0xed, 0x46, 0x66, + 0xd8, 0x2c, 0x96, 0x13, 0xf8, 0xcb, 0x09, 0xc7, 0xbd, 0xae, 0x28, 0xd9, 0xf2, 0x1b, 0x3f, 0xec, + 0xc3, 0xdf, 0x11, 0x22, 0x0b, 0xff, 0xa3, 0xf4, 0x5e, 0xb0, 0xbd, 0x66, 0x6b, 0x70, 0x34, 0x5a, + 0x70, 0xaf, 0x97, 0xf7, 0x8c, 0xfc, 0x2e, 0x98, 0x74, 0xe2, 0x96, 0x91, 0xfa, 0xa1, 0x54, 0xc1, + 0xb9, 0x52, 0xe3, 0x08, 0xd5, 0xa4, 0xa8, 0xa5, 0x7f, 0x1e, 0xf7, 0xba, 0x4c, 0x98, 0x4f, 0xa1, + 0xe0, 0x1f, 0xc0, 0xdc, 0xbe, 0xc7, 0xba, 0x1e, 0x63, 0x23, 0xbc, 0xbf, 0x08, 0xe6, 0xf3, 0xcc, + 0x8c, 0xe2, 0x77, 0x80, 0x9a, 0x3d, 0xd1, 0xfd, 0x8c, 0x92, 0xdc, 0x7d, 0x1c, 0x5b, 0xcb, 0xe1, + 0x58, 0x0c, 0x33, 0xdd, 0x5e, 0x4c, 0x3a, 0x2d, 0xd2, 0x0e, 0x83, 0x0e, 0xe3, 0xc6, 0x9c, 0xb5, + 0x73, 0xb4, 0xa4, 0xa2, 0x97, 0xce, 0x62, 0x14, 0x1f, 0x81, 0xb9, 0xe7, 0x04, 0x6d, 0xe2, 0x8f, + 0x43, 0x11, 0xbc, 0x06, 0xab, 0x15, 0xbb, 0xa5, 0x58, 0x45, 0x92, 0x87, 0x62, 0x15, 0x85, 0x93, + 0x51, 0xdc, 0x00, 0x54, 0xd8, 0x77, 0xf0, 0x06, 0x75, 0x58, 0x2c, 0xf1, 0x33, 0x8a, 0x3d, 0x58, + 0x6d, 0xe5, 0x82, 0xe5, 0xd8, 0x6b, 0x5f, 0x06, 0x4e, 0x97, 0x0c, 0x8d, 0xe2, 0x40, 0x30, 0x66, + 0x51, 0x9c, 0x7d, 0x2b, 0x96, 0x98, 0xc8, 0x59, 0x62, 0x1d, 0xac, 0xaa, 0xa3, 0x18, 0xc5, 0x1f, + 0x78, 0xc3, 0x96, 0x3e, 0x64, 0xad, 0x1e, 0x15, 0xb0, 0x79, 0xbc, 0x0d, 0x5b, 0x95, 0x8f, 0x3c, + 0xde, 0xa8, 0xe9, 0xcf, 0x1e, 0xf3, 0x4b, 0xfa, 0x98, 0x57, 0x8c, 0xfe, 0x21, 0x23, 0x75, 0xe5, + 0xaf, 0x78, 0x46, 0x97, 0x84, 0x3e, 0xb9, 0x35, 0xff, 0x77, 0x0d, 0xea, 0x79, 0x97, 0x0c, 0xc7, + 0x7a, 0x55, 0x09, 0xf7, 0x13, 0x25, 0x22, 0x26, 0xc4, 0xb3, 0xe5, 0x86, 0xa1, 0xeb, 0x93, 0x74, + 0x20, 0x73, 0xde, 0xbb, 0x68, 0xb4, 0xe2, 0xc8, 0x0b, 0xdc, 0x57, 0x8e, 0xdf, 0x23, 0x4a, 0xbc, + 0x7c, 0x0d, 0x77, 0x2f, 0x9c, 0x36, 0x79, 0x69, 0x1f, 0x09, 0x98, 0x3c, 0x58, 0x30, 0x63, 0x46, + 0x3f, 0x85, 0xe9, 0x28, 0xf4, 0xc9, 0x11, 0xb9, 0x26, 0xbe, 0x39, 0xc9, 0x25, 0xd7, 0x4a, 0x92, + 0x87, 0x41, 0xfc, 0xf8, 0x51, 0x2a, 0xd8, 0xe7, 0x46, 0x5f, 0x41, 0x8d, 0xbc, 0x37, 0xa7, 0x46, + 0x38, 0xad, 0x46, 0xde, 0x27, 0xbd, 0x9c, 0xce, 0x4a, 0x8c, 0xe2, 0x1f, 0xf7, 0xe1, 0xed, 0x93, + 0x73, 0x16, 0x47, 0x4e, 0x3b, 0x1e, 0xc5, 0x9f, 0x7f, 0x35, 0x60, 0xa1, 0x24, 0x34, 0xc0, 0xe6, + 0x5f, 0x89, 0x09, 0x5a, 0x33, 0x2b, 0xb4, 0xe7, 0xb2, 0xdd, 0x28, 0x2f, 0xa0, 0x1f, 0xc2, 0xa2, + 0x9b, 0x6f, 0x18, 0x9e, 0x3b, 0xec, 0x2d, 0x77, 0xca, 0x1d, 0x5b, 0xb7, 0x84, 0x3b, 0x60, 0xea, + 0xaf, 0xc1, 0x28, 0x7a, 0x2e, 0x30, 0x85, 0xba, 0x90, 0x45, 0x9a, 0x29, 0xde, 0xd8, 0xb2, 0xa4, + 0x46, 0x06, 0x1f, 0x83, 0xe9, 0xa6, 0x43, 0x81, 0xc3, 0x40, 0x7d, 0x9d, 0x06, 0x8d, 0x23, 0x54, + 0x2b, 0xd6, 0x0a, 0x56, 0x7c, 0x03, 0xab, 0x15, 0xfb, 0x8d, 0xe3, 0xa9, 0x7b, 0xf4, 0xdf, 0x79, + 0x48, 0x87, 0x94, 0xe8, 0x1b, 0xb8, 0xdf, 0xee, 0xcf, 0xe4, 0x50, 0x3d, 0x43, 0x16, 0xb9, 0xe9, + 0xa2, 0xb5, 0xac, 0x23, 0x33, 0x8a, 0xbe, 0x86, 0xe9, 0x77, 0x59, 0x7b, 0x8d, 0x16, 0x05, 0x93, + 0x3a, 0x00, 0xb0, 0x96, 0xca, 0xc4, 0x54, 0xee, 0x2a, 0xeb, 0x4e, 0xa5, 0x9c, 0xda, 0xd9, 0x4a, + 0xb9, 0x5c, 0x13, 0x8b, 0x9e, 0xc2, 0xac, 0xab, 0x8e, 0xf0, 0xd0, 0x4a, 0xe6, 0xa5, 0xc2, 0x20, + 0xd0, 0x32, 0xf5, 0x0b, 0x8c, 0xa2, 0x6f, 0x61, 0x86, 0x29, 0x23, 0x35, 0x94, 0xdd, 0xad, 0x30, + 0xc8, 0xb3, 0x56, 0xb4, 0x74, 0x46, 0xd1, 0x1f, 0x60, 0xc5, 0xd5, 0x8f, 0xbe, 0xd0, 0xe7, 0x85, + 0x53, 0xcb, 0xc3, 0x29, 0x0b, 0x0f, 0x63, 0x61, 0x14, 0x5d, 0x48, 0xef, 0x97, 0x47, 0x4c, 0xe8, + 0x8b, 0xfe, 0x06, 0x95, 0x23, 0x30, 0x6b, 0x7b, 0x38, 0x13, 0xa3, 0xe8, 0x05, 0xa0, 0xb8, 0x34, + 0xc8, 0x41, 0xeb, 0x42, 0x56, 0x3b, 0x66, 0xb2, 0x1e, 0x0c, 0x58, 0x65, 0x14, 0xb5, 0xc1, 0x74, + 0x2b, 0x26, 0x18, 0x08, 0xe7, 0x52, 0x4a, 0x3b, 0x7f, 0xb1, 0xbe, 0x18, 0xca, 0x93, 0xea, 0xed, + 0x96, 0x26, 0x07, 0x52, 0x6f, 0xed, 0x94, 0x43, 0xea, 0x5d, 0x31, 0x72, 0x38, 0x85, 0x45, 0xb7, + 0xdc, 0xcc, 0x23, 0xbd, 0x94, 0x8c, 0xb2, 0x8d, 0x41, 0xcb, 0xbc, 0xc0, 0xcc, 0x5d, 0xe6, 0xfb, + 0x6a, 0xb4, 0x2a, 0x44, 0xca, 0xdd, 0xbd, 0x65, 0x55, 0x2d, 0xc9, 0x2b, 0x17, 0x7a, 0x61, 0xf5, + 0xca, 0xe5, 0x2e, 0x5d, 0xbd, 0xb2, 0xae, 0x89, 0x3e, 0x86, 0x05, 0xaf, 0xd8, 0x86, 0xa2, 0x35, + 0x21, 0xa3, 0x6b, 0x89, 0xad, 0xf5, 0xea, 0xc5, 0x34, 0xa9, 0x65, 0x72, 0xca, 0xa4, 0x56, 0xdb, + 0x2a, 0x99, 0xd4, 0xf9, 0xee, 0xa6, 0xe4, 0xcd, 0x04, 0xd3, 0x57, 0x78, 0x53, 0xf4, 0x20, 0x15, + 0xde, 0x94, 0xcd, 0xc0, 0xb7, 0x30, 0xd3, 0x51, 0xd0, 0xb7, 0xcc, 0xf1, 0x02, 0x7e, 0x97, 0x39, + 0x5e, 0x84, 0xea, 0x89, 0xe3, 0xba, 0x79, 0x4c, 0x2b, 0x1d, 0x57, 0x46, 0xce, 0xd2, 0x71, 0x1a, + 0x18, 0x8c, 0x5e, 0x43, 0xbd, 0xad, 0xc3, 0xc8, 0x68, 0x33, 0xab, 0xa9, 0x15, 0x78, 0xdc, 0xda, + 0x1a, 0xcc, 0x90, 0x5a, 0x5c, 0x6a, 0x29, 0x2d, 0xae, 0x62, 0x66, 0x69, 0xf1, 0x1c, 0x30, 0x4e, + 0x6e, 0x57, 0xd0, 0x49, 0xde, 0xae, 0x8c, 0xbb, 0xe5, 0xed, 0x34, 0x10, 0x5b, 0xd4, 0x42, 0x1d, + 0xba, 0x54, 0x6b, 0x61, 0x05, 0xf2, 0x55, 0x6b, 0x61, 0x25, 0x40, 0x4d, 0xa3, 0xa3, 0x80, 0x0f, + 0xd5, 0xe8, 0x28, 0xe3, 0x4d, 0x35, 0x3a, 0x74, 0xc0, 0xf2, 0x0d, 0x2c, 0x33, 0x2d, 0x58, 0x47, + 0x5b, 0x85, 0x9a, 0x5f, 0x6a, 0x1b, 0xac, 0xcf, 0x87, 0x70, 0xa4, 0x1a, 0xb3, 0x12, 0xa4, 0x92, + 0x1a, 0x6b, 0x31, 0xa9, 0xd4, 0x58, 0x8f, 0xc5, 0xd0, 0x6f, 0x61, 0xc9, 0xd5, 0x80, 0x18, 0x54, + 0xac, 0x3f, 0x05, 0xa0, 0x66, 0x6d, 0x0e, 0x5c, 0x4f, 0xa3, 0x53, 0x8b, 0x33, 0x64, 0x74, 0x56, + 0xa1, 0x1a, 0x19, 0x9d, 0x95, 0x30, 0xe5, 0xe9, 0xe6, 0xeb, 0x07, 0x27, 0x94, 0x04, 0x67, 0x87, + 0x4d, 0xe5, 0x1f, 0x9a, 0x5c, 0xe8, 0xe7, 0xfc, 0xf7, 0x7c, 0x8a, 0x93, 0x1e, 0xff, 0x2f, 0x00, + 0x00, 0xff, 0xff, 0xe8, 0xd2, 0xc8, 0xfe, 0x43, 0x1d, 0x00, 0x00, } diff --git a/pkg/proto/group/group.proto b/pkg/proto/group/group.proto index 69b38fd9d..e463419a6 100644 --- a/pkg/proto/group/group.proto +++ b/pkg/proto/group/group.proto @@ -181,8 +181,7 @@ message GetGroupMembersCMSReq { message GetGroupMembersCMSResp { repeated server_api_params.GroupMemberFullInfo members = 1; - server_api_params.ResponsePagination pagination = 2; - int32 memberNums = 3; + int32 memberNums = 2; } message DismissGroupReq{ diff --git a/pkg/utils/utils_v2.go b/pkg/utils/utils_v2.go index cabf9067e..88123808a 100644 --- a/pkg/utils/utils_v2.go +++ b/pkg/utils/utils_v2.go @@ -5,7 +5,7 @@ import ( "sort" ) -// DistinctAny remove duplicate elements +// DistinctAny 去重 func DistinctAny[E any, K comparable](es []E, fn func(e E) K) []E { v := make([]E, 0, len(es)) tmp := map[K]struct{}{} @@ -20,14 +20,14 @@ func DistinctAny[E any, K comparable](es []E, fn func(e E) K) []E { return v } -// Distinct remove duplicate elements +// Distinct 去重 func Distinct[T comparable](ts []T) []T { return DistinctAny(ts, func(t T) T { return t }) } -// Delete delete slice element, support negative number to delete the penultimate +// Delete 删除切片元素, 支持负数删除倒数第几个 func Delete[E any](es []E, index ...int) []E { switch len(index) { case 0: @@ -59,7 +59,7 @@ func Delete[E any](es []E, index ...int) []E { } } -// DeleteAt delete slice element, support negative number to delete the penultimate +// DeleteAt 删除切片元素, 支持负数删除倒数第几个 func DeleteAt[E any](es *[]E, index ...int) []E { v := Delete(*es, index...) *es = v @@ -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,18 +78,18 @@ 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 include element or not -func Contain[E comparable](es []E, e E) bool { - return IndexOf(es, e) >= 0 +// Contain 是否包含 +func Contain[E comparable](e E, es ...E) bool { + return IndexOf(e, es...) >= 0 } -// DuplicateAny judge whether it is repeated +// DuplicateAny 是否有重复的 func DuplicateAny[E any, K comparable](es []E, fn func(e E) K) bool { t := make(map[K]struct{}) for _, e := range es { @@ -102,14 +102,14 @@ func DuplicateAny[E any, K comparable](es []E, fn func(e E) K) bool { return false } -// Duplicate judge whether it is repeated +// Duplicate 是否有重复的 func Duplicate[E comparable](es []E) bool { return DuplicateAny(es, func(e E) E { return e }) } -// SliceToMapOkAny slice to map +// SliceToMapOkAny slice to map (自定义类型, 筛选) func SliceToMapOkAny[E any, K comparable, V any](es []E, fn func(e E) (K, V, bool)) map[K]V { kv := make(map[K]V) for i := 0; i < len(es); i++ { @@ -121,7 +121,7 @@ func SliceToMapOkAny[E any, K comparable, V any](es []E, fn func(e E) (K, V, boo return kv } -// SliceToMapAny slice to map +// SliceToMapAny slice to map (自定义类型) func SliceToMapAny[E any, K comparable, V any](es []E, fn func(e E) (K, V)) map[K]V { return SliceToMapOkAny(es, func(e E) (K, V, bool) { k, v := fn(e) @@ -144,6 +144,15 @@ func SliceSetAny[E any, K comparable](es []E, fn func(e E) K) map[K]struct{} { }) } +// Slice 批量转换切片类型 +func Slice[E any, T any](es []E, fn func(e E) T) []T { + v := make([]T, len(es)) + for i := 0; i < len(es); i++ { + v = append(v, fn(es[i])) + } + return v +} + // SliceSet slice to map[E]struct{} func SliceSet[E comparable](es []E) map[E]struct{} { return SliceSetAny(es, func(e E) E { @@ -182,7 +191,7 @@ func Max[E Ordered](e ...E) E { return v } -// BothExistAny get elements common to multiple slices +// BothExistAny 获取切片中共同存在的元素(交集) func BothExistAny[E any, K comparable](es [][]E, fn func(e E) K) []E { if len(es) == 0 { return []E{} @@ -225,43 +234,40 @@ func BothExistAny[E any, K comparable](es [][]E, fn func(e E) K) []E { return v } -// BothExist get elements common to multiple slices +// BothExist 获取切片中共同存在的元素(交集) func BothExist[E comparable](es ...[]E) []E { return BothExistAny(es, func(e E) E { return e }) } -// CompleteAny complete inclusion -func CompleteAny[K comparable, E any](ks []K, es []E, fn func(e E) K) bool { - a := SliceSetAny(es, fn) - for k := range SliceSet(ks) { - if !HasKey(a, k) { - return false - } - delete(a, k) - } - return len(a) == 0 -} +//// CompleteAny a中存在b的所有元素, 同时b中的所有元素a +//func CompleteAny[K comparable, E any](ks []K, es []E, fn func(e E) K) bool { +// if len(ks) == 0 && len(es) == 0 { +// return true +// } +// kn := make(map[K]uint8) +// for _, e := range Distinct(ks) { +// kn[e]++ +// } +// for k := range SliceSetAny(es, fn) { +// kn[k]++ +// } +// for _, n := range kn { +// if n != 2 { +// return false +// } +// } +// return true +//} +// Complete a和b去重后是否相等(忽略顺序) func Complete[E comparable](a []E, b []E) bool { - if len(a) == 0 && len(b) == 0 { - return true - } - if (len(a) == 0 && len(b) != 0) || (len(a) != 0 && len(b) == 0) { - return false - } - t := SliceSet(a) - for _, e := range b { - if _, ok := t[e]; !ok { - return false - } - } - return true + return len(Single(a, b)) == 0 } -// MapKey get map keys -func MapKey[K comparable, V any](kv map[K]V) []K { +// Keys get map keys +func Keys[K comparable, V any](kv map[K]V) []K { ks := make([]K, 0, len(kv)) for k := range kv { ks = append(ks, k) @@ -269,8 +275,8 @@ func MapKey[K comparable, V any](kv map[K]V) []K { return ks } -// MapValue get map values -func MapValue[K comparable, V any](kv map[K]V) []V { +// Values get map values +func Values[K comparable, V any](kv map[K]V) []V { vs := make([]V, 0, len(kv)) for k := range kv { vs = append(vs, kv[k]) @@ -306,6 +312,7 @@ func If[T any](isa bool, a, b T) T { return b } +// Equal 比较切片是否相对(包括元素顺序) func Equal[E comparable](a []E, b []E) bool { if len(a) != len(b) { return false @@ -318,11 +325,50 @@ func Equal[E comparable](a []E, b []E) bool { return true } -// Single - +// Single a中存在,b中不存在 或 b中存在,a中不存在 func Single[E comparable](a, b []E) []E { + kn := make(map[E]uint8) + for _, e := range Distinct(a) { + kn[e]++ + } + for _, e := range Distinct(b) { + kn[e]++ + } + v := make([]E, 0, len(kn)) + for k, n := range kn { + if n == 1 { + v = append(v, k) + } + } + return v +} - return nil +// Order 将ts按es排序 +func Order[E comparable, T any](es []E, ts []T, fn func(t T) E) []T { + if len(es) == 0 || len(ts) == 0 { + return ts + } + kv := make(map[E][]T) + for i := 0; i < len(ts); i++ { + t := ts[i] + k := fn(t) + kv[k] = append(kv[k], t) + } + rs := make([]T, 0, len(ts)) + for _, e := range es { + vs := kv[e] + delete(kv, e) + rs = append(rs, vs...) + } + for k := range kv { + rs = append(rs, kv[k]...) + } + return rs +} + +func OrderPtr[E comparable, T any](es []E, ts *[]T, fn func(t T) E) []T { + *ts = Order(es, *ts, fn) + return *ts } func UniqueJoin(s ...string) string { diff --git a/pkg/utils/utils_v2_test.go b/pkg/utils/utils_v2_test.go index 270cf4d69..bea4dfdf6 100644 --- a/pkg/utils/utils_v2_test.go +++ b/pkg/utils/utils_v2_test.go @@ -75,9 +75,9 @@ func TestCompleteAny(t *testing.T) { DeleteAt(&list, -1) DeleteAt(&ids, -1) - ok := CompleteAny(ids, list, func(t Item) int { + ok := Complete(ids, Slice(list, func(t Item) int { return t.ID - }) + })) fmt.Printf("%+v\n", ok)