Files
webman-buildadmin/app/common/library/game/StreakWinReward.php
2026-04-20 10:31:14 +08:00

206 lines
5.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\common\library\game;
use app\common\service\GameHotDataRedis;
/**
* 连胜奖励game_config.streak_win_reward按「连胜档位」110 配置赔率系数与是否大奖。
*
* 派彩total_amount × odds_factor与后台「连胜奖励」表一致不再额外 ×33
*/
final class StreakWinReward
{
public const CONFIG_KEY = 'streak_win_reward';
/** @var list<array{streak: int, odds_factor: int, is_jackpot: bool}>|null */
private static ?array $cache = null;
public static function clearCache(): void
{
self::$cache = null;
}
/**
* @return list<array{streak: int, odds_factor: int, is_jackpot: bool}>
*/
public static function defaultRows(): array
{
$out = [];
for ($s = 1; $s <= 10; $s++) {
$out[] = [
'streak' => $s,
'odds_factor' => $s,
'is_jackpot' => $s === 10,
];
}
return $out;
}
/**
* @param mixed $raw
*
* @return list<array{streak: int, odds_factor: int, is_jackpot: bool}>
*/
public static function parseFromConfigValue($raw): array
{
if (!is_string($raw) || trim($raw) === '') {
return self::defaultRows();
}
$decoded = json_decode($raw, true);
if (!is_array($decoded)) {
return self::defaultRows();
}
$list = $decoded['rows'] ?? $decoded;
if (!is_array($list)) {
return self::defaultRows();
}
$byStreak = [];
foreach ($list as $row) {
if (!is_array($row)) {
continue;
}
$streak = isset($row['streak']) && is_numeric($row['streak']) ? (int) $row['streak'] : 0;
if ($streak < 1 || $streak > 10) {
continue;
}
$factor = isset($row['odds_factor']) && is_numeric($row['odds_factor']) ? (int) $row['odds_factor'] : $streak;
if ($factor < 1) {
$factor = 1;
}
$jack = !empty($row['is_jackpot']);
$byStreak[$streak] = [
'streak' => $streak,
'odds_factor' => $factor,
'is_jackpot' => $jack,
];
}
$out = [];
for ($s = 1; $s <= 10; $s++) {
$out[] = $byStreak[$s] ?? [
'streak' => $s,
'odds_factor' => $s,
'is_jackpot' => $s === 10,
];
}
return $out;
}
/**
* 从库加载并缓存
*
* @return list<array{streak: int, odds_factor: int, is_jackpot: bool}>
*/
public static function loadRows(): array
{
if (self::$cache !== null) {
return self::$cache;
}
$row = GameHotDataRedis::gameConfigRow(self::CONFIG_KEY);
self::$cache = self::parseFromConfigValue($row['config_value'] ?? null);
return self::$cache;
}
/**
* streak_at_bet 为下注时快照0 表示尚未连胜);档位取 min(streak_at_bet+1, 10)。
*/
public static function levelFromStreakAtBet(int $streakAtBet): int
{
$level = $streakAtBet + 1;
if ($level < 1) {
$level = 1;
}
if ($level > 10) {
$level = 10;
}
return $level;
}
/**
* @return array{streak: int, odds_factor: int, is_jackpot: bool}
*/
public static function rowForStreakAtBet(int $streakAtBet): array
{
$level = self::levelFromStreakAtBet($streakAtBet);
foreach (self::loadRows() as $row) {
if ((int) ($row['streak'] ?? 0) === $level) {
return $row;
}
}
return [
'streak' => $level,
'odds_factor' => $level,
'is_jackpot' => $level === 10,
];
}
public static function isJackpotForStreakAtBet(int $streakAtBet): bool
{
return self::rowForStreakAtBet($streakAtBet)['is_jackpot'] === true;
}
/**
* 返回该注单适用的「赔率乘数」字符串(= 配置档位的 odds_factor供 bcmul(total_amount, ..., 4)。
*/
public static function totalOddsMultiplierForStreakAtBet(int $streakAtBet): string
{
$factor = (int) self::rowForStreakAtBet($streakAtBet)['odds_factor'];
if ($factor < 1) {
$factor = 1;
}
return bcadd((string) $factor, '0', 4);
}
/**
* @param list<array{streak: int, odds_factor: int, is_jackpot: bool}> $rows
*/
public static function encodeForDb(array $rows): string
{
$normalized = [];
for ($s = 1; $s <= 10; $s++) {
$found = null;
foreach ($rows as $r) {
if (!is_array($r)) {
continue;
}
$st = isset($r['streak']) && is_numeric($r['streak']) ? (int) $r['streak'] : 0;
if ($st === $s) {
$found = $r;
break;
}
}
if ($found === null) {
$normalized[] = [
'streak' => $s,
'odds_factor' => $s,
'is_jackpot' => $s === 10,
];
} else {
$f = isset($found['odds_factor']) && is_numeric($found['odds_factor']) ? (int) $found['odds_factor'] : $s;
if ($f < 1) {
$f = 1;
}
$normalized[] = [
'streak' => $s,
'odds_factor' => $f,
'is_jackpot' => !empty($found['is_jackpot']),
];
}
}
$json = json_encode(['rows' => $normalized], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if ($json === false) {
return '{"rows":[]}';
}
return $json;
}
}