feat(customerservice): cap in-memory messages at 500 to prevent unbounded growth

长会话(8h 班,高活跃客户)前端 messages 数组会无限累积:每条
INCOMING_MESSAGE SSE + 每次用户 loadMore 都 push 进来,从不剔除。
极端场景下渲染 / findIndex 会卡死浏览器。

加 MAX_MESSAGES_IN_MEMORY=500 软上限:超过时砍到一半(留最新的
250 条),并把 noMoreMessages 重置 false 让用户向上翻历史时还能
从后端拉回被砍掉的老消息(DB 是真相,前端只是缓存)。

切会话时 openConversation 已经整体替换 messages,无需特殊处理。
This commit is contained in:
i548450 2026-06-09 22:49:43 +08:00
parent 57dabd61d4
commit 7942def291

View File

@ -28,6 +28,15 @@ import type {
const PAGE_SIZE = 50;
/**
* Cap on in-memory messages for the currently opened conversation.
* Long-lived sessions (8h shift on a chatty customer) would otherwise grow
* unbounded every SSE INCOMING + every loadMore prepend keeps adding.
* When exceeded we drop the oldest half and reopen the loadMore door, so
* the user can scroll up to fetch them back from the server.
*/
const MAX_MESSAGES_IN_MEMORY = 500;
/**
* Workbench store: holds the two left-rail lists (mine / unassigned),
* the currently opened conversation + ascending message stream, and the
@ -88,7 +97,7 @@ export const useConversationStore = defineStore('customerservice-conversation',
async function sendReply(body: ReplyMessageRequest) {
if (!openedConversation.value) return;
const res = await apiSendMessage(openedConversation.value.id, body);
messages.value.push(res.data as any);
appendMessage(res.data as any);
}
async function retry(messageId: number) {
@ -114,10 +123,20 @@ export const useConversationStore = defineStore('customerservice-conversation',
agents.value = ((res.data as any).rows ?? []) as AgentVO[];
}
function appendMessage(msg: Message) {
messages.value.push(msg);
if (messages.value.length > MAX_MESSAGES_IN_MEMORY) {
// Keep only the latest half; mark loadMore re-openable so user can
// scroll up to refetch the dropped older slice if needed.
messages.value = messages.value.slice(-MAX_MESSAGES_IN_MEMORY / 2);
noMoreMessages.value = false;
}
}
// ===== SSE handlers =====
function onIncomingMessage(p: IncomingMessagePayload) {
if (openedConversation.value?.id === p.conversationId) {
messages.value.push(p.message);
appendMessage(p.message);
}
refreshLists();
}