feat(im): 修 IM 历史消息切会话串号:loadEarlier 用 getConversationKey 守卫,watch(conversation) 重置分页态

im
YunaiV 2026-05-21 09:05:44 +08:00
parent 8468d9bf4d
commit 69653163b0
1 changed files with 42 additions and 20 deletions

View File

@ -264,7 +264,8 @@ import {
import { import {
buildFacePreviewText, buildFacePreviewText,
buildRecallTip, buildRecallTip,
buildRecallTipSegments buildRecallTipSegments,
getConversationKey
} from '@/views/im/utils/conversation' } from '@/views/im/utils/conversation'
import { useMessagePuller } from '@/views/im/home/composables/useMessagePuller' import { useMessagePuller } from '@/views/im/home/composables/useMessagePuller'
import { useVoicePlayer } from '@/views/im/home/composables/useVoicePlayer' import { useVoicePlayer } from '@/views/im/home/composables/useVoicePlayer'
@ -538,48 +539,60 @@ const hasMore = ref(true)
* - 返回数量 < limit 视为到顶 * - 返回数量 < limit 视为到顶
*/ */
async function loadEarlier() { async function loadEarlier() {
// 1. / / 退 conversation // / / 退 conversation
if (loadingMore.value || !hasMore.value || !conversation.value) { if (loadingMore.value || !hasMore.value || !conversation.value) {
return return
} }
// await / prepend
const requestedKey = getConversationKey(conversation.value)
const requestedType = conversation.value.type
const requestedTargetId = conversation.value.targetId
const requestedIsGroup = requestedType === ImConversationType.GROUP
loadingMore.value = true loadingMore.value = true
try { try {
// 2. maxId id // maxId id
// id=0 id // id=0 id
// / reduce POSITIVE_INFINITY undefined // / reduce POSITIVE_INFINITY undefined
const earliestId = allMessages.value const earliestId = allMessages.value
.filter((message) => message.id > 0) .filter((message) => message.id > 0)
.reduce((min, message) => Math.min(min, message.id), Number.POSITIVE_INFINITY) .reduce((min, message) => Math.min(min, message.id), Number.POSITIVE_INFINITY)
const maxId = Number.isFinite(earliestId) ? earliestId : undefined const maxId = Number.isFinite(earliestId) ? earliestId : undefined
// 3. list / useMessagePuller // list / useMessagePuller
// convert Message puller // convert Message puller
let earlier: Message[] = [] let earlier: Message[] = []
if (isGroup.value) { let pageLength = 0
if (requestedIsGroup) {
const list = await apiGetGroupMessageList({ const list = await apiGetGroupMessageList({
groupId: conversation.value.targetId, groupId: requestedTargetId,
maxId, maxId,
limit: HISTORY_PAGE_SIZE limit: HISTORY_PAGE_SIZE
}) })
earlier = (list || []).map(convertGroupMessage) earlier = (list || []).map(convertGroupMessage)
// < limit "" pageLength = list?.length ?? 0
if (!list || list.length < HISTORY_PAGE_SIZE) {
hasMore.value = false
}
} else { } else {
const list = await apiGetPrivateMessageList({ const list = await apiGetPrivateMessageList({
receiverId: conversation.value.targetId, receiverId: requestedTargetId,
maxId, maxId,
limit: HISTORY_PAGE_SIZE limit: HISTORY_PAGE_SIZE
}) })
earlier = (list || []).map(convertPrivateMessage) earlier = (list || []).map(convertPrivateMessage)
if (!list || list.length < HISTORY_PAGE_SIZE) { pageLength = list?.length ?? 0
hasMore.value = false
}
} }
// 4. conversationStoreprependMessages + + IndexedDB
// messages // await active null / hasMore prepend
conversationStore.prependMessages(conversation.value.type, conversation.value.targetId, earlier) if (!conversation.value || getConversationKey(conversation.value) !== requestedKey) {
return
}
// < limit ""
if (pageLength < HISTORY_PAGE_SIZE) {
hasMore.value = false
}
// conversationStoreprependMessages + + IndexedDB
// messages
conversationStore.prependMessages(requestedType, requestedTargetId, earlier)
} finally { } finally {
loadingMore.value = false loadingMore.value = false
} }
@ -607,6 +620,15 @@ watch(visible, (value) => {
} }
}) })
/**
* 抽屉开着时外部切了 active conversationdialog title / 列表 / isGroup 全部跟着新 conversation
* 这里把分页态一并重置否则旧会话残留的 loadingMore=true / hasMore=false 会让新会话"加载更早"按钮失效
*/
watch(conversation, () => {
loadingMore.value = false
hasMore.value = true
})
// ==================== helper ==================== // ==================== helper ====================
/** 取头像 url自己用 userStore群里查 groupStore 成员,私聊用 conversation.avatar */ /** 取头像 url自己用 userStore群里查 groupStore 成员,私聊用 conversation.avatar */