feat: 添加新的错误码以支持配置版本管理,更新彩票配置以启用手动审核,增强 API 路由以支持玩法和赔率版本化管理

This commit is contained in:
2026-05-11 10:08:48 +08:00
parent aeaf124096
commit 067c2b39f5
41 changed files with 2578 additions and 1 deletions

View File

@@ -15,6 +15,8 @@ class DatabaseSeeder extends Seeder
$this->call([
CurrencySeeder::class,
PlayTypeSeeder::class,
OperationalConfigV1Seeder::class,
OddsPrizeScopesBackfillSeeder::class,
LotterySettingsSeeder::class,
]);

View File

@@ -0,0 +1,20 @@
<?php
namespace Database\Seeders;
use App\Models\OddsVersion;
use App\Support\OddsStandardScopes;
use Illuminate\Database\Seeder;
/**
* 为历史 odds_versions 补全 §5.5 五档 prize_scope幂等可重复执行
*/
class OddsPrizeScopesBackfillSeeder extends Seeder
{
public function run(): void
{
foreach (OddsVersion::query()->orderBy('id')->cursor() as $version) {
OddsStandardScopes::syncMissingForVersion($version);
}
}
}

View File

@@ -0,0 +1,95 @@
<?php
namespace Database\Seeders;
use App\Lottery\ConfigVersionStatus;
use App\Models\OddsItem;
use App\Models\OddsVersion;
use App\Models\PlayConfigItem;
use App\Models\PlayConfigVersion;
use App\Models\PlayType;
use App\Models\RiskCapItem;
use App\Models\RiskCapVersion;
use App\Support\OddsStandardScopes;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
/**
* 阶段 4:写入首套 **active** 玩法配置 / 赔率 / 风控封顶版本(依赖 {@see PlayTypeSeeder}{@see CurrencySeeder})。
*/
class OperationalConfigV1Seeder extends Seeder
{
public function run(): void
{
if (PlayConfigVersion::query()->where('status', ConfigVersionStatus::Active->value)->exists()) {
return;
}
DB::transaction(function (): void {
$playVersion = PlayConfigVersion::query()->create([
'version_no' => 1,
'status' => ConfigVersionStatus::Active->value,
'effective_at' => now(),
'updated_by' => null,
'reason' => 'seed:v1',
]);
foreach (PlayType::query()->orderBy('sort_order')->orderBy('play_code')->get() as $pt) {
PlayConfigItem::query()->create([
'version_id' => $playVersion->id,
'play_code' => $pt->play_code,
'is_enabled' => (bool) $pt->is_enabled,
'min_bet_amount' => 100,
'max_bet_amount' => 500_000_000,
'display_order' => (int) $pt->sort_order,
'rule_text_zh' => null,
'rule_text_en' => null,
'rule_text_ne' => null,
'extra_config_json' => null,
]);
}
$oddsVersion = OddsVersion::query()->create([
'version_no' => 1,
'status' => ConfigVersionStatus::Active->value,
'effective_at' => now(),
'updated_by' => null,
'reason' => 'seed:v1',
]);
/** 对齐界面文档 §5.5:头/二/三/特别/安慰odds_value = 乘数×10000NPR 基准展示口径) */
foreach (PlayType::query()->orderBy('sort_order')->orderBy('play_code')->get() as $pt) {
foreach (OddsStandardScopes::PRESET_ODDS_BY_SCOPE as $scope => $oddsValue) {
OddsItem::query()->create([
'version_id' => $oddsVersion->id,
'play_code' => $pt->play_code,
'prize_scope' => $scope,
'odds_value' => $oddsValue,
'rebate_rate' => 0,
'commission_rate' => 0,
'currency_code' => 'NPR',
'extra_config_json' => null,
]);
}
}
$riskVersion = RiskCapVersion::query()->create([
'version_no' => 1,
'status' => ConfigVersionStatus::Active->value,
'effective_at' => now(),
'updated_by' => null,
'reason' => 'seed:v1',
]);
foreach (['0000', '1234', '9999'] as $num) {
RiskCapItem::query()->create([
'version_id' => $riskVersion->id,
'draw_id' => null,
'normalized_number' => $num,
'cap_amount' => 50_000_000_000,
'cap_type' => 'per_number',
]);
}
});
}
}