好友置顶

pull/3727/head
hawklin2017 2 months ago
parent 7859fa2f2a
commit a3bda263a7

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

@ -190,6 +190,7 @@ func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, co
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)
friendRouterGroup.POST("/get_pinned_friend_ids", f.GetPinnedFriendIDs)
}
g := NewGroupApi(group.NewGroupClient(groupConn))

@ -34,12 +34,15 @@ import (
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller"
"github.com/openimsdk/open-im-server/v3/pkg/util/conversationutil"
"github.com/openimsdk/protocol/constant"
conversationpb "github.com/openimsdk/protocol/conversation"
"github.com/openimsdk/protocol/relation"
"github.com/openimsdk/protocol/sdkws"
"github.com/openimsdk/tools/db/mongoutil"
"github.com/openimsdk/tools/discovery"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
"github.com/openimsdk/tools/utils/datautil"
"google.golang.org/grpc"
)
@ -54,6 +57,7 @@ type friendServer struct {
webhookClient *webhook.Client
queue *memamq.MemoryQueue
userClient *rpcli.UserClient
conversationClient *rpcli.ConversationClient
}
type Config struct {
@ -101,6 +105,10 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
if err != nil {
return err
}
conversationConn, err := client.GetConn(ctx, config.Share.RpcRegisterName.Conversation)
if err != nil {
return err
}
userClient := rpcli.NewUserClient(userConn)
database := controller.NewFriendDatabase(
@ -131,6 +139,7 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
webhookClient: webhook.NewWebhookClient(config.WebhooksConfig.URL),
queue: memamq.NewMemoryQueue(16, 1024*1024),
userClient: userClient,
conversationClient: rpcli.NewConversationClient(conversationConn),
})
return nil
}
@ -549,6 +558,22 @@ func (s *friendServer) UpdateFriends(
return nil, err
}
if req.IsPinned != nil {
for _, friendUserID := range req.FriendUserIDs {
convID := conversationutil.GenConversationIDForSingle(req.OwnerUserID, friendUserID)
if err := s.conversationClient.SetConversations(ctx, []string{req.OwnerUserID},
&conversationpb.ConversationReq{
ConversationID: convID,
ConversationType: constant.SingleChatType,
UserID: friendUserID,
IsPinned: req.IsPinned,
}); err != nil {
log.ZWarn(ctx, "sync conversation isPinned failed", err,
"ownerUserID", req.OwnerUserID, "friendUserID", friendUserID)
}
}
}
resp := &relation.UpdateFriendsResp{}
s.notificationSender.FriendsInfoUpdateNotification(ctx, req.OwnerUserID, req.FriendUserIDs)
@ -570,6 +595,17 @@ func (s *friendServer) GetSelfUnhandledApplyCount(ctx context.Context, req *rela
}, nil
}
func (s *friendServer) GetPinnedFriendIDs(ctx context.Context, req *relation.GetPinnedFriendIDsReq) (*relation.GetPinnedFriendIDsResp, error) {
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
return nil, err
}
ids, err := s.db.GetPinnedFriendIDs(ctx, req.UserID)
if err != nil {
return nil, err
}
return &relation.GetPinnedFriendIDsResp{FriendUserIDs: ids}, nil
}
func (s *friendServer) getCommonUserMap(ctx context.Context, userIDs []string) (map[string]common_user.CommonUser, error) {
users, err := s.userClient.GetUsersInfo(ctx, userIDs)
if err != nil {

@ -90,6 +90,8 @@ type FriendDatabase interface {
OwnerIncrVersion(ctx context.Context, ownerUserID string, friendUserIDs []string, state int32) error
GetUnhandledCount(ctx context.Context, userID string, ts int64) (int64, error)
GetPinnedFriendIDs(ctx context.Context, ownerUserID string) ([]string, error)
}
type friendDatabase struct {
@ -402,3 +404,7 @@ func (f *friendDatabase) OwnerIncrVersion(ctx context.Context, ownerUserID strin
func (f *friendDatabase) GetUnhandledCount(ctx context.Context, userID string, ts int64) (int64, error) {
return f.friendRequest.GetUnhandledCount(ctx, userID, ts)
}
func (f *friendDatabase) GetPinnedFriendIDs(ctx context.Context, ownerUserID string) ([]string, error) {
return f.friend.FindPinnedFriendUserIDs(ctx, ownerUserID)
}

@ -57,4 +57,6 @@ type Friend interface {
FindOwnerFriendUserIds(ctx context.Context, ownerUserID string, limit int) ([]string, error)
IncrVersion(ctx context.Context, ownerUserID string, friendUserIDs []string, state int32) error
FindPinnedFriendUserIDs(ctx context.Context, ownerUserID string) ([]string, error)
}

@ -47,6 +47,17 @@ func NewFriendMongo(db *mongo.Database) (database.Friend, error) {
if err != nil {
return nil, err
}
// Compound index to support efficient sorted pagination: pinned friends first, then by _id.
_, err = coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
Keys: bson.D{
{Key: "owner_user_id", Value: 1},
{Key: "is_pinned", Value: -1},
{Key: "_id", Value: 1},
},
})
if err != nil {
return nil, err
}
owner, err := NewVersionLog(db.Collection(database.FriendVersionName))
if err != nil {
return nil, err
@ -268,3 +279,10 @@ func (f *FriendMgo) IsUpdateIsPinned(data map[string]any) bool {
_, ok := data["is_pinned"]
return ok
}
func (f *FriendMgo) FindPinnedFriendUserIDs(ctx context.Context, ownerUserID string) ([]string, error) {
return mongoutil.Find[string](ctx, f.coll, bson.M{
"owner_user_id": ownerUserID,
"is_pinned": true,
}, options.Find().SetProjection(bson.M{"_id": 0, "friend_user_id": 1}))
}

Loading…
Cancel
Save