104 lines
3.6 KiB
PHP
104 lines
3.6 KiB
PHP
<?php
|
||
|
||
namespace App\Support;
|
||
|
||
use App\Models\Currency;
|
||
use App\Models\OddsItem;
|
||
use App\Models\PlayType;
|
||
use App\Models\OddsVersion;
|
||
use Illuminate\Support\Facades\DB;
|
||
|
||
/**
|
||
* 界面文档 §5.5:每个玩法需具备的五档 prize_scope;odds_value = 乘数×10000。
|
||
*/
|
||
final class OddsStandardScopes
|
||
{
|
||
/** @var array<string, int> */
|
||
public const PRESET_ODDS_BY_SCOPE = [
|
||
'first' => 250_000,
|
||
'second' => 110_000,
|
||
'third' => 55_000,
|
||
'starter' => 22_000,
|
||
'consolation' => 6_500,
|
||
];
|
||
|
||
/** @var list<string> */
|
||
public const SCOPE_KEYS = ['first', 'second', 'third', 'starter', 'consolation'];
|
||
|
||
/**
|
||
* 为指定赔率版本补全缺失的标准五档行(幂等)。
|
||
*
|
||
* 仅对「该版本里已出现过的 (play_code, currency_code)」补全,避免给从未配置过的玩法凭空加行。
|
||
* 若版本下无任何 odds_items,则用当前全部玩法 × 首个可下注币种补全。
|
||
*/
|
||
public static function syncMissingForVersion(OddsVersion $version): void
|
||
{
|
||
DB::transaction(function () use ($version): void {
|
||
$vid = (int) $version->id;
|
||
|
||
$pairs = OddsItem::query()
|
||
->where('version_id', $vid)
|
||
->select(['play_code', 'currency_code'])
|
||
->distinct()
|
||
->get();
|
||
|
||
if ($pairs->isEmpty()) {
|
||
$currencyCode = Currency::query()
|
||
->where('is_bettable', true)
|
||
->where('is_enabled', true)
|
||
->orderBy('code')
|
||
->value('code');
|
||
if ($currencyCode === null || $currencyCode === '') {
|
||
return;
|
||
}
|
||
$pairs = PlayType::query()
|
||
->orderBy('sort_order')
|
||
->orderBy('play_code')
|
||
->get(['play_code'])
|
||
->map(fn (PlayType $pt) => (object) [
|
||
'play_code' => $pt->play_code,
|
||
'currency_code' => $currencyCode,
|
||
]);
|
||
}
|
||
|
||
foreach ($pairs as $pair) {
|
||
$playCode = (string) $pair->play_code;
|
||
$currencyCode = strtoupper((string) $pair->currency_code);
|
||
|
||
$anchor = OddsItem::query()
|
||
->where('version_id', $vid)
|
||
->where('play_code', $playCode)
|
||
->where('currency_code', $currencyCode)
|
||
->orderByDesc('id')
|
||
->first();
|
||
|
||
$rebate = (float) ($anchor?->rebate_rate ?? 0);
|
||
$commission = (float) ($anchor?->commission_rate ?? 0);
|
||
|
||
foreach (self::PRESET_ODDS_BY_SCOPE as $scope => $oddsValue) {
|
||
$exists = OddsItem::query()
|
||
->where('version_id', $vid)
|
||
->where('play_code', $playCode)
|
||
->where('currency_code', $currencyCode)
|
||
->where('prize_scope', $scope)
|
||
->exists();
|
||
if ($exists) {
|
||
continue;
|
||
}
|
||
|
||
OddsItem::query()->create([
|
||
'version_id' => $vid,
|
||
'play_code' => $playCode,
|
||
'prize_scope' => $scope,
|
||
'odds_value' => $oddsValue,
|
||
'rebate_rate' => $rebate,
|
||
'commission_rate' => $commission,
|
||
'currency_code' => $currencyCode,
|
||
'extra_config_json' => null,
|
||
]);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
}
|