diff --git a/src/views/customerservice/workbench/composables/useConversationStore.ts b/src/views/customerservice/workbench/composables/useConversationStore.ts index c5fa4dae..6eacb992 100644 --- a/src/views/customerservice/workbench/composables/useConversationStore.ts +++ b/src/views/customerservice/workbench/composables/useConversationStore.ts @@ -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(); }