From ab474400167fc8693469c1cc628957a1e7c604d8 Mon Sep 17 00:00:00 2001 From: zhenhui <1276357500@qq.com> Date: Thu, 28 May 2026 16:06:04 +0800 Subject: [PATCH] =?UTF-8?q?1.=E4=BC=98=E5=8C=96websocket=E4=B8=AD=E7=9A=84?= =?UTF-8?q?jackpot.hit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/common/service/GameBetSettleService.php | 59 +++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/app/common/service/GameBetSettleService.php b/app/common/service/GameBetSettleService.php index 79fdc0d..a3620c8 100644 --- a/app/common/service/GameBetSettleService.php +++ b/app/common/service/GameBetSettleService.php @@ -38,6 +38,53 @@ final class GameBetSettleService /** jackpot.hit 去重(独立于 settleNotify,避免 recover/补偿路径漏广播) */ private const JACKPOT_HIT_DEDUP_PREFIX = 'dfw:v1:ws:jackpot_hit:'; + /** + * 从 bet.win 聚合载荷重建 jackpot.hit 广播(用于兜底:jackpot_hits 聚合缺失或旧逻辑漏记时)。 + * + * @param list> $betWins + * @return list + */ + private static function buildJackpotHitsFromBetWins(array $betWins, string $periodNo, int $resultNumber): array + { + if ($betWins === [] || $periodNo === '' || $resultNumber < 1) { + return []; + } + $byUser = []; + foreach ($betWins as $row) { + if (!is_array($row)) { + continue; + } + if (empty($row['is_jackpot'])) { + continue; + } + $uid = filter_var($row['user_id'] ?? 0, FILTER_VALIDATE_INT); + if ($uid === false || $uid <= 0) { + continue; + } + $total = isset($row['total_win']) && is_scalar($row['total_win']) ? (string) $row['total_win'] : '0.00'; + if (!isset($byUser[$uid])) { + $byUser[$uid] = '0.00'; + } + $byUser[$uid] = bcadd((string) $byUser[$uid], bcadd($total, '0', 2), 2); + } + if ($byUser === []) { + return []; + } + $userIds = array_map('intval', array_keys($byUser)); + $nameMap = self::loadUserDisplayNames($userIds); + $out = []; + foreach ($userIds as $uid) { + $out[] = [ + 'user_id' => $uid, + 'nickname' => $nameMap[$uid] ?? ('用户' . $uid), + 'period_no' => $periodNo, + 'total_win' => (string) ($byUser[$uid] ?? '0.00'), + 'result_number' => $resultNumber, + ]; + } + return $out; + } + /** * 对指定期次按开奖号码结算所有「待开奖」注单;同一注单幂等(仅 status=1 会更新)。 * @@ -516,6 +563,18 @@ final class GameBetSettleService // jackpot.hit 独立去重:即使 settleNotify 已被占位(recover/补偿路径)也允许补广播一次 $jackpotHits = is_array($settleOut['jackpot_hits'] ?? null) ? $settleOut['jackpot_hits'] : []; + if ($jackpotHits === [] && $betWins !== []) { + $rebuilt = self::buildJackpotHitsFromBetWins($betWins, $periodNo, $resultNumber); + if ($rebuilt !== []) { + Log::channel('ws')->warning('jackpot.hit rebuilt from bet_wins (jackpot_hits empty)', [ + 'period_id' => $periodId, + 'period_no' => $periodNo, + 'result_number' => $resultNumber, + 'hit_count' => count($rebuilt), + ]); + $jackpotHits = $rebuilt; + } + } self::publishJackpotHitsAfterCommit($jackpotHits, $periodId, $periodNo, $resultNumber); if (($settledCount !== false && $settledCount > 0) || $hasStreak || $hasWallet) {