From a5299ef2e829bd7d2f09681e3a94428d0b4ef7d2 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 19 Jun 2026 11:16:42 -0700 Subject: [PATCH] =?UTF-8?q?fix(im)=EF=BC=9A=E4=BF=AE=E5=A4=8D=E5=B7=B2?= =?UTF-8?q?=E8=AF=BB=E8=A1=A5=E4=B8=8A=E6=8A=A5=E5=AD=97=E6=AE=B5=E4=B8=8E?= =?UTF-8?q?=E7=BE=A4=E9=80=9A=E8=AF=9D=E7=AB=9E=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将会话已上报读位置字段改为 reportedReadMessageId,避免旧 readMessageId 本地缓存污染跳过判断 - read API 跳过逻辑继续基于已上报读位置,失败后可重新进入会话补上报 - RTC_CALL_END 按 room 移除群通话胶囊,避免旧房间结束事件误删新房间通话 - participantsLoaded 仅在同 room 下继承,避免新房间误跳过参与者补齐 --- src/views/im/home/store/conversationStore.ts | 12 ++++++------ src/views/im/home/store/rtcStore.ts | 11 ++++++++--- src/views/im/home/store/websocketStore.ts | 4 ++-- src/views/im/home/types/index.ts | 2 +- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/views/im/home/store/conversationStore.ts b/src/views/im/home/store/conversationStore.ts index 4d3967eae..b7b37df36 100644 --- a/src/views/im/home/store/conversationStore.ts +++ b/src/views/im/home/store/conversationStore.ts @@ -61,7 +61,7 @@ function toConversationDO(conversation: Conversation): ConversationDO { lastReceiptStatus: conversation.lastReceiptStatus, lastSelfSend: conversation.lastSelfSend, lastSenderDisplayName: conversation.lastSenderDisplayName, - readMessageId: conversation.readMessageId, + reportedReadMessageId: conversation.reportedReadMessageId, deleted: conversation.deleted, top: conversation.top, silent: conversation.silent, @@ -307,7 +307,7 @@ export const useConversationStore = defineStore('imConversationStore', { return false } const conversation = this.getConversation(type, targetId) - return (conversation?.readMessageId || 0) >= messageId + return (conversation?.reportedReadMessageId || 0) >= messageId }, /** 应用读位置到会话 */ @@ -366,9 +366,9 @@ export const useConversationStore = defineStore('imConversationStore', { const conversation = this.getConversation(record.conversationType, record.targetId) if ( conversation && - record.messageId > (conversation.readMessageId || 0) + record.messageId > (conversation.reportedReadMessageId || 0) ) { - conversation.readMessageId = record.messageId + conversation.reportedReadMessageId = record.messageId changedConversations.set(clientConversationId, conversation) } if (!current || messageId > current.messageId) { @@ -713,10 +713,10 @@ export const useConversationStore = defineStore('imConversationStore', { return } const conversation = this.getConversation(type, targetId) - if (!conversation || messageId <= (conversation.readMessageId || 0)) { + if (!conversation || messageId <= (conversation.reportedReadMessageId || 0)) { return } - conversation.readMessageId = messageId + conversation.reportedReadMessageId = messageId this.saveConversation(conversation) }, diff --git a/src/views/im/home/store/rtcStore.ts b/src/views/im/home/store/rtcStore.ts index fc8e8cfc7..c5876ebff 100644 --- a/src/views/im/home/store/rtcStore.ts +++ b/src/views/im/home/store/rtcStore.ts @@ -260,7 +260,8 @@ export const useRtcStore = defineStore('imRtc', () => { useGroupStore().markGroupActiveCallLoaded(payload.groupId) // 浅比较:room / mediaType / joinedUserIds / inviteeIds 都没变就跳过,避免下游 watcher 无意义重算 const existing = groupActiveCalls.value.get(payload.groupId) - const nextParticipantsLoaded = participantsLoaded ?? !!existing?.participantsLoaded + const nextParticipantsLoaded = + participantsLoaded ?? (existing?.room === payload.room && !!existing.participantsLoaded) if ( existing && isSameGroupCall(existing, payload) && @@ -309,10 +310,14 @@ export const useRtcStore = defineStore('imRtc', () => { } /** 群通话结束:从 groupActiveCalls 移除;胶囊条消失 */ - function removeGroupCall(groupId: number) { + function removeGroupCall(groupId: number, room?: string) { if (!groupId) { return } + const existing = groupActiveCalls.value.get(groupId) + if (room && existing?.room !== room) { + return + } clearGroupCallCache(groupId) useGroupStore().markGroupActiveCallLoaded(groupId) } @@ -396,7 +401,7 @@ export const useRtcStore = defineStore('imRtc', () => { return } if (nextJoined.length === 0 && nextInvitee.length === 0) { - removeGroupCall(groupId) + removeGroupCall(groupId, room) return } setGroupCall({ diff --git a/src/views/im/home/store/websocketStore.ts b/src/views/im/home/store/websocketStore.ts index ac2455763..3fc1e000c 100644 --- a/src/views/im/home/store/websocketStore.ts +++ b/src/views/im/home/store/websocketStore.ts @@ -1171,10 +1171,10 @@ export const useImWebSocketStore = defineStore('imWebSocketStore', { } const rtcStore = useRtcStore() const isGroup = payload.conversationType === ImConversationType.GROUP - // 群通话:移除胶囊条(按外层 groupId 取,不依赖 payload) + // 群通话:移除对应房间的胶囊条 const groupId = (websocketMessage as ImGroupMessageNotification).groupId if (isGroup && groupId) { - rtcStore.removeGroupCall(groupId) + rtcStore.removeGroupCall(groupId, payload.room) } // 通话窗 / 来电窗指向同一 room 时关闭: // RUNNING / INVITING 阶段对比 call.room;INCOMING 阶段对比 incomingPayload.room diff --git a/src/views/im/home/types/index.ts b/src/views/im/home/types/index.ts index 3807b3a2a..2af8efab7 100644 --- a/src/views/im/home/types/index.ts +++ b/src/views/im/home/types/index.ts @@ -110,7 +110,7 @@ export interface Conversation { silent?: boolean // 是否免打扰(不展示未读徽标 + 不响提示音) atMe?: boolean // 群聊:是否有人 @我 atAll?: boolean // 群聊:是否有人 @全体成员 - readMessageId?: number // 已上报到服务端的最大已读消息编号 + reportedReadMessageId?: number // 已上报到服务端的最大已读消息编号 draft?: { html: string // 输入框 HTML plain: string // 输入框纯文本