1.ws优化bet.win订阅,修复中大奖没有推送

This commit is contained in:
2026-05-26 19:10:23 +08:00
parent 6d3711e1db
commit 4c69a8c77f
3 changed files with 90 additions and 17 deletions

View File

@@ -328,7 +328,7 @@ final class GameBetSettleService
if ($userId === false || $userId <= 0) {
continue;
}
if ($periodId > 0 && !self::markBetWinNotifyOnce($periodId, $userId)) {
if ($periodId > 0 && self::hasBetWinNotifyMarked($periodId, $userId)) {
continue;
}
$isJackpot = !empty($payload['is_jackpot']);
@@ -340,6 +340,15 @@ final class GameBetSettleService
'server_time' => $now,
]), $userId);
GameWebSocketEventBus::publish(self::TOPIC_BET_WIN, $data);
if ($periodId > 0) {
self::markBetWinNotifyOnce($periodId, $userId);
}
Log::info('bet.win published', [
'period_id' => $periodId,
'user_id' => $userId,
'total_win' => $payload['total_win'] ?? '',
'is_jackpot' => $isJackpot,
]);
}
}
@@ -489,9 +498,13 @@ final class GameBetSettleService
}
}
$effectiveBetWins = $betWins;
if ($effectiveBetWins === [] && $periodId > 0 && $resultNumber > 0) {
$effectiveBetWins = self::buildBetWinPayloadsFromSettledOrders($periodId, $resultNumber);
$effectiveBetWins = $periodId > 0 && $resultNumber > 0
? self::buildBetWinPayloadsFromSettledOrders($periodId, $resultNumber)
: [];
if ($effectiveBetWins === []) {
$effectiveBetWins = $betWins;
} else {
$effectiveBetWins = self::mergeBetWinPayloads($betWins, $effectiveBetWins);
}
self::publishBetWinsAfterCommit($effectiveBetWins, $periodId);
if ($periodId > 0 && $resultNumber > 0) {
@@ -520,13 +533,8 @@ final class GameBetSettleService
if ($userId === false || $userId <= 0) {
continue;
}
$key = self::BET_WIN_NOTIFY_DEDUP_PREFIX . $periodId . ':' . $userId;
try {
$existing = Redis::get($key);
if ($existing !== false && $existing !== null && $existing !== '') {
continue;
}
} catch (Throwable) {
if (self::hasBetWinNotifyMarked($periodId, $userId)) {
continue;
}
$missing[] = $payload;
}
@@ -540,21 +548,65 @@ final class GameBetSettleService
}
}
private static function markBetWinNotifyOnce(int $periodId, int $userId): bool
private static function hasBetWinNotifyMarked(int $periodId, int $userId): bool
{
if ($periodId <= 0 || $userId <= 0) {
return true;
return false;
}
$key = self::BET_WIN_NOTIFY_DEDUP_PREFIX . $periodId . ':' . $userId;
try {
$ok = Redis::set($key, '1', ['nx', 'ex' => 86400]);
$existing = Redis::get($key);
return $ok === true || $ok === 'OK';
return $existing !== false && $existing !== null && $existing !== '';
} catch (Throwable) {
return true;
return false;
}
}
private static function markBetWinNotifyOnce(int $periodId, int $userId): void
{
if ($periodId <= 0 || $userId <= 0) {
return;
}
$key = self::BET_WIN_NOTIFY_DEDUP_PREFIX . $periodId . ':' . $userId;
try {
Redis::setEx($key, 86400, '1');
} catch (Throwable) {
}
}
/**
* @param list<array<string, mixed>> $primary
* @param list<array<string, mixed>> $secondary
* @return list<array<string, mixed>>
*/
private static function mergeBetWinPayloads(array $primary, array $secondary): array
{
/** @var array<int, array<string, mixed>> $byUser */
$byUser = [];
foreach (array_merge($primary, $secondary) as $payload) {
if (!is_array($payload)) {
continue;
}
$userId = filter_var($payload['user_id'] ?? 0, FILTER_VALIDATE_INT);
if ($userId === false || $userId <= 0) {
continue;
}
if (!isset($byUser[$userId])) {
$byUser[$userId] = $payload;
continue;
}
if (!empty($payload['is_jackpot'])) {
$byUser[$userId]['is_jackpot'] = true;
}
if (!empty($payload['payout_pending_review'])) {
$byUser[$userId]['payout_pending_review'] = true;
}
}
return array_values($byUser);
}
private static function markSettlementNotifyOnce(int $periodId): bool
{
if ($periodId <= 0) {