mirror of
https://gitee.com/JavaLionLi/plus-ui.git
synced 2026-09-15 08:25:10 +08:00
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:
parent
57dabd61d4
commit
7942def291
@ -28,6 +28,15 @@ import type {
|
|||||||
|
|
||||||
const PAGE_SIZE = 50;
|
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),
|
* Workbench store: holds the two left-rail lists (mine / unassigned),
|
||||||
* the currently opened conversation + ascending message stream, and the
|
* the currently opened conversation + ascending message stream, and the
|
||||||
@ -88,7 +97,7 @@ export const useConversationStore = defineStore('customerservice-conversation',
|
|||||||
async function sendReply(body: ReplyMessageRequest) {
|
async function sendReply(body: ReplyMessageRequest) {
|
||||||
if (!openedConversation.value) return;
|
if (!openedConversation.value) return;
|
||||||
const res = await apiSendMessage(openedConversation.value.id, body);
|
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) {
|
async function retry(messageId: number) {
|
||||||
@ -114,10 +123,20 @@ export const useConversationStore = defineStore('customerservice-conversation',
|
|||||||
agents.value = ((res.data as any).rows ?? []) as AgentVO[];
|
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 =====
|
// ===== SSE handlers =====
|
||||||
function onIncomingMessage(p: IncomingMessagePayload) {
|
function onIncomingMessage(p: IncomingMessagePayload) {
|
||||||
if (openedConversation.value?.id === p.conversationId) {
|
if (openedConversation.value?.id === p.conversationId) {
|
||||||
messages.value.push(p.message);
|
appendMessage(p.message);
|
||||||
}
|
}
|
||||||
refreshLists();
|
refreshLists();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user