优化百家乐提醒

This commit is contained in:
2026-04-14 22:09:03 +08:00
parent 392f46769c
commit a2e51f5668
3 changed files with 236 additions and 1 deletions
+97 -1
View File
@@ -96,8 +96,9 @@ class CloseBaccaratRoundJob implements ShouldQueue
// 收集各用户输赢结果,用于公屏展示
$winners = [];
$losers = [];
$participantSettlements = [];
DB::transaction(function () use ($bets, $result, $config, $currency, $lossCoverService, &$totalPayout, &$winners, &$losers) {
DB::transaction(function () use ($bets, $result, $config, $currency, $lossCoverService, &$totalPayout, &$winners, &$losers, &$participantSettlements) {
foreach ($bets as $bet) {
/** @var \App\Models\BaccaratBet $bet */
$username = $bet->user->username ?? '匿名';
@@ -107,6 +108,7 @@ class CloseBaccaratRoundJob implements ShouldQueue
$bet->update(['status' => 'lost', 'payout' => 0]);
$lossCoverService->registerSettlement($bet->fresh());
$losers[] = "{$username}-{$bet->amount}";
$this->recordParticipantSettlement($participantSettlements, $bet, -$bet->amount, 0);
if ($username === 'AI小班长') {
$this->handleAiLoseStreak();
@@ -131,6 +133,8 @@ class CloseBaccaratRoundJob implements ShouldQueue
$totalPayout += $payout;
$lossCoverService->registerSettlement($bet->fresh());
$winners[] = "{$username}+".number_format($payout);
// 结算提醒展示的是本局净输赢,因此要扣除下注时已经支付的本金。
$this->recordParticipantSettlement($participantSettlements, $bet, $payout - $bet->amount, $payout);
if ($username === 'AI小班长') {
Redis::del('ai_baccarat_lose_streak'); // 赢了清空连输
@@ -139,6 +143,7 @@ class CloseBaccaratRoundJob implements ShouldQueue
$bet->update(['status' => 'lost', 'payout' => 0]);
$lossCoverService->registerSettlement($bet->fresh());
$losers[] = "{$username}-".number_format($bet->amount);
$this->recordParticipantSettlement($participantSettlements, $bet, -$bet->amount, 0);
if ($username === 'AI小班长') {
$this->handleAiLoseStreak();
@@ -166,6 +171,9 @@ class CloseBaccaratRoundJob implements ShouldQueue
// ── 公屏公告 ─────────────────────────────────────────────────
$this->pushResultMessage($round, $chatState, $winners, $losers);
// ── 参与者私聊提醒 ────────────────────────────────────────────
$this->pushParticipantToastNotifications($round, $chatState, $participantSettlements);
}
/**
@@ -180,6 +188,94 @@ class CloseBaccaratRoundJob implements ShouldQueue
}
}
/**
* 汇总单个参与者本局的下注、返还与净输赢金额。
*
* @param array<int, array<string, mixed>> $participantSettlements
*/
private function recordParticipantSettlement(array &$participantSettlements, BaccaratBet $bet, int $netChange, int $payout): void
{
if (! $bet->user) {
return;
}
$userId = (int) $bet->user->id;
$existing = $participantSettlements[$userId] ?? [
'user' => $bet->user,
'username' => $bet->user->username,
'bet_amount' => 0,
'payout' => 0,
'net_change' => 0,
];
// 同一用户若存在多条下注记录,这里统一聚合成本局总输赢。
$existing['bet_amount'] += (int) $bet->amount;
$existing['payout'] += $payout;
$existing['net_change'] += $netChange;
$participantSettlements[$userId] = $existing;
}
/**
* 向参与本局的用户发送私聊结算提示,并复用右下角 toast 通知。
*
* @param array<int, array<string, mixed>> $participantSettlements
*/
private function pushParticipantToastNotifications(BaccaratRound $round, ChatStateService $chatState, array $participantSettlements): void
{
if ($participantSettlements === []) {
return;
}
$roomId = 1;
$roundResultLabel = $round->resultLabel();
foreach ($participantSettlements as $settlement) {
$user = $settlement['user'];
$username = (string) $settlement['username'];
$betAmount = (int) $settlement['bet_amount'];
$netChange = (int) $settlement['net_change'];
$freshGold = (int) ($user->fresh()->jjb ?? 0);
$absNetChange = number_format(abs($netChange));
$betAmountText = number_format($betAmount);
$summaryText = $netChange > 0
? "净赢 {$absNetChange} 金币"
: ($netChange < 0 ? "净输 {$absNetChange} 金币" : '不输不赢');
$toastIcon = $netChange > 0 ? '🎉' : ($netChange < 0 ? '📉' : '🎲');
$toastColor = $netChange > 0 ? '#10b981' : ($netChange < 0 ? '#ef4444' : '#3b82f6');
$toastMessage = $netChange > 0
? "本局结果:<b>{$roundResultLabel}</b><br>你本局净赢 <b>+{$absNetChange}</b> 金币!"
: ($netChange < 0
? "本局结果:<b>{$roundResultLabel}</b><br>你本局净输 <b>-{$absNetChange}</b> 金币。"
: "本局结果:<b>{$roundResultLabel}</b><br>你本局不输不赢。");
// 写入系统私聊,确保用户刷新聊天室后仍能看到本局输赢记录。
$msg = [
'id' => $chatState->nextMessageId($roomId),
'room_id' => $roomId,
'from_user' => '系统',
'to_user' => $username,
'content' => "🎲 百家乐第 #{$round->id} 局已开奖,结果:{$roundResultLabel}。你本局下注 {$betAmountText} 金币,{$summaryText};当前金币:{$freshGold} 枚。",
'is_secret' => true,
'font_color' => '#8b5cf6',
'action' => '',
'sent_at' => now()->toDateTimeString(),
'toast_notification' => [
'title' => '🎲 百家乐本局结算',
'message' => $toastMessage,
'icon' => $toastIcon,
'color' => $toastColor,
'duration' => 10000,
],
];
$chatState->pushMessage($roomId, $msg);
broadcast(new MessageSent($roomId, $msg));
SaveMessageJob::dispatch($msg);
}
}
/**
* 向公屏发送开奖结果系统消息(含各用户输赢情况)。
*