From fc9a66469a2a14ed29b131bf005ae7e5e9ad48f1 Mon Sep 17 00:00:00 2001 From: lkddi Date: Tue, 14 Apr 2026 22:31:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B1=8F=E8=94=BD=E6=96=B0=E5=A2=9E=20?= =?UTF-8?q?=E7=99=BE=E5=AE=B6=E4=B9=90=20=E8=B7=91=E9=A9=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/partials/layout/input-bar.blade.php | 12 +++ .../views/chat/partials/scripts.blade.php | 89 ++++++++++++++----- tests/Feature/ChatControllerTest.php | 2 + 3 files changed, 83 insertions(+), 20 deletions(-) diff --git a/resources/views/chat/partials/layout/input-bar.blade.php b/resources/views/chat/partials/layout/input-bar.blade.php index eff8cf0..8a157ee 100644 --- a/resources/views/chat/partials/layout/input-bar.blade.php +++ b/resources/views/chat/partials/layout/input-bar.blade.php @@ -133,6 +133,18 @@ $welcomeMessages = [ onchange="toggleBlockedSystemSender('星海小博士', this.checked)"> 星海小博士 + + diff --git a/resources/views/chat/partials/scripts.blade.php b/resources/views/chat/partials/scripts.blade.php index 7e6ed23..3f6bebf 100644 --- a/resources/views/chat/partials/scripts.blade.php +++ b/resources/views/chat/partials/scripts.blade.php @@ -38,7 +38,7 @@ const onlineCount = document.getElementById('online-count'); const onlineCountBottom = document.getElementById('online-count-bottom'); const BLOCKED_SYSTEM_SENDERS_STORAGE_KEY = 'chat_blocked_system_senders'; - const BLOCKABLE_SYSTEM_SENDERS = ['钓鱼播报', '星海小博士']; + const BLOCKABLE_SYSTEM_SENDERS = ['钓鱼播报', '星海小博士', '百家乐', '跑马']; // ── 消息区:手机端双触发打开用户名片(PC 端靠 ondblclick 内联属性)── // span[data-u] 由 clickableUser() 生成,touchend 委托至容器避免每条消息单独绑定 @@ -107,6 +107,8 @@ function syncBlockedSystemSenderCheckboxes() { const fishingCheckbox = document.getElementById('block-sender-fishing'); const doctorCheckbox = document.getElementById('block-sender-doctor'); + const baccaratCheckbox = document.getElementById('block-sender-baccarat'); + const horseRaceCheckbox = document.getElementById('block-sender-horse-race'); if (fishingCheckbox) { fishingCheckbox.checked = blockedSystemSenders.has('钓鱼播报'); @@ -115,35 +117,74 @@ if (doctorCheckbox) { doctorCheckbox.checked = blockedSystemSenders.has('星海小博士'); } + + if (baccaratCheckbox) { + baccaratCheckbox.checked = blockedSystemSenders.has('百家乐'); + } + + if (horseRaceCheckbox) { + horseRaceCheckbox.checked = blockedSystemSenders.has('跑马'); + } } /** - * 判断当前消息发送者是否已被用户屏蔽。 + * 根据消息内容识别其对应的屏蔽规则键。 * - * @param {string} fromUser 发送者名称 - * @returns {boolean} + * @param {Record} msg 消息对象 + * @returns {string|null} */ - function isBlockedSystemSender(fromUser) { - return blockedSystemSenders.has(String(fromUser || '')); + function resolveBlockedSystemSenderKey(msg) { + const fromUser = String(msg?.from_user || ''); + const content = String(msg?.content || ''); + + if (fromUser === '钓鱼播报') { + return '钓鱼播报'; + } + + if (fromUser === '星海小博士') { + return '星海小博士'; + } + + if ((fromUser === '系统传音' || fromUser === '系统') && content.includes('百家乐')) { + return '百家乐'; + } + + if ((fromUser === '系统传音' || fromUser === '系统') && (content.includes('赛马') || content.includes('跑马'))) { + return '跑马'; + } + + return null; } /** - * 从当前已渲染的聊天窗口中移除指定发送者的所有消息。 + * 批量切换当前已渲染消息的显示状态。 * - * @param {string} sender 发送者名称 + * @param {string} blockKey 屏蔽规则键 + * @param {boolean} hidden true = 隐藏,false = 恢复显示 */ - function removeRenderedMessagesBySender(sender) { + function setRenderedMessagesVisibilityBySender(blockKey, hidden) { [container, container2].forEach(targetContainer => { if (!targetContainer) { return; } - targetContainer.querySelectorAll('[data-from-user]').forEach(node => { - if (node.dataset.fromUser === sender) { - node.remove(); + targetContainer.querySelectorAll('[data-block-key]').forEach(node => { + if (node.dataset.blockKey === blockKey) { + if (hidden) { + node.dataset.blockHidden = '1'; + node.style.display = 'none'; + } else if (node.dataset.blockHidden === '1') { + node.removeAttribute('data-block-hidden'); + node.style.display = ''; + } } }); }); + + if (!hidden && autoScroll) { + container.scrollTop = container.scrollHeight; + container2.scrollTop = container2.scrollHeight; + } } /** @@ -176,7 +217,7 @@ /** * 更新指定系统播报项的屏蔽状态,并在勾选后立即清理当前窗口。 * - * @param {string} sender 系统播报发送者 + * @param {string} sender 系统播报发送者/规则键 * @param {boolean} blocked 是否屏蔽 */ function toggleBlockedSystemSender(sender, blocked) { @@ -186,10 +227,12 @@ if (blocked) { blockedSystemSenders.add(sender); - // 勾选后立刻移除聊天室窗口内已显示的对应播报内容。 - removeRenderedMessagesBySender(sender); + // 勾选后立刻隐藏聊天室窗口内已显示的对应播报内容。 + setRenderedMessagesVisibilityBySender(sender, true); } else { blockedSystemSenders.delete(sender); + // 取消勾选后立即恢复先前被隐藏的对应播报内容。 + setRenderedMessagesVisibilityBySender(sender, false); } persistBlockedSystemSenders(); @@ -799,19 +842,19 @@ _maxMsgId = msg.id; } - // 用户勾选屏蔽后,历史消息和实时消息统一在这里拦截,不再进入渲染流程。 - if (isBlockedSystemSender(msg?.from_user)) { - return; - } - const isMe = msg.from_user === window.chatContext.username; const fontColor = msg.font_color || '#000000'; + const blockRuleKey = resolveBlockedSystemSenderKey(msg); + const shouldHideByBlock = blockRuleKey ? blockedSystemSenders.has(blockRuleKey) : false; const div = document.createElement('div'); div.className = 'msg-line'; if (msg?.from_user) { div.dataset.fromUser = msg.from_user; } + if (blockRuleKey) { + div.dataset.blockKey = blockRuleKey; + } const timeStr = msg.sent_at || ''; let timeStrOverride = false; @@ -1061,6 +1104,12 @@ } div.innerHTML = html; + // 命中屏蔽规则时,消息仍保留在 DOM 中,便于取消屏蔽后立即恢复显示。 + if (shouldHideByBlock) { + div.dataset.blockHidden = '1'; + div.style.display = 'none'; + } + // 后端下发的带有 welcome_user 的也是系统欢迎/离开消息,加上属性标记 if (msg.welcome_user) { div.setAttribute('data-system-user', msg.welcome_user); diff --git a/tests/Feature/ChatControllerTest.php b/tests/Feature/ChatControllerTest.php index d9d927f..f09c1a8 100644 --- a/tests/Feature/ChatControllerTest.php +++ b/tests/Feature/ChatControllerTest.php @@ -74,6 +74,8 @@ class ChatControllerTest extends TestCase $response->assertSee('🔕 屏蔽', false); $response->assertSee('钓鱼播报'); $response->assertSee('星海小博士'); + $response->assertSee('百家乐'); + $response->assertSee('跑马'); $response->assertSee('chat_blocked_system_senders'); $response->assertSee('toggleBlockedSystemSender'); }