好友、群置顶

This commit is contained in:
hawklin2017 2026-05-13 11:06:36 +08:00
parent 25e79e4b77
commit 3b50bd1b18
6 changed files with 128 additions and 1 deletions

View File

@ -134,3 +134,11 @@ func (o *FriendApi) SetMute(c *gin.Context) {
func (o *FriendApi) GetMute(c *gin.Context) {
a2r.Call(c, relation.FriendClient.GetMute, o.Client)
}
func (o *FriendApi) PinFriend(c *gin.Context) {
a2r.Call(c, relation.FriendClient.PinFriend, o.Client)
}
func (o *FriendApi) UnpinFriend(c *gin.Context) {
a2r.Call(c, relation.FriendClient.UnpinFriend, o.Client)
}

View File

@ -193,3 +193,11 @@ func (o *GroupApi) SetGroupMute(c *gin.Context) {
func (o *GroupApi) GetGroupMute(c *gin.Context) {
a2r.Call(c, group.GroupClient.GetGroupMute, o.Client)
}
func (o *GroupApi) PinGroup(c *gin.Context) {
a2r.Call(c, group.GroupClient.PinGroup, o.Client)
}
func (o *GroupApi) UnpinGroup(c *gin.Context) {
a2r.Call(c, group.GroupClient.UnpinGroup, o.Client)
}

View File

@ -223,6 +223,9 @@ func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, co
friendRouterGroup.POST("/add_oneway_friend", f.AddOnewayFriend)
friendRouterGroup.POST("/set_mute", f.SetMute)
friendRouterGroup.POST("/get_mute", f.GetMute)
// 好友会话置顶 / 取消置顶(同步写入 friend.is_pinned 与 conversation.isPinned
friendRouterGroup.POST("/pin", f.PinFriend)
friendRouterGroup.POST("/unpin", f.UnpinFriend)
}
g := NewGroupApi(group.NewGroupClient(groupConn))
@ -266,6 +269,9 @@ func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, co
groupRouterGroup.POST("/get_group_pinned_messages", g.GetGroupPinnedMessages)
groupRouterGroup.POST("/set_mute", g.SetGroupMute)
groupRouterGroup.POST("/get_mute", g.GetGroupMute)
// 群会话置顶 / 取消置顶(同步写入 conversation.isPinned
groupRouterGroup.POST("/pin", g.PinGroup)
groupRouterGroup.POST("/unpin", g.UnpinGroup)
}
// certificate
{

View File

@ -0,0 +1,49 @@
package group
import (
"context"
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
"github.com/openimsdk/protocol/constant"
pbconversation "github.com/openimsdk/protocol/conversation"
pbgroup "github.com/openimsdk/protocol/group"
"github.com/openimsdk/protocol/wrapperspb"
"github.com/openimsdk/tools/mcontext"
)
// PinGroup pins the group conversation for the current operator
// (syncs conversation.isPinned = true via the conversation service).
func (s *groupServer) PinGroup(ctx context.Context, req *pbgroup.PinGroupReq) (*pbgroup.PinGroupResp, error) {
if err := s.setGroupConversationPinned(ctx, req.GroupID, true); err != nil {
return nil, err
}
return &pbgroup.PinGroupResp{}, nil
}
// UnpinGroup unpins the group conversation for the current operator
// (syncs conversation.isPinned = false via the conversation service).
func (s *groupServer) UnpinGroup(ctx context.Context, req *pbgroup.UnpinGroupReq) (*pbgroup.UnpinGroupResp, error) {
if err := s.setGroupConversationPinned(ctx, req.GroupID, false); err != nil {
return nil, err
}
return &pbgroup.UnpinGroupResp{}, nil
}
func (s *groupServer) setGroupConversationPinned(ctx context.Context, groupID string, pinned bool) error {
opUserID := mcontext.GetOpUserID(ctx)
if opUserID == "" {
return servererrs.ErrNoPermission.WrapMsg("op user id is empty")
}
// Must be a member of the group to pin / unpin its conversation.
if _, err := s.db.TakeGroupMember(ctx, groupID, opUserID); err != nil {
return err
}
conv := &pbconversation.ConversationReq{
ConversationID: msgprocessor.GetConversationIDBySessionType(constant.ReadGroupChatType, groupID),
ConversationType: constant.ReadGroupChatType,
GroupID: groupID,
IsPinned: &wrapperspb.BoolValue{Value: pinned},
}
return s.conversationClient.SetConversations(ctx, []string{opUserID}, conv)
}

View File

@ -0,0 +1,56 @@
package relation
import (
"context"
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
"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/wrapperspb"
"github.com/openimsdk/tools/log"
)
// PinFriend pins a friend conversation for ownerUserID
// (syncs friend.is_pinned = true and conversation.isPinned = true).
func (s *friendServer) PinFriend(ctx context.Context, req *relation.PinFriendReq) (*relation.PinFriendResp, error) {
if err := s.setFriendConversationPinned(ctx, req.OwnerUserID, req.FriendUserID, true); err != nil {
return nil, err
}
return &relation.PinFriendResp{}, nil
}
// UnpinFriend unpins a friend conversation for ownerUserID
// (syncs friend.is_pinned = false and conversation.isPinned = false).
func (s *friendServer) UnpinFriend(ctx context.Context, req *relation.UnpinFriendReq) (*relation.UnpinFriendResp, error) {
if err := s.setFriendConversationPinned(ctx, req.OwnerUserID, req.FriendUserID, false); err != nil {
return nil, err
}
return &relation.UnpinFriendResp{}, nil
}
func (s *friendServer) setFriendConversationPinned(ctx context.Context, ownerUserID, friendUserID string, pinned bool) error {
if err := authverify.CheckAccessV3(ctx, ownerUserID, s.config.Share.IMAdminUserID); err != nil {
return err
}
if _, err := s.db.FindFriendsWithError(ctx, ownerUserID, []string{friendUserID}); err != nil {
return err
}
if err := s.db.UpdateFriends(ctx, ownerUserID, []string{friendUserID}, map[string]any{"is_pinned": pinned}); err != nil {
return err
}
convID := conversationutil.GenConversationIDForSingle(ownerUserID, friendUserID)
if err := s.conversationClient.SetConversations(ctx, []string{ownerUserID},
&conversationpb.ConversationReq{
ConversationID: convID,
ConversationType: constant.SingleChatType,
UserID: friendUserID,
IsPinned: &wrapperspb.BoolValue{Value: pinned},
}); err != nil {
log.ZWarn(ctx, "sync conversation isPinned failed", err,
"ownerUserID", ownerUserID, "friendUserID", friendUserID, "isPinned", pinned)
}
s.notificationSender.FriendsInfoUpdateNotification(ctx, ownerUserID, []string{friendUserID})
return nil
}

@ -1 +1 @@
Subproject commit ab69a8df51841e7e70e637033c3f05b7e40bb747
Subproject commit 2e1f23fe06d15adcabf07ef72c1e8b08bca0f2c1