From ef779eeedb122fd4c76085f47240c71c0d6aa26e Mon Sep 17 00:00:00 2001 From: hawklin2017 <32898629+hawklin2017@users.noreply.github.com> Date: Thu, 14 May 2026 20:43:04 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=94=E5=9B=9E=E8=AE=BE=E7=BD=AE=E9=9D=99?= =?UTF-8?q?=E9=9F=B3=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/rpc/conversation/conversation.go | 35 ++++++-- internal/rpc/conversation/mute_fill.go | 98 +++++++++++++++++++++++ protocol | 2 +- 3 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 internal/rpc/conversation/mute_fill.go diff --git a/internal/rpc/conversation/conversation.go b/internal/rpc/conversation/conversation.go index c443bb638..15c5a945c 100644 --- a/internal/rpc/conversation/conversation.go +++ b/internal/rpc/conversation/conversation.go @@ -49,6 +49,7 @@ type conversationServer struct { pbconversation.UnimplementedConversationServer conversationDatabase controller.ConversationDatabase msgBurnDeadlineDB database.MsgBurnDeadline + userMuteDB controller.UserMuteDatabase conversationNotificationSender *ConversationNotificationSender config *Config @@ -85,6 +86,10 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg if err != nil { return err } + userMuteMongoDB, err := mgo.NewUserMuteMongo(mgocli.GetDB()) + if err != nil { + return err + } userConn, err := client.GetConn(ctx, config.Share.RpcRegisterName.User) if err != nil { return err @@ -104,6 +109,7 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg conversationDatabase: controller.NewConversationDatabase(conversationDB, redis.NewConversationRedis(rdb, &config.LocalCacheConfig, redis.GetRocksCacheOptions(), conversationDB), mgocli.GetTx()), msgBurnDeadlineDB: msgBurnDeadlineDB, + userMuteDB: controller.NewUserMuteDatabase(userMuteMongoDB), userClient: rpcli.NewUserClient(userConn), groupClient: rpcli.NewGroupClient(groupConn), msgClient: msgClient, @@ -121,6 +127,7 @@ func (c *conversationServer) GetConversation(ctx context.Context, req *pbconvers } resp := &pbconversation.GetConversationResp{Conversation: &pbconversation.Conversation{}} resp.Conversation = convert.ConversationDB2Pb(conversations[0]) + c.fillConversationUserMute(ctx, resp.Conversation) return resp, nil } @@ -195,6 +202,15 @@ func (c *conversationServer) GetSortedConversationList(ctx context.Context, req } conversation_notPinTime[time] = conversationID } + if c.userMuteDB != nil { + for _, v := range conversations { + elem, ok := conversationMsg[v.ConversationID] + if !ok { + continue + } + c.fillConversationElemUserMute(ctx, c.userMuteDB, req.UserID, elem, v.ConversationType, v.UserID) + } + } resp = &pbconversation.GetSortedConversationListResp{ ConversationTotal: int64(len(chatLogs)), ConversationElems: []*pbconversation.ConversationElem{}, @@ -215,6 +231,7 @@ func (c *conversationServer) GetAllConversations(ctx context.Context, req *pbcon } resp := &pbconversation.GetAllConversationsResp{Conversations: []*pbconversation.Conversation{}} resp.Conversations = convert.ConversationsDB2Pb(conversations) + c.fillConversationsUserMute(ctx, resp.Conversations) return resp, nil } @@ -233,9 +250,9 @@ func (c *conversationServer) getConversations(ctx context.Context, ownerUserID s if err != nil { return nil, err } - resp := &pbconversation.GetConversationsResp{Conversations: []*pbconversation.Conversation{}} - resp.Conversations = convert.ConversationsDB2Pb(conversations) - return convert.ConversationsDB2Pb(conversations), nil + list := convert.ConversationsDB2Pb(conversations) + c.fillConversationsUserMute(ctx, list) + return list, nil } // Deprecated @@ -523,7 +540,9 @@ func (c *conversationServer) GetConversationsByConversationID( if err != nil { return nil, err } - return &pbconversation.GetConversationsByConversationIDResp{Conversations: convert.ConversationsDB2Pb(conversations)}, nil + list := convert.ConversationsDB2Pb(conversations) + c.fillConversationsUserMute(ctx, list) + return &pbconversation.GetConversationsByConversationIDResp{Conversations: list}, nil } func (c *conversationServer) GetConversationOfflinePushUserIDs(ctx context.Context, req *pbconversation.GetConversationOfflinePushUserIDsReq) (*pbconversation.GetConversationOfflinePushUserIDsResp, error) { @@ -711,9 +730,11 @@ func (c *conversationServer) GetOwnerConversation(ctx context.Context, req *pbco if err != nil { return nil, err } + list := convert.ConversationsDB2Pb(conversations) + c.fillConversationsUserMute(ctx, list) return &pbconversation.GetOwnerConversationResp{ Total: total, - Conversations: convert.ConversationsDB2Pb(conversations), + Conversations: list, }, nil } @@ -764,7 +785,9 @@ func (c *conversationServer) GetConversationsNeedClearMsg(ctx context.Context, _ } } - return &pbconversation.GetConversationsNeedClearMsgResp{Conversations: convert.ConversationsDB2Pb(temp)}, nil + list := convert.ConversationsDB2Pb(temp) + c.fillConversationsUserMute(ctx, list) + return &pbconversation.GetConversationsNeedClearMsgResp{Conversations: list}, nil } func (c *conversationServer) GetNotNotifyConversationIDs(ctx context.Context, req *pbconversation.GetNotNotifyConversationIDsReq) (*pbconversation.GetNotNotifyConversationIDsResp, error) { diff --git a/internal/rpc/conversation/mute_fill.go b/internal/rpc/conversation/mute_fill.go new file mode 100644 index 000000000..2581f96fd --- /dev/null +++ b/internal/rpc/conversation/mute_fill.go @@ -0,0 +1,98 @@ +// Copyright © 2023 OpenIM. All rights reserved. + +package conversation + +import ( + "context" + "math" + "time" + + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" + "github.com/openimsdk/protocol/constant" + pbconversation "github.com/openimsdk/protocol/conversation" + "github.com/openimsdk/tools/log" +) + +// int64MuteDurationToProto 将 user_mute 的秒数配置写入 Conversation.muteDuration(int32);正数过大时截断。 +func int64MuteDurationToProto(d int64) int32 { + if d > int64(math.MaxInt32) { + return math.MaxInt32 + } + if d < int64(math.MinInt32) { + return math.MinInt32 + } + return int32(d) +} + +// conversationMuteFromRecord 与 relation.GetMute 判定一致:未记录/已过期则未静音;永久为 duration=-1 且 end=0。 +func conversationMuteFromRecord(rec *model.UserMute, nowUnix int64) (isMuted bool, muteDuration int32, muteEndTime int64) { + if rec == nil { + return false, 0, 0 + } + if rec.MuteEndTime != 0 && rec.MuteEndTime <= nowUnix { + return false, 0, 0 + } + d := rec.MuteDuration + if d == 0 && rec.MuteEndTime == 0 { + d = -1 + } + md := int64MuteDurationToProto(d) + me := rec.MuteEndTime + isMuted = (md == -1) || (me > nowUnix) + return isMuted, md, me +} + +func (c *conversationServer) fillConversationUserMute(ctx context.Context, conv *pbconversation.Conversation) { + if c == nil || c.userMuteDB == nil || conv == nil { + return + } + if conv.ConversationType != constant.SingleChatType || conv.UserID == "" { + return + } + rec, err := c.userMuteDB.Get(ctx, conv.OwnerUserID, conv.UserID) + if err != nil { + log.ZWarn(ctx, "fillConversationUserMute Get", err, "owner", conv.OwnerUserID, "peer", conv.UserID) + return + } + now := time.Now().Unix() + isMuted, dur, end := conversationMuteFromRecord(rec, now) + conv.IsMuted = isMuted + conv.MuteDuration = dur + conv.MuteEndTime = end +} + +func (c *conversationServer) fillConversationsUserMute(ctx context.Context, list []*pbconversation.Conversation) { + if len(list) == 0 { + return + } + for _, conv := range list { + c.fillConversationUserMute(ctx, conv) + } +} + +func (c *conversationServer) fillConversationElemUserMute( + ctx context.Context, + db controller.UserMuteDatabase, + ownerUserID string, + elem *pbconversation.ConversationElem, + conversationType int32, + peerUserID string, +) { + if db == nil || elem == nil || ownerUserID == "" { + return + } + if conversationType != constant.SingleChatType || peerUserID == "" { + return + } + rec, err := db.Get(ctx, ownerUserID, peerUserID) + if err != nil { + log.ZWarn(ctx, "fillConversationElemUserMute Get", err, "owner", ownerUserID, "peer", peerUserID) + return + } + now := time.Now().Unix() + isMuted, dur, end := conversationMuteFromRecord(rec, now) + elem.IsMuted = isMuted + elem.MuteDuration = dur + elem.MuteEndTime = end +} diff --git a/protocol b/protocol index 9e40541a8..9afba4648 160000 --- a/protocol +++ b/protocol @@ -1 +1 @@ -Subproject commit 9e40541a87bb803959895e635a1923f4a6550952 +Subproject commit 9afba46486484563098e1e77b46cc94e0d85c9dd