null, 'bets' => [], 'candidate_numbers' => [], 'ai_default_number' => null, 'server_time' => time(), ]; } $bets = Db::name('bet_order') ->where('period_id', (int) $record['id']) ->order('id', 'desc') ->limit(200) ->select() ->toArray(); $candidates = []; $bestNumber = null; $bestLoss = null; for ($n = 1; $n <= 36; $n++) { $loss = self::estimateLossForNumber($bets, $n); $candidates[] = [ 'number' => $n, 'estimated_loss' => $loss, ]; if ($bestLoss === null || bccomp((string) $loss, (string) $bestLoss, 4) < 0) { $bestLoss = $loss; $bestNumber = $n; } } return [ 'record' => $record, 'bets' => array_map(static function (array $row): array { return [ 'id' => (int) $row['id'], 'user_id' => (int) $row['user_id'], 'period_no' => (string) $row['period_no'], 'pick_numbers' => $row['pick_numbers'], 'unit_amount' => (string) $row['unit_amount'], 'total_amount' => (string) $row['total_amount'], 'streak_at_bet' => (int) $row['streak_at_bet'], 'create_time' => (int) $row['create_time'], ]; }, $bets), 'candidate_numbers' => $candidates, 'ai_default_number' => $bestNumber, 'server_time' => time(), ]; } public static function publishSnapshot(?int $recordId = null): void { try { $payload = self::buildSnapshot($recordId); $api = new Api( str_replace('0.0.0.0', '127.0.0.1', (string) config('plugin.webman.push.app.api')), (string) config('plugin.webman.push.app.app_key'), (string) config('plugin.webman.push.app.app_secret') ); $api->trigger(self::CHANNEL, self::EVENT, $payload); } catch (Throwable) { } } private static function resolveRecord(?int $recordId): ?array { if ($recordId !== null && $recordId > 0) { $row = Db::name('game_record')->where('id', $recordId)->find(); if ($row) { return $row; } } return Db::name('game_record')->whereIn('status', [0, 1, 2, 3])->order('id', 'desc')->find(); } private static function estimateLossForNumber(array $bets, int $number): string { $payout = '0.0000'; foreach ($bets as $bet) { $pickNumbers = $bet['pick_numbers']; if (is_string($pickNumbers)) { $decoded = json_decode($pickNumbers, true); $pickNumbers = is_array($decoded) ? $decoded : []; } if (!is_array($pickNumbers)) { $pickNumbers = []; } if (!in_array($number, array_map('intval', $pickNumbers), true)) { continue; } $unit = (string) ($bet['unit_amount'] ?? '0'); $streak = (int) ($bet['streak_at_bet'] ?? 0); $odds = (string) (($streak + 1) * self::BASE_ODDS); $orderPayout = bcmul($unit, $odds, 4); $payout = bcadd($payout, $orderPayout, 4); } return $payout; } }