修复礼包领取弹窗重复显示

This commit is contained in:
pllx
2026-05-05 21:48:51 +08:00
parent 11a882bd8e
commit 725a38eac3
3 changed files with 39 additions and 7 deletions
+19 -7
View File
@@ -94,6 +94,8 @@ class GameBetBroadcastService
toastMessage: "<b>{$username}</b> 抢到 <b>{$formattedAmount}</b> {$typeLabel}礼包", toastMessage: "<b>{$username}</b> 抢到 <b>{$formattedAmount}</b> {$typeLabel}礼包",
toastIcon: '🧧', toastIcon: '🧧',
toastColor: $toastColor, toastColor: $toastColor,
toastActorUsername: $username,
skipToastForActor: true,
); );
} }
@@ -109,7 +111,23 @@ class GameBetBroadcastService
string $toastIcon, string $toastIcon,
string $toastColor, string $toastColor,
string $action = '', string $action = '',
?string $toastActorUsername = null,
bool $skipToastForActor = false,
): void { ): void {
$toastNotification = [
'title' => $toastTitle,
'message' => $toastMessage,
'icon' => $toastIcon,
'color' => $toastColor,
'duration' => 8000,
];
if ($toastActorUsername !== null) {
// 记录触发人用于前端去重,避免本人同时看到本地到账提示和公屏领取提示。
$toastNotification['actor_username'] = $toastActorUsername;
$toastNotification['skip_for_actor'] = $skipToastForActor;
}
$message = [ $message = [
'id' => $this->chatState->nextMessageId($roomId), 'id' => $this->chatState->nextMessageId($roomId),
'room_id' => $roomId, 'room_id' => $roomId,
@@ -120,13 +138,7 @@ class GameBetBroadcastService
'font_color' => $fontColor, 'font_color' => $fontColor,
'action' => $action, 'action' => $action,
'sent_at' => now()->toDateTimeString(), 'sent_at' => now()->toDateTimeString(),
'toast_notification' => [ 'toast_notification' => $toastNotification,
'title' => $toastTitle,
'message' => $toastMessage,
'icon' => $toastIcon,
'color' => $toastColor,
'duration' => 8000,
],
]; ];
// 下注通知必须进房间 Presence 频道,确保当前房间所有在线人员都能看到右下角提示。 // 下注通知必须进房间 Presence 频道,确保当前房间所有在线人员都能看到右下角提示。
+18
View File
@@ -70,6 +70,20 @@ function runWhenDomReady(callback) {
callback(); callback();
} }
/**
* 判断 Toast 通知是否需要对当前用户隐藏。
*
* @param {Record<string, any>} toastNotification 右下角通知载荷
* @returns {boolean}
*/
function shouldSkipToastForCurrentUser(toastNotification) {
if (!toastNotification?.skip_for_actor) {
return false;
}
return String(toastNotification.actor_username || "") === String(window.chatContext?.username || "");
}
// ── 禁言逻辑 ── // ── 禁言逻辑 ──
function handleMutedEvent(e) { function handleMutedEvent(e) {
const state = getState(); const state = getState();
@@ -417,6 +431,10 @@ export function bindChatEvents() {
// 若消息携带 toast_notification 字段且当前用户是接收者或为公屏广播或为欢迎动作,弹右下角小卡片 // 若消息携带 toast_notification 字段且当前用户是接收者或为公屏广播或为欢迎动作,弹右下角小卡片
if (msg.toast_notification && (msg.to_user === window.chatContext?.username || msg.to_user === '大家' || msg.action === '欢迎')) { if (msg.toast_notification && (msg.to_user === window.chatContext?.username || msg.to_user === '大家' || msg.action === '欢迎')) {
const t = msg.toast_notification; const t = msg.toast_notification;
if (shouldSkipToastForCurrentUser(t)) {
return;
}
window.chatToast?.show({ window.chatToast?.show({
title: t.title || "通知", title: t.title || "通知",
message: t.message || "", message: t.message || "",
@@ -280,6 +280,8 @@ class RedPacketControllerTest extends TestCase
$this->assertFalse((bool) ($publicMessage['is_secret'] ?? true)); $this->assertFalse((bool) ($publicMessage['is_secret'] ?? true));
$this->assertStringContainsString('金币礼包', (string) ($publicMessage['toast_notification']['message'] ?? '')); $this->assertStringContainsString('金币礼包', (string) ($publicMessage['toast_notification']['message'] ?? ''));
$this->assertSame('🧧', $publicMessage['toast_notification']['icon'] ?? null); $this->assertSame('🧧', $publicMessage['toast_notification']['icon'] ?? null);
$this->assertSame($user->username, $publicMessage['toast_notification']['actor_username'] ?? null);
$this->assertTrue((bool) ($publicMessage['toast_notification']['skip_for_actor'] ?? false));
} }
/** /**