From f0137f3fa3bbb150c6d32cc5fb64e2c6cb4f9bfa Mon Sep 17 00:00:00 2001 From: pllx Date: Tue, 28 Apr 2026 11:59:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=E6=81=A2=E5=A4=8D=E6=97=B6=E5=8F=AA=E7=9C=81=E7=95=A5=E8=BF=87?= =?UTF-8?q?=E6=97=B6=E7=9A=84=E7=B3=BB=E7=BB=9F/=E6=B8=B8=E6=88=8F?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=EF=BC=8C=E4=BF=9D=E7=95=99=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E8=81=8A=E5=A4=A9=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/js/chat-room/message-renderer.js | 76 +++++++++++++++++----- 1 file changed, 61 insertions(+), 15 deletions(-) diff --git a/resources/js/chat-room/message-renderer.js b/resources/js/chat-room/message-renderer.js index aa86926..55ff285 100644 --- a/resources/js/chat-room/message-renderer.js +++ b/resources/js/chat-room/message-renderer.js @@ -457,8 +457,22 @@ export function enqueueChatMessage(msg) { state.chatMessageFlushTimer = scheduleFlush(flushQueuedChatMessages); } -/** 后台恢复时公屏最大渲染条数,避免暴刷 */ -const MAX_BURST_RENDER = 50; +/** + * 判断是否为普通用户聊天消息(非系统/游戏通知)。 + */ +function isUserChatMessage(msg) { + if (!msg || !msg.from_user) return false; + const u = msg.from_user; + if (SYSTEM_USERS.includes(u)) return false; + if (u.endsWith("播报")) return false; + if (u === "百家乐" || u === "跑马") return false; + return true; +} + +/** 后台恢复时系统通知最多保留条数 */ +const MAX_SYSTEM_BURST = 20; +/** 后台恢复时超过该时间的系统通知直接丢弃(分钟) */ +const MAX_SYSTEM_AGE_MINUTES = 10; /** * 分批渲染待处理消息,给动画、输入和滚动留出主线程时间。 @@ -469,21 +483,53 @@ export function flushQueuedChatMessages() { state.chatMessageFlushTimer = null; - // 大批量消息堆积(后台标签页恢复)时,丢弃早于 MAX_BURST_RENDER 的消息, - // 插入一条省略提示,避免用户一回来就看到满屏消息狂刷。 - if (state.pendingChatMessages.length > MAX_BURST_RENDER + 20) { - const skipped = state.pendingChatMessages.length - MAX_BURST_RENDER; - state.pendingChatMessages.splice(0, skipped); + // 大批量消息堆积(后台标签页恢复)时,保留所有用户聊天记录, + // 但过时的系统/游戏通知只保留最近 MAX_SYSTEM_BURST 条。 + if (state.pendingChatMessages.length > MAX_SYSTEM_BURST + 30) { + const now = Date.now(); + const maxAge = MAX_SYSTEM_AGE_MINUTES * 60 * 1000; + const totalSystem = state.pendingChatMessages.filter((m) => !isUserChatMessage(m)).length; + let systemSeen = 0; + let dropped = 0; - const container = state.container; - if (container) { - const notice = document.createElement("div"); - notice.className = "msg-line msg-burst-notice"; - notice.style.cssText = - "text-align:center;padding:6px 0;margin:4px 0;font-size:12px;color:#94a3b8;border-top:1px dashed #d1d5db;border-bottom:1px dashed #d1d5db;"; - notice.textContent = `⏫ 省略了 ${skipped} 条未读消息`; - container.appendChild(notice); + const filtered = state.pendingChatMessages.filter((msg) => { + if (isUserChatMessage(msg)) return true; + + systemSeen++; + + // 超过10分钟的系统通知直接丢弃 + let msgTime = 0; + if (msg.sent_at) { + msgTime = new Date(msg.sent_at.replace(" ", "T")).getTime(); + } + if (msgTime > 0 && now - msgTime > maxAge) { + dropped++; + return false; + } + + // 从旧到新遍历,只保留最后 MAX_SYSTEM_BURST 条系统通知 + const remainingAfter = totalSystem - systemSeen; + if (remainingAfter >= MAX_SYSTEM_BURST) { + dropped++; + return false; + } + + return true; + }); + + if (dropped > 0) { + const container = state.container; + if (container) { + const notice = document.createElement("div"); + notice.className = "msg-line msg-burst-notice"; + notice.style.cssText = + "text-align:center;padding:6px 0;margin:4px 0;font-size:12px;color:#94a3b8;border-top:1px dashed #d1d5db;border-bottom:1px dashed #d1d5db;"; + notice.textContent = `⏫ 省略了 ${dropped} 条系统通知`; + container.appendChild(notice); + } } + + state.pendingChatMessages = filtered; } const batch = state.pendingChatMessages.splice(0, CHAT_MESSAGE_FLUSH_BATCH_SIZE);