屏蔽新增 百家乐 跑马

This commit is contained in:
2026-04-14 22:31:11 +08:00
parent 0183de66dd
commit fc9a66469a
3 changed files with 83 additions and 20 deletions
@@ -133,6 +133,18 @@ $welcomeMessages = [
onchange="toggleBlockedSystemSender('星海小博士', this.checked)">
星海小博士
</label>
<label
style="display:flex;align-items:center;gap:6px;font-size:12px;color:#1e293b;cursor:pointer;padding:4px 2px;">
<input type="checkbox" id="block-sender-baccarat"
onchange="toggleBlockedSystemSender('百家乐', this.checked)">
百家乐
</label>
<label
style="display:flex;align-items:center;gap:6px;font-size:12px;color:#1e293b;cursor:pointer;padding:4px 2px;">
<input type="checkbox" id="block-sender-horse-race"
onchange="toggleBlockedSystemSender('跑马', this.checked)">
跑马
</label>
</div>
</div>
+69 -20
View File
@@ -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<string, any>} 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);
+2
View File
@@ -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');
}