1.优化开奖和推送

2.新增控制连续开奖赔率
This commit is contained in:
2026-04-20 10:02:27 +08:00
parent c184fa8a46
commit 24aab111b5
18 changed files with 749 additions and 37 deletions

View File

@@ -0,0 +1,205 @@
<?php
declare(strict_types=1);
namespace app\common\library\game;
use support\think\Db;
/**
* 连胜奖励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 = Db::name('game_config')->where('config_key', self::CONFIG_KEY)->find();
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;
}
}