红包领取增加全员通知

This commit is contained in:
pllx
2026-04-30 15:52:16 +08:00
parent 9764961519
commit 92e3dd0cdf
3 changed files with 47 additions and 20 deletions
+4 -16
View File
@@ -26,6 +26,7 @@ use App\Models\RedPacketClaim;
use App\Models\RedPacketEnvelope; use App\Models\RedPacketEnvelope;
use App\Models\User; use App\Models\User;
use App\Services\ChatStateService; use App\Services\ChatStateService;
use App\Services\GameBetBroadcastService;
use App\Services\PositionPermissionService; use App\Services\PositionPermissionService;
use App\Services\UserCurrencyService; use App\Services\UserCurrencyService;
use App\Support\PositionPermissionRegistry; use App\Support\PositionPermissionRegistry;
@@ -58,6 +59,7 @@ class RedPacketController extends Controller
private readonly ChatStateService $chatState, private readonly ChatStateService $chatState,
private readonly UserCurrencyService $currencyService, private readonly UserCurrencyService $currencyService,
private readonly PositionPermissionService $positionPermissionService, private readonly PositionPermissionService $positionPermissionService,
private readonly GameBetBroadcastService $betBroadcastService,
) {} ) {}
/** /**
@@ -357,23 +359,9 @@ class RedPacketController extends Controller
type: $envelopeType, type: $envelopeType,
)); ));
// 在聊天室发送领取播报(所有人可见) // 在聊天室发送领取播报并附带右下角通知,提醒房间内所有在线人员。
$typeLabel = $envelopeType === 'exp' ? '经验' : '金币'; $typeLabel = $envelopeType === 'exp' ? '经验' : '金币';
$typeIcon = $envelopeType === 'exp' ? '✨' : '💰'; $this->betBroadcastService->redPacketClaimed($roomId, $user->username, $amount, $envelopeType);
$claimedMsg = [
'id' => $this->chatState->nextMessageId($roomId),
'room_id' => $roomId,
'from_user' => '系统传音',
'to_user' => '',
'content' => "🧧 <b>{$user->username}</b> 抢到了 <b>{$amount}</b> {$typeLabel}礼包!{$typeIcon}",
'is_secret' => false,
'font_color' => $envelopeType === 'exp' ? '#6d28d9' : '#d97706',
'action' => '',
'sent_at' => now()->toDateTimeString(),
];
$this->chatState->pushMessage($roomId, $claimedMsg);
broadcast(new MessageSent($roomId, $claimedMsg));
SaveMessageJob::dispatch($claimedMsg);
$balanceField = $envelopeType === 'exp' ? 'exp_num' : 'jjb'; $balanceField = $envelopeType === 'exp' ? 'exp_num' : 'jjb';
$balanceNow = $user->fresh()->$balanceField; $balanceNow = $user->fresh()->$balanceField;
+25 -4
View File
@@ -1,9 +1,9 @@
<?php <?php
/** /**
* 文件功能:游戏下注公屏右下角通知广播服务 * 文件功能:游戏下注与奖励公屏右下角通知广播服务
* *
* 统一处理百家乐、赛马、双色球等游戏下注成功后的公屏消息、 * 统一处理百家乐、赛马、双色球等游戏下注或奖励领取成功后的公屏消息、
* 右下角 Toast 通知载荷和异步落库,避免各玩法重复拼装广播结构。 * 右下角 Toast 通知载荷和异步落库,避免各玩法重复拼装广播结构。
*/ */
@@ -13,7 +13,7 @@ use App\Events\MessageSent;
use App\Jobs\SaveMessageJob; use App\Jobs\SaveMessageJob;
/** /**
* 类功能:为游戏下注成功事件生成并广播全员可见通知。 * 类功能:为游戏下注和奖励领取成功事件生成并广播全员可见通知。
*/ */
class GameBetBroadcastService class GameBetBroadcastService
{ {
@@ -77,7 +77,28 @@ class GameBetBroadcastService
} }
/** /**
* 推送带右下角通知载荷的公屏游戏下注消息 * 广播红包领取成功通知
*/
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,
);
}
/**
* 推送带右下角通知载荷的公屏游戏消息。
*/ */
private function pushBetMessage( private function pushBetMessage(
int $roomId, int $roomId,
+18
View File
@@ -1,5 +1,11 @@
<?php <?php
/**
* 文件功能:礼包红包控制器功能测试
*
* 覆盖礼包发放权限、领取入账、领取广播、状态查询和重复领取约束。
*/
namespace Tests\Feature; namespace Tests\Feature;
use App\Events\RedPacketClaimed; use App\Events\RedPacketClaimed;
@@ -262,6 +268,18 @@ class RedPacketControllerTest extends TestCase
&& $event->remainingCount === 9 && $event->remainingCount === 9
&& $event->type === 'gold'; && $event->type === 'gold';
}); });
$messages = Redis::lrange('room:1:messages', 0, -1);
$publicMessage = collect($messages)
->map(fn (string $item) => json_decode($item, true))
->first(fn (array $item) => ($item['to_user'] ?? null) === '大家'
&& ($item['toast_notification']['title'] ?? null) === '🧧 有人领取红包'
&& str_contains((string) ($item['toast_notification']['message'] ?? ''), $user->username));
$this->assertNotNull($publicMessage);
$this->assertFalse((bool) ($publicMessage['is_secret'] ?? true));
$this->assertStringContainsString('金币礼包', (string) ($publicMessage['toast_notification']['message'] ?? ''));
$this->assertSame('🧧', $publicMessage['toast_notification']['icon'] ?? null);
} }
/** /**