fix(im):修复已读补上报字段与群通话竞态
- 将会话已上报读位置字段改为 reportedReadMessageId,避免旧 readMessageId 本地缓存污染跳过判断 - read API 跳过逻辑继续基于已上报读位置,失败后可重新进入会话补上报 - RTC_CALL_END 按 room 移除群通话胶囊,避免旧房间结束事件误删新房间通话 - participantsLoaded 仅在同 room 下继承,避免新房间误跳过参与者补齐im
parent
b6e13c59c7
commit
a5299ef2e8
|
|
@ -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)
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -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({
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ export interface Conversation {
|
|||
silent?: boolean // 是否免打扰(不展示未读徽标 + 不响提示音)
|
||||
atMe?: boolean // 群聊:是否有人 @我
|
||||
atAll?: boolean // 群聊:是否有人 @全体成员
|
||||
readMessageId?: number // 已上报到服务端的最大已读消息编号
|
||||
reportedReadMessageId?: number // 已上报到服务端的最大已读消息编号
|
||||
draft?: {
|
||||
html: string // 输入框 HTML
|
||||
plain: string // 输入框纯文本
|
||||
|
|
|
|||
Loading…
Reference in New Issue