153 lines
5.3 KiB
PHP
153 lines
5.3 KiB
PHP
<?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);
|
||
}
|
||
}
|