feat: optimize friend and group applications

pull/3384/head
withchao 4 months ago
parent f86b90fbfb
commit cf0ebe5c75

@ -12,7 +12,7 @@ require (
github.com/gorilla/websocket v1.5.1
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/mitchellh/mapstructure v1.5.0
github.com/openimsdk/protocol v0.0.73-alpha.10
github.com/openimsdk/protocol v0.0.73-alpha.11
github.com/openimsdk/tools v0.0.50-alpha.83
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.18.0
@ -219,5 +219,3 @@ require (
golang.org/x/crypto v0.27.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
//replace github.com/openimsdk/protocol => /Users/chao/Desktop/code/protocol

@ -347,8 +347,8 @@ github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y=
github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
github.com/openimsdk/gomake v0.0.15-alpha.5 h1:eEZCEHm+NsmcO3onXZPIUbGFCYPYbsX5beV3ZyOsGhY=
github.com/openimsdk/gomake v0.0.15-alpha.5/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
github.com/openimsdk/protocol v0.0.73-alpha.10 h1:gytT3OaDj+WvccptvGXRqxtLSotIV0ZbzO0eymaUZRo=
github.com/openimsdk/protocol v0.0.73-alpha.10/go.mod h1:WF7EuE55vQvpyUAzDXcqg+B+446xQyEba0X35lTINmw=
github.com/openimsdk/protocol v0.0.73-alpha.11 h1:afrnUPNDLf1rEGmzhSdY/FEjGMeoVtwVFAv6t9c2wxA=
github.com/openimsdk/protocol v0.0.73-alpha.11/go.mod h1:WF7EuE55vQvpyUAzDXcqg+B+446xQyEba0X35lTINmw=
github.com/openimsdk/tools v0.0.50-alpha.83 h1:7c1D40YGqIWUmGfCII5pduETGC/8c2DyS9SQ4LvoplU=
github.com/openimsdk/tools v0.0.50-alpha.83/go.mod h1:n2poR3asX1e1XZce4O+MOWAp+X02QJRFvhcLCXZdzRo=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=

@ -114,3 +114,7 @@ func (o *FriendApi) GetIncrementalBlacks(c *gin.Context) {
func (o *FriendApi) GetFullFriendUserIDs(c *gin.Context) {
a2r.Call(c, relation.FriendClient.GetFullFriendUserIDs, o.Client)
}
func (o *FriendApi) GetSelfUnhandledApplyCount(c *gin.Context) {
a2r.Call(c, relation.FriendClient.GetSelfUnhandledApplyCount, o.Client)
}

@ -165,3 +165,7 @@ func (o *GroupApi) GetFullGroupMemberUserIDs(c *gin.Context) {
func (o *GroupApi) GetFullJoinGroupIDs(c *gin.Context) {
a2r.Call(c, group.GroupClient.GetFullJoinGroupIDs, o.Client)
}
func (o *GroupApi) GetGroupApplicationUnhandledCount(c *gin.Context) {
a2r.Call(c, group.GroupClient.GetGroupApplicationUnhandledCount, o.Client)
}

@ -156,6 +156,7 @@ func newGinRouter(ctx context.Context, client discovery.Conn, cfg *Config) (*gin
friendRouterGroup.POST("/update_friends", f.UpdateFriends)
friendRouterGroup.POST("/get_incremental_friends", f.GetIncrementalFriends)
friendRouterGroup.POST("/get_full_friend_user_ids", f.GetFullFriendUserIDs)
friendRouterGroup.POST("/get_self_unhandled_apply_count", f.GetSelfUnhandledApplyCount)
}
g := NewGroupApi(group.NewGroupClient(groupConn))
@ -192,6 +193,7 @@ func newGinRouter(ctx context.Context, client discovery.Conn, cfg *Config) (*gin
groupRouterGroup.POST("/get_incremental_group_members_batch", g.GetIncrementalGroupMemberBatch)
groupRouterGroup.POST("/get_full_group_member_user_ids", g.GetFullGroupMemberUserIDs)
groupRouterGroup.POST("/get_full_join_group_ids", g.GetFullJoinGroupIDs)
groupRouterGroup.POST("/get_group_application_unhandled_count", g.GetGroupApplicationUnhandledCount)
}
// certificate
{

@ -20,6 +20,7 @@ import (
"fmt"
"time"
"github.com/google/uuid"
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
"go.mongodb.org/mongo-driver/mongo"
@ -365,6 +366,10 @@ func (g *NotificationSender) GroupInfoSetAnnouncementNotification(ctx context.Co
g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetAnnouncementNotification, tips, notification.WithRpcGetUserName(), notification.WithSendMessage(sendMessage))
}
func (g *NotificationSender) uuid() string {
return uuid.New().String()
}
func (g *NotificationSender) JoinGroupApplicationNotification(ctx context.Context, req *pbgroup.JoinGroupReq) {
var err error
defer func() {
@ -387,7 +392,7 @@ func (g *NotificationSender) JoinGroupApplicationNotification(ctx context.Contex
return
}
userIDs = append(userIDs, req.InviterUserID, mcontext.GetOpUserID(ctx))
tips := &sdkws.JoinGroupApplicationTips{Group: group, Applicant: user, ReqMsg: req.ReqMessage}
tips := &sdkws.JoinGroupApplicationTips{Group: group, Applicant: user, ReqMsg: req.ReqMessage, Uuid: g.uuid()}
for _, userID := range datautil.Distinct(userIDs) {
g.Notification(ctx, mcontext.GetOpUserID(ctx), userID, constant.JoinGroupApplicationNotification, tips)
}
@ -432,8 +437,8 @@ func (g *NotificationSender) GroupApplicationAcceptedNotification(ctx context.Co
if err = g.fillOpUser(ctx, &opUser, group.GroupID); err != nil {
return
}
tips := &sdkws.GroupApplicationAcceptedTips{Group: group, OpUser: opUser, HandleMsg: req.HandledMsg, Uuid: g.uuid()}
for _, userID := range append(userIDs, req.FromUserID) {
tips := &sdkws.GroupApplicationAcceptedTips{Group: group, OpUser: opUser, HandleMsg: req.HandledMsg}
if userID == req.FromUserID {
tips.ReceiverAs = applicantReceiver
} else {
@ -465,8 +470,8 @@ func (g *NotificationSender) GroupApplicationRejectedNotification(ctx context.Co
if err = g.fillOpUser(ctx, &opUser, group.GroupID); err != nil {
return
}
tips := &sdkws.GroupApplicationRejectedTips{Group: group, OpUser: opUser, HandleMsg: req.HandledMsg, Uuid: g.uuid()}
for _, userID := range append(userIDs, req.FromUserID) {
tips := &sdkws.GroupApplicationAcceptedTips{Group: group, OpUser: opUser, HandleMsg: req.HandledMsg}
if userID == req.FromUserID {
tips.ReceiverAs = applicantReceiver
} else {

@ -341,7 +341,10 @@ func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *rel
return nil, err
}
total, friendRequests, err := s.db.PageFriendRequestToMe(ctx, req.UserID, req.Pagination)
handleResults := datautil.Slice(req.HandleResults, func(e int32) int {
return int(e)
})
total, friendRequests, err := s.db.PageFriendRequestToMe(ctx, req.UserID, handleResults, req.Pagination)
if err != nil {
return nil, err
}
@ -358,17 +361,19 @@ func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *rel
}
func (s *friendServer) GetPaginationFriendsApplyFrom(ctx context.Context, req *relation.GetPaginationFriendsApplyFromReq) (resp *relation.GetPaginationFriendsApplyFromResp, err error) {
resp = &relation.GetPaginationFriendsApplyFromResp{}
if err := authverify.CheckAccess(ctx, req.UserID); err != nil {
return nil, err
}
total, friendRequests, err := s.db.PageFriendRequestFromMe(ctx, req.UserID, req.Pagination)
handleResults := datautil.Slice(req.HandleResults, func(e int32) int {
return int(e)
})
total, friendRequests, err := s.db.PageFriendRequestFromMe(ctx, req.UserID, handleResults, req.Pagination)
if err != nil {
return nil, err
}
resp = &relation.GetPaginationFriendsApplyFromResp{}
resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.userClient.GetUsersInfoMap)
if err != nil {
return nil, err
@ -544,3 +549,18 @@ func (s *friendServer) UpdateFriends(ctx context.Context, req *relation.UpdateFr
s.notificationSender.FriendsInfoUpdateNotification(ctx, req.OwnerUserID, req.FriendUserIDs)
return resp, nil
}
func (s *friendServer) GetSelfUnhandledApplyCount(ctx context.Context, req *relation.GetSelfUnhandledApplyCountReq) (*relation.GetSelfUnhandledApplyCountResp, error) {
if err := authverify.CheckAccess(ctx, req.UserID); err != nil {
return nil, err
}
count, err := s.db.GetUnhandledCount(ctx, req.UserID, req.Time)
if err != nil {
return nil, err
}
return &relation.GetSelfUnhandledApplyCountResp{
Count: count,
}, nil
}

@ -17,10 +17,11 @@ package controller
import (
"context"
"fmt"
"time"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
"time"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
"github.com/openimsdk/protocol/constant"
@ -61,10 +62,10 @@ type FriendDatabase interface {
PageInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*model.Friend, err error)
// PageFriendRequestFromMe retrieves the friend requests sent by the user with pagination
PageFriendRequestFromMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error)
PageFriendRequestFromMe(ctx context.Context, userID string, handleResults []int, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error)
// PageFriendRequestToMe retrieves the friend requests received by the user with pagination
PageFriendRequestToMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error)
PageFriendRequestToMe(ctx context.Context, userID string, handleResults []int, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error)
// FindFriendsWithError fetches specified friends of a user and returns an error if any do not exist
FindFriendsWithError(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*model.Friend, err error)
@ -87,6 +88,8 @@ type FriendDatabase interface {
FindFriendUserID(ctx context.Context, friendUserID string) ([]string, error)
OwnerIncrVersion(ctx context.Context, ownerUserID string, friendUserIDs []string, state int32) error
GetUnhandledCount(ctx context.Context, userID string, ts int64) (int64, error)
}
type friendDatabase struct {
@ -334,13 +337,13 @@ func (f *friendDatabase) PageInWhoseFriends(ctx context.Context, friendUserID st
}
// PageFriendRequestFromMe retrieves friend requests sent by me. It does not return an error if the result is empty.
func (f *friendDatabase) PageFriendRequestFromMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error) {
return f.friendRequest.FindFromUserID(ctx, userID, pagination)
func (f *friendDatabase) PageFriendRequestFromMe(ctx context.Context, userID string, handleResults []int, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error) {
return f.friendRequest.FindFromUserID(ctx, userID, handleResults, pagination)
}
// PageFriendRequestToMe retrieves friend requests received by me. It does not return an error if the result is empty.
func (f *friendDatabase) PageFriendRequestToMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error) {
return f.friendRequest.FindToUserID(ctx, userID, pagination)
func (f *friendDatabase) PageFriendRequestToMe(ctx context.Context, userID string, handleResults []int, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error) {
return f.friendRequest.FindToUserID(ctx, userID, handleResults, pagination)
}
// FindFriendsWithError retrieves specified friends' information for ownerUserID. Returns an error if any friend does not exist.
@ -397,3 +400,7 @@ func (f *friendDatabase) OwnerIncrVersion(ctx context.Context, ownerUserID strin
}
return f.cache.DelMaxFriendVersion(ownerUserID).ChainExecDel(ctx)
}
func (f *friendDatabase) GetUnhandledCount(ctx context.Context, userID string, ts int64) (int64, error) {
return f.friendRequest.GetUnhandledCount(ctx, userID, ts)
}

@ -16,6 +16,7 @@ package database
import (
"context"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
"github.com/openimsdk/tools/db/pagination"
)
@ -33,8 +34,9 @@ type FriendRequest interface {
Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *model.FriendRequest, err error)
Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *model.FriendRequest, err error)
// Get list of friend requests received by toUserID
FindToUserID(ctx context.Context, toUserID string, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error)
FindToUserID(ctx context.Context, toUserID string, handleResults []int, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error)
// Get list of friend requests sent by fromUserID
FindFromUserID(ctx context.Context, fromUserID string, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error)
FindFromUserID(ctx context.Context, fromUserID string, handleResults []int, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error)
FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*model.FriendRequest, err error)
GetUnhandledCount(ctx context.Context, userID string, ts int64) (int64, error)
}

@ -16,24 +16,32 @@ package mgo
import (
"context"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
"go.mongodb.org/mongo-driver/mongo/options"
"github.com/openimsdk/tools/db/mongoutil"
"github.com/openimsdk/tools/db/pagination"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func NewFriendRequestMongo(db *mongo.Database) (database.FriendRequest, error) {
coll := db.Collection(database.FriendRequestName)
_, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
Keys: bson.D{
{Key: "from_user_id", Value: 1},
{Key: "to_user_id", Value: 1},
_, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{
{
Keys: bson.D{
{Key: "from_user_id", Value: 1},
{Key: "to_user_id", Value: 1},
},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{
{Key: "create_time", Value: -1},
},
},
Options: options.Index().SetUnique(true),
})
if err != nil {
return nil, err
@ -45,12 +53,24 @@ type FriendRequestMgo struct {
coll *mongo.Collection
}
func (f *FriendRequestMgo) FindToUserID(ctx context.Context, toUserID string, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error) {
return mongoutil.FindPage[*model.FriendRequest](ctx, f.coll, bson.M{"to_user_id": toUserID}, pagination)
func (f *FriendRequestMgo) sort() any {
return bson.E{Key: "create_time", Value: -1}
}
func (f *FriendRequestMgo) FindFromUserID(ctx context.Context, fromUserID string, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error) {
return mongoutil.FindPage[*model.FriendRequest](ctx, f.coll, bson.M{"from_user_id": fromUserID}, pagination)
func (f *FriendRequestMgo) FindToUserID(ctx context.Context, toUserID string, handleResults []int, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error) {
filter := bson.M{"to_user_id": toUserID}
if len(handleResults) > 0 {
filter["handle_result"] = bson.M{"$in": handleResults}
}
return mongoutil.FindPage[*model.FriendRequest](ctx, f.coll, filter, pagination, options.Find().SetSort(f.sort()))
}
func (f *FriendRequestMgo) FindFromUserID(ctx context.Context, fromUserID string, handleResults []int, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error) {
filter := bson.M{"from_user_id": fromUserID}
if len(handleResults) > 0 {
filter["handle_result"] = bson.M{"$in": handleResults}
}
return mongoutil.FindPage[*model.FriendRequest](ctx, f.coll, filter, pagination, options.Find().SetSort(f.sort()))
}
func (f *FriendRequestMgo) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*model.FriendRequest, err error) {
@ -110,3 +130,11 @@ func (f *FriendRequestMgo) Find(ctx context.Context, fromUserID, toUserID string
func (f *FriendRequestMgo) Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *model.FriendRequest, err error) {
return f.Find(ctx, fromUserID, toUserID)
}
func (f *FriendRequestMgo) GetUnhandledCount(ctx context.Context, userID string, ts int64) (int64, error) {
filter := bson.M{"to_user_id": userID, "handle_result": 0}
if ts != 0 {
filter["req_time"] = bson.M{"$gt": ts}
}
return mongoutil.Count(ctx, f.coll, filter)
}

@ -31,12 +31,19 @@ import (
func NewGroupRequestMgo(db *mongo.Database) (database.GroupRequest, error) {
coll := db.Collection(database.GroupRequestName)
_, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
Keys: bson.D{
{Key: "group_id", Value: 1},
{Key: "user_id", Value: 1},
_, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{
{
Keys: bson.D{
{Key: "group_id", Value: 1},
{Key: "user_id", Value: 1},
},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{
{Key: "req_time", Value: -1},
},
},
Options: options.Index().SetUnique(true),
})
if err != nil {
return nil, errs.Wrap(err)
@ -69,7 +76,7 @@ func (g *GroupRequestMgo) FindGroupRequests(ctx context.Context, groupID string,
}
func (g *GroupRequestMgo) sort() any {
return bson.E{Key: "_id", Value: -1}
return bson.E{Key: "req_time", Value: -1}
}
func (g *GroupRequestMgo) Page(ctx context.Context, userID string, groupIDs []string, handleResults []int, pagination pagination.Pagination) (total int64, groups []*model.GroupRequest, err error) {
@ -98,6 +105,9 @@ func (g *GroupRequestMgo) GetUnhandledCount(ctx context.Context, groupIDs []stri
if len(groupIDs) == 0 {
return 0, nil
}
return 0, nil
filter := bson.M{"group_id": bson.M{"$in": groupIDs}, "handle_result": 0}
if ts != 0 {
filter["req_time"] = bson.M{"$gt": ts}
}
return mongoutil.Count(ctx, g.coll, filter)
}

Loading…
Cancel
Save