Files
chatroom/app/Services/GameBetBroadcastService.php
T
2026-05-05 22:03:18 +08:00

153 lines
5.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* 文件功能:游戏下注与奖励公屏右下角通知广播服务
*
* 统一处理百家乐、赛马、双色球等游戏下注或奖励领取成功后的公屏消息、
* 右下角 Toast 通知载荷和异步落库,避免各玩法重复拼装广播结构。
*/
namespace App\Services;
use App\Events\MessageSent;
use App\Jobs\SaveMessageJob;
/**
* 类功能:为游戏下注和奖励领取成功事件生成并广播全员可见通知。
*/
class GameBetBroadcastService
{
public function __construct(
private readonly ChatStateService $chatState,
) {}
/**
* 广播百家乐下注成功通知。
*/
public function baccarat(int $roomId, string $username, int $amount, string $betLabel): void
{
$formattedAmount = number_format($amount);
$this->pushBetMessage(
roomId: $roomId,
content: "🎲 <b>【百家乐】【{$username}】</b> 押注了 <b>{$formattedAmount}</b> 金币({$betLabel})!✨",
fontColor: '#d97706',
toastTitle: '🎲 有人下注百家乐',
toastMessage: "<b>{$username}</b> 押注 <b>{$formattedAmount}</b> 金币({$betLabel}",
toastIcon: '🎲',
toastColor: '#d97706',
toastActorUsername: $username,
);
}
/**
* 广播赛马下注成功通知。
*/
public function horseRace(int $roomId, string $username, int $amount, string $horseName): void
{
$formattedAmount = number_format($amount);
$this->pushBetMessage(
roomId: $roomId,
content: "🐎 <b>【赛马】【{$username}】</b> 押注了 <b>{$formattedAmount}</b> 金币({$horseName})!✨",
fontColor: '#d97706',
toastTitle: '🐎 有人下注赛马',
toastMessage: "<b>{$username}</b> 押注 <b>{$formattedAmount}</b> 金币({$horseName}",
toastIcon: '🐎',
toastColor: '#d97706',
toastActorUsername: $username,
);
}
/**
* 广播双色球购票成功通知。
*/
public function lottery(int $roomId, string $username, string $issueNo, string $numbersLabel, int $ticketCount): void
{
$moreText = $ticketCount > 1 ? "{$ticketCount} 注号码" : '';
$this->pushBetMessage(
roomId: $roomId,
content: "🎟️ 【{$username}】购买 {$issueNo}{$numbersLabel} {$moreText}",
fontColor: '#dc2626',
toastTitle: '🎟️ 有人购买双色球',
toastMessage: "<b>{$username}</b> 购买 {$issueNo}{$numbersLabel} {$moreText}",
toastIcon: '🎟️',
toastColor: '#dc2626',
action: '大声宣告',
toastActorUsername: $username,
);
}
/**
* 广播红包领取成功通知。
*/
public function redPacketClaimed(int $roomId, string $username, int $amount, string $type): void
{
$typeLabel = $type === 'exp' ? '经验' : '金币';
$typeIcon = $type === 'exp' ? '✨' : '💰';
$toastColor = $type === 'exp' ? '#6d28d9' : '#d97706';
$formattedAmount = number_format($amount);
$this->pushBetMessage(
roomId: $roomId,
content: "🧧 <b>{$username}</b> 抢到了 <b>{$formattedAmount}</b> {$typeLabel}礼包!{$typeIcon}",
fontColor: $toastColor,
toastTitle: '🧧 有人领取红包',
toastMessage: "<b>{$username}</b> 抢到 <b>{$formattedAmount}</b> {$typeLabel}礼包",
toastIcon: '🧧',
toastColor: $toastColor,
toastActorUsername: $username,
skipToastForActor: true,
);
}
/**
* 推送带右下角通知载荷的公屏游戏消息。
*/
private function pushBetMessage(
int $roomId,
string $content,
string $fontColor,
string $toastTitle,
string $toastMessage,
string $toastIcon,
string $toastColor,
string $action = '',
?string $toastActorUsername = null,
bool $skipToastForActor = false,
): void {
$toastNotification = [
'title' => $toastTitle,
'message' => $toastMessage,
'icon' => $toastIcon,
'color' => $toastColor,
'duration' => 3000,
];
if ($toastActorUsername !== null) {
// 记录触发人用于前端去重,避免本人同时看到本地到账提示和公屏领取提示。
$toastNotification['actor_username'] = $toastActorUsername;
$toastNotification['skip_for_actor'] = $skipToastForActor;
}
$message = [
'id' => $this->chatState->nextMessageId($roomId),
'room_id' => $roomId,
'from_user' => '系统传音',
'to_user' => '大家',
'content' => $content,
'is_secret' => false,
'font_color' => $fontColor,
'action' => $action,
'sent_at' => now()->toDateTimeString(),
'toast_notification' => $toastNotification,
];
// 下注通知必须进房间 Presence 频道,确保当前房间所有在线人员都能看到右下角提示。
$this->chatState->pushMessage($roomId, $message);
event(new MessageSent($roomId, $message));
SaveMessageJob::dispatch($message);
}
}