From f6506eff76fd94905d8d7c710f2dd3e74b5e7701 Mon Sep 17 00:00:00 2001 From: hawklin2017 <32898629+hawklin2017@users.noreply.github.com> Date: Mon, 18 May 2026 20:49:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=9A=E8=AF=9D=E9=98=85=E5=90=8E=E5=8D=B3?= =?UTF-8?q?=E7=84=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/api/conversation.go | 4 +++ internal/api/router.go | 1 + internal/rpc/conversation/conversation.go | 15 +++++++++ internal/rpc/msg/as_read.go | 37 ++++++++++++++--------- internal/rpc/rtc/signal.go | 2 +- protocol | 2 +- 6 files changed, 45 insertions(+), 16 deletions(-) diff --git a/internal/api/conversation.go b/internal/api/conversation.go index a43721569..23024e14b 100644 --- a/internal/api/conversation.go +++ b/internal/api/conversation.go @@ -75,3 +75,7 @@ func (o *ConversationApi) GetPinnedConversationIDs(c *gin.Context) { func (o *ConversationApi) SetMute(c *gin.Context) { a2r.Call(c, conversation.ConversationClient.SetConversationMute, o.Client) } + +func (o *ConversationApi) SetBurn(c *gin.Context) { + a2r.Call(c, conversation.ConversationClient.SetConversationBurn, o.Client) +} diff --git a/internal/api/router.go b/internal/api/router.go index dc32db737..4cc8dd664 100644 --- a/internal/api/router.go +++ b/internal/api/router.go @@ -357,6 +357,7 @@ func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, co conversationGroup.POST("/get_not_notify_conversation_ids", c.GetNotNotifyConversationIDs) conversationGroup.POST("/get_pinned_conversation_ids", c.GetPinnedConversationIDs) conversationGroup.POST("/set_mute", c.SetMute) + conversationGroup.POST("/set_burn", c.SetBurn) } { diff --git a/internal/rpc/conversation/conversation.go b/internal/rpc/conversation/conversation.go index 39edb9024..3d156c225 100644 --- a/internal/rpc/conversation/conversation.go +++ b/internal/rpc/conversation/conversation.go @@ -914,6 +914,21 @@ func (c *conversationServer) ClearBurnExpiredMsgs(ctx context.Context, req *pbco return &pbconversation.ClearBurnExpiredMsgsResp{Count: processed}, nil } +func (c *conversationServer) SetConversationBurn(ctx context.Context, req *pbconversation.SetConversationBurnReq) (*pbconversation.SetConversationBurnResp, error) { + if err := c.conversationDatabase.UpdateUsersConversationField( + ctx, + []string{req.OwnerUserID}, + req.ConversationID, + map[string]any{ + "burn_duration": req.BurnDuration, + }, + ); err != nil { + return nil, err + } + c.conversationNotificationSender.ConversationChangeNotification(ctx, req.OwnerUserID, []string{req.ConversationID}) + return &pbconversation.SetConversationBurnResp{}, nil +} + func (c *conversationServer) SetConversationMute(ctx context.Context, req *pbconversation.SetConversationMuteReq) (*pbconversation.SetConversationMuteResp, error) { var ( muteDuration int32 diff --git a/internal/rpc/msg/as_read.go b/internal/rpc/msg/as_read.go index d4c1531e4..5ded5d478 100644 --- a/internal/rpc/msg/as_read.go +++ b/internal/rpc/msg/as_read.go @@ -206,16 +206,18 @@ func (m *msgServer) MarkConversationAsRead(ctx context.Context, req *msg.MarkCon return &msg.MarkConversationAsReadResp{}, nil } -// recordBurnDeadlines 在「单聊」场景下,根据对端(发送者)的 MsgBurnDuration -// 为本次已读的每条消息同时给接收者和发送者各记录一份「阅后即焚」截止时间。 -// cron 到期后会分别推进两人各自的 min_seq,双方都看不到该消息。 +// recordBurnDeadlines 在「单聊」场景下,为本次已读的每条消息同时给接收者和发送者 +// 各记录一份「阅后即焚」截止时间。cron 到期后会分别删除双方该消息,双方都看不到。 +// +// 销毁时长优先级: +// 1. 会话级 BurnDuration(通过 /conversation/set_burn 设置); +// 2. 对端(发送者)全局 MsgBurnDuration。 // // 设计要点: // 1. 仅单聊。 -// 2. 仅当发送者 MsgBurnDuration > 0 时才记录;0 表示未开启。 -// 3. $setOnInsert 确保同一 (UserID, ConversationID, Seq) 已存在时不覆盖, +// 2. $setOnInsert 确保同一 (UserID, ConversationID, Seq) 已存在时不覆盖, // 以「首次阅读时刻」为 deadline 基准,多端重复 MarkAsRead 不会往后推。 -// 4. 失败仅记录日志,不影响已读主流程。 +// 3. 失败仅记录日志,不影响已读主流程。 func (m *msgServer) recordBurnDeadlines(ctx context.Context, conv *conversation.Conversation, readerUserID string, seqs []int64) { if len(seqs) == 0 { return @@ -227,16 +229,23 @@ func (m *msgServer) recordBurnDeadlines(ctx context.Context, conv *conversation. if peerID == "" || peerID == readerUserID { return } - peerInfo, err := m.UserLocalCache.GetUserInfo(ctx, peerID) - if err != nil { - log.ZWarn(ctx, "recordBurnDeadlines GetUserInfo failed", err, "peerID", peerID) - return - } - if peerInfo == nil || peerInfo.MsgBurnDuration <= 0 { - return + + // 优先使用会话级 BurnDuration(双方协商后保存到会话),否则回退到发送者全局设置。 + burnSeconds := conv.BurnDuration + if burnSeconds <= 0 { + peerInfo, err := m.UserLocalCache.GetUserInfo(ctx, peerID) + if err != nil { + log.ZWarn(ctx, "recordBurnDeadlines GetUserInfo failed", err, "peerID", peerID) + return + } + if peerInfo == nil || peerInfo.MsgBurnDuration <= 0 { + return + } + burnSeconds = peerInfo.MsgBurnDuration } + now := time.Now().UnixMilli() - deadline := now + int64(peerInfo.MsgBurnDuration)*1000 + deadline := now + int64(burnSeconds)*1000 // 每条消息同时为接收者和发送者各写一条 deadline,双方消息同步焚毁。 items := make([]*model.MsgBurnDeadline, 0, len(seqs)*2) for _, seq := range seqs { diff --git a/internal/rpc/rtc/signal.go b/internal/rpc/rtc/signal.go index d192def38..89dfeb52d 100644 --- a/internal/rpc/rtc/signal.go +++ b/internal/rpc/rtc/signal.go @@ -270,7 +270,7 @@ func (s *rtcServer) handleInviteInGroup(ctx context.Context, req *rtc.SignalInvi continue } if err := s.sendSignalingNotification(ctx, req.UserID, inviteeID, int32(constant.ReadGroupChatType), inv.GroupID, req.OfflinePushInfo, content); err != nil { - log.ZWarn(ctx, "sendSignalingNotification to group invitee failed", err, "inviteeID", inviteeID) + log.ZWarn(ctx, "handleInviteInGroup to group invitee failed", err, "inviteeID", inviteeID) } } diff --git a/protocol b/protocol index 1d47a639e..7eb773753 160000 --- a/protocol +++ b/protocol @@ -1 +1 @@ -Subproject commit 1d47a639ede5965901dfe0966b8369444c865e24 +Subproject commit 7eb7737531d6ff779571e77f5a49aa21ce9bcb43