完善百家乐买单补偿自动领取与聊天室播报

This commit is contained in:
2026-04-11 23:43:07 +08:00
parent e43dceab2c
commit f4a632a9c1
3 changed files with 268 additions and 1 deletions
+74 -1
View File
@@ -11,6 +11,7 @@ namespace App\Services;
use App\Enums\CurrencySource;
use App\Events\MessageSent;
use App\Jobs\AiClaimBaccaratLossCoverJob;
use App\Jobs\SaveMessageJob;
use App\Models\BaccaratBet;
use App\Models\BaccaratLossCoverEvent;
@@ -198,7 +199,7 @@ class BaccaratLossCoverService
return ['ok' => false, 'message' => '当前活动暂未开放领取,或已超过领取时间。'];
}
return DB::transaction(function () use ($event, $user): array {
$result = DB::transaction(function () use ($event, $user): array {
$record = BaccaratLossCoverRecord::query()
->where('event_id', $event->id)
->where('user_id', $user->id)
@@ -247,6 +248,13 @@ class BaccaratLossCoverService
'amount' => $amount,
];
});
// 领取成功后,需要向聊天室广播一条同款百家乐风格消息,方便其他人快速领取。
if (($result['ok'] ?? false) === true && isset($result['amount'])) {
$this->pushClaimMessage($event->fresh(), $user, (int) $result['amount']);
}
return $result;
}
/**
@@ -396,6 +404,9 @@ class BaccaratLossCoverService
$this->pushRoomMessage($content, '#7c3aed');
$event->update(['ended_notice_sent_at' => now()]);
// 活动开放领取后,为 AI小班长补发一次自动领取任务。
$this->dispatchAiAutoClaimJob($event->fresh());
}
/**
@@ -419,4 +430,66 @@ class BaccaratLossCoverService
broadcast(new MessageSent(1, $message));
SaveMessageJob::dispatch($message);
}
/**
* 在用户领取补偿成功后,向聊天室广播领取播报。
*/
private function pushClaimMessage(?BaccaratLossCoverEvent $event, User $user, int $amount): void
{
if (! $event) {
return;
}
$formattedAmount = number_format($amount);
$button = $event->status === 'claimable'
? ' <button onclick="claimBaccaratLossCover('.$event->id.')" style="margin-left:8px;padding:3px 12px;background:#16a34a;color:#fff;border:none;border-radius:12px;cursor:pointer;font-size:12px;font-weight:bold;">领取补偿</button>'
: '';
// 领取成功的公屏格式复用百家乐参与播报风格,保证聊天室感知一致。
$content = "🌟 🎲 <b>{$user->username}</b> 领取了 <b>{$formattedAmount}</b> 金币补偿!✨{$button}";
$message = [
'id' => $this->chatState->nextMessageId(1),
'room_id' => 1,
'from_user' => '系统传音',
'to_user' => '大家',
'content' => $content,
'is_secret' => false,
'font_color' => '#d97706',
'action' => '',
'sent_at' => now()->toDateTimeString(),
];
$this->chatState->pushMessage(1, $message);
broadcast(new MessageSent(1, $message));
SaveMessageJob::dispatch($message);
}
/**
* 在活动可领取后,为 AI小班长派发自动领取补偿任务。
*/
private function dispatchAiAutoClaimJob(?BaccaratLossCoverEvent $event): void
{
if (! $event || $event->status !== 'claimable') {
return;
}
$aiUserId = User::query()->where('username', 'AI小班长')->value('id');
if (! $aiUserId) {
return;
}
$hasPendingRecord = BaccaratLossCoverRecord::query()
->where('event_id', $event->id)
->where('user_id', $aiUserId)
->where('claim_status', 'pending')
->where('compensation_amount', '>', 0)
->exists();
// 只有 AI小班长确实存在待领取补偿时,才派发自动领取任务。
if (! $hasPendingRecord) {
return;
}
AiClaimBaccaratLossCoverJob::dispatch($event->id);
}
}