- 将玩法相关的显示名称字段统一为 `display_name`,移除多语言字段。 - 在 `PlayTypePatchController` 中新增即时切换玩法开关的功能,并推送大厅更新。 - 优化多个控制器和服务中的权限检查与数据处理逻辑,提升代码可读性与维护性。
147 lines
5.2 KiB
PHP
147 lines
5.2 KiB
PHP
<?php
|
||
|
||
namespace Database\Seeders;
|
||
|
||
use App\Models\Currency;
|
||
use App\Models\OddsItem;
|
||
use App\Models\PlayType;
|
||
use App\Models\OddsVersion;
|
||
use App\Models\PlayConfigItem;
|
||
use Illuminate\Database\Seeder;
|
||
use App\Models\PlayConfigVersion;
|
||
use Illuminate\Support\Facades\DB;
|
||
use App\Support\OddsStandardScopes;
|
||
use App\Lottery\ConfigVersionStatus;
|
||
|
||
/**
|
||
* 将「玩法目录」与已存在的玩法配置 / 赔率版本对齐(幂等,可反复执行)。
|
||
*
|
||
* 典型场景:`play_types` 已扩展,但某条 active/draft 的 `play_config_items` 或 `odds_items`
|
||
* 仍是早期子集,后台出现大量「无配置行」或赔率缺档。
|
||
*
|
||
* 执行:php artisan db:seed --class=PlayOperationalAlignmentSeeder
|
||
*/
|
||
final class PlayOperationalAlignmentSeeder extends Seeder
|
||
{
|
||
private const MIN_BET = 100;
|
||
|
||
private const MAX_BET = 500_000_000;
|
||
|
||
public function run(): void
|
||
{
|
||
$this->call(PlayTypeSeeder::class);
|
||
|
||
DB::transaction(function (): void {
|
||
$open = [ConfigVersionStatus::Active->value, ConfigVersionStatus::Draft->value];
|
||
|
||
foreach (PlayConfigVersion::query()->whereIn('status', $open)->orderBy('id')->cursor() as $version) {
|
||
$this->syncPlayConfigItems($version);
|
||
}
|
||
|
||
foreach (OddsVersion::query()->whereIn('status', $open)->orderBy('id')->cursor() as $version) {
|
||
$this->syncOddsItemsForAllPlayTypes($version);
|
||
}
|
||
});
|
||
}
|
||
|
||
private function syncPlayConfigItems(PlayConfigVersion $version): void
|
||
{
|
||
$vid = (int) $version->id;
|
||
$existing = PlayConfigItem::query()
|
||
->where('version_id', $vid)
|
||
->pluck('play_code')
|
||
->all();
|
||
$have = array_fill_keys($existing, true);
|
||
|
||
foreach (PlayType::query()->orderBy('sort_order')->orderBy('play_code')->cursor() as $pt) {
|
||
if (isset($have[$pt->play_code])) {
|
||
continue;
|
||
}
|
||
|
||
PlayConfigItem::query()->create([
|
||
'version_id' => $vid,
|
||
'play_code' => $pt->play_code,
|
||
'category' => $pt->category,
|
||
'dimension' => $pt->dimension,
|
||
'bet_mode' => $pt->bet_mode,
|
||
'display_name' => $pt->display_name,
|
||
'is_enabled' => (bool) $pt->is_enabled,
|
||
'min_bet_amount' => self::MIN_BET,
|
||
'max_bet_amount' => self::MAX_BET,
|
||
'display_order' => (int) $pt->sort_order,
|
||
'supports_multi_number' => (bool) $pt->supports_multi_number,
|
||
'reserved_rule_json' => $pt->reserved_rule_json,
|
||
'rule_text_zh' => null,
|
||
'rule_text_en' => null,
|
||
'rule_text_ne' => null,
|
||
'extra_config_json' => null,
|
||
]);
|
||
}
|
||
}
|
||
|
||
private function syncOddsItemsForAllPlayTypes(OddsVersion $version): void
|
||
{
|
||
$vid = (int) $version->id;
|
||
|
||
$currencies = OddsItem::query()
|
||
->where('version_id', $vid)
|
||
->distinct()
|
||
->pluck('currency_code')
|
||
->filter(static fn ($c) => is_string($c) && $c !== '')
|
||
->values();
|
||
|
||
if ($currencies->isEmpty()) {
|
||
$fallback = Currency::query()
|
||
->where('is_bettable', true)
|
||
->where('is_enabled', true)
|
||
->orderBy('code')
|
||
->value('code');
|
||
if ($fallback === null || $fallback === '') {
|
||
return;
|
||
}
|
||
$currencies = collect([strtoupper((string) $fallback)]);
|
||
}
|
||
|
||
foreach ($currencies as $currencyCode) {
|
||
$currencyCode = strtoupper((string) $currencyCode);
|
||
|
||
foreach (PlayType::query()->orderBy('sort_order')->orderBy('play_code')->cursor() as $pt) {
|
||
$playCode = $pt->play_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 (OddsStandardScopes::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,
|
||
]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|