feat(lottery): 扩展传统马来赔率、玩法结算与开注商短码支持
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('bet_providers', function (Blueprint $table): void {
|
||||
$table->string('short_code', 1)->nullable()->after('name');
|
||||
});
|
||||
|
||||
DB::table('bet_providers')->orderBy('id')->get(['id', 'code'])->each(function (object $provider): void {
|
||||
DB::table('bet_providers')
|
||||
->where('id', $provider->id)
|
||||
->update(['short_code' => strtoupper(substr((string) $provider->code, 0, 1))]);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('bet_providers', function (Blueprint $table): void {
|
||||
$table->dropColumn('short_code');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -10,9 +10,9 @@ final class BetProviderSeeder extends Seeder
|
||||
public function run(): void
|
||||
{
|
||||
$rows = [
|
||||
['code' => 'SG', 'name' => 'Singapore', 'sort_order' => 10],
|
||||
['code' => 'MY', 'name' => 'Malaysia', 'sort_order' => 20],
|
||||
['code' => 'TH', 'name' => 'Thailand', 'sort_order' => 30],
|
||||
['code' => 'SG', 'name' => 'Singapore', 'short_code' => 'S', 'sort_order' => 10],
|
||||
['code' => 'MY', 'name' => 'Malaysia', 'short_code' => 'M', 'sort_order' => 20],
|
||||
['code' => 'TH', 'name' => 'Thailand', 'short_code' => 'T', 'sort_order' => 30],
|
||||
];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
@@ -20,6 +20,7 @@ final class BetProviderSeeder extends Seeder
|
||||
['code' => $row['code']],
|
||||
[
|
||||
'name' => $row['name'],
|
||||
'short_code' => $row['short_code'],
|
||||
'is_enabled' => true,
|
||||
'sort_order' => $row['sort_order'],
|
||||
],
|
||||
|
||||
@@ -98,7 +98,7 @@ final class OperationalConfigV1Seeder extends Seeder
|
||||
|
||||
/** 对齐界面文档 §5.5:头/二/三/特别/安慰;odds_value = 乘数×10000(NPR 基准展示口径) */
|
||||
foreach (PlayType::query()->orderBy('sort_order')->orderBy('play_code')->get() as $pt) {
|
||||
foreach (OddsStandardScopes::PRESET_ODDS_BY_SCOPE as $scope => $oddsValue) {
|
||||
foreach (OddsStandardScopes::presetOddsForPlay((string) $pt->play_code) as $scope => $oddsValue) {
|
||||
OddsItem::query()->create([
|
||||
'version_id' => $oddsVersion->id,
|
||||
'play_code' => $pt->play_code,
|
||||
|
||||
@@ -118,7 +118,7 @@ final class PlayOperationalAlignmentSeeder extends Seeder
|
||||
$rebate = (float) ($anchor?->rebate_rate ?? 0);
|
||||
$commission = (float) ($anchor?->commission_rate ?? 0);
|
||||
|
||||
foreach (OddsStandardScopes::PRESET_ODDS_BY_SCOPE as $scope => $oddsValue) {
|
||||
foreach (OddsStandardScopes::presetOddsForPlay((string) $playCode) as $scope => $oddsValue) {
|
||||
$exists = OddsItem::query()
|
||||
->where('version_id', $vid)
|
||||
->where('play_code', $playCode)
|
||||
|
||||
@@ -17,6 +17,7 @@ final class PlayTypeSeeder extends Seeder
|
||||
array_merge($row, $defaults),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -25,24 +26,36 @@ final class PlayTypeSeeder extends Seeder
|
||||
private function rows(): array
|
||||
{
|
||||
return [
|
||||
$this->row('big', 'standard', 4, 'single', 'Big', 10),
|
||||
$this->row('small', 'standard', 4, 'single', 'Small', 20),
|
||||
$this->row('big', 'standard', 4, 'single', 'B', 10),
|
||||
$this->row('small', 'standard', 4, 'single', 'S', 20),
|
||||
|
||||
$this->row('pos_4a', 'position', 4, 'single', '4A', 30, false, ['prize_scope' => ['first']]),
|
||||
$this->row('pos_4b', 'position', 4, 'single', '4B', 40, false, ['prize_scope' => ['second']]),
|
||||
$this->row('pos_4c', 'position', 4, 'single', '4C', 50, false, ['prize_scope' => ['third']]),
|
||||
$this->row('pos_4d', 'position', 4, 'single', '4D', 60, false, ['prize_scope' => ['starter']]),
|
||||
$this->row('pos_4e', 'position', 4, 'single', '4E', 70, false, ['prize_scope' => ['consolation']]),
|
||||
$this->row('four_any', 'position', 4, 'single', '4N', 75, false, ['prize_scope' => ['first', 'second', 'third', 'starter', 'consolation']]),
|
||||
$this->row('four_top', 'position', 4, 'single', 'A', 76, false, ['prize_scope' => ['first', 'second', 'third']]),
|
||||
$this->row('four_lower', 'position', 4, 'single', 'C', 77, false, ['prize_scope' => ['starter', 'consolation']]),
|
||||
|
||||
$this->row('pos_3a', 'position', 3, 'single', '3A', 80, false, ['prize_scope' => ['first']]),
|
||||
$this->row('pos_3a', 'position', 3, 'single', 'A', 80, false, ['prize_scope' => ['first']]),
|
||||
$this->row('pos_3b', 'position', 3, 'single', '3B', 90, false, ['prize_scope' => ['second']]),
|
||||
$this->row('pos_3c', 'position', 3, 'single', '3C', 100, false, ['prize_scope' => ['third']]),
|
||||
$this->row('pos_3abc', 'position', 3, 'single', '3ABC', 110, false, ['prize_scope' => ['first', 'second', 'third']]),
|
||||
$this->row('pos_3d', 'position', 3, 'single', '3D', 110, false, ['prize_scope' => ['starter']]),
|
||||
$this->row('pos_3e', 'position', 3, 'single', '3E', 115, false, ['prize_scope' => ['consolation']]),
|
||||
$this->row('pos_3lower', 'position', 3, 'single', 'C', 117, false, ['prize_scope' => ['starter', 'consolation']]),
|
||||
|
||||
$this->row('pos_2a', 'position', 2, 'single', '2A', 120, false, ['prize_scope' => ['first']]),
|
||||
$this->row('pos_2b', 'position', 2, 'single', '2B', 130, false, ['prize_scope' => ['second']]),
|
||||
$this->row('pos_2c', 'position', 2, 'single', '2C', 140, false, ['prize_scope' => ['third']]),
|
||||
$this->row('pos_2abc', 'position', 2, 'single', '2ABC', 150, false, ['prize_scope' => ['first', 'second', 'third']]),
|
||||
$this->row('pos_2d', 'position', 2, 'single', '2D', 150, false, ['prize_scope' => ['starter']]),
|
||||
$this->row('pos_2e', 'position', 2, 'single', '2E', 155, false, ['prize_scope' => ['consolation']]),
|
||||
$this->row('pos_2any', 'position', 2, 'single', '2N', 157, false, ['prize_scope' => ['first', 'second', 'third', 'starter', 'consolation']]),
|
||||
|
||||
// 5D / 6D require their own published result source. Keep them in the catalog,
|
||||
// but disabled until that independent draw pipeline is enabled.
|
||||
$this->row('five_d', 'position', 5, 'single', '5D', 158, false, ['requires_independent_draw' => true], false),
|
||||
$this->row('six_d', 'position', 6, 'single', '6D', 159, false, ['requires_independent_draw' => true], false),
|
||||
|
||||
$this->row('straight', 'box', 4, 'single', 'Straight', 160, false, ['expand_mode' => 'straight']),
|
||||
$this->row('box', 'box', 4, 'single', 'Box', 170, false, ['expand_mode' => 'box']),
|
||||
|
||||
38
database/seeders/TraditionalMalaysiaOddsSeeder.php
Normal file
38
database/seeders/TraditionalMalaysiaOddsSeeder.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\OddsItem;
|
||||
use App\Models\OddsVersion;
|
||||
use App\Models\RiskCapItem;
|
||||
use App\Support\OddsStandardScopes;
|
||||
use App\Lottery\ConfigVersionStatus;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
/** Applies the traditional Malaysia baseline to active and draft odds versions. */
|
||||
final class TraditionalMalaysiaOddsSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$codes = [
|
||||
'big', 'small', 'pos_4a', 'pos_4b', 'pos_4c', 'pos_4d', 'pos_4e', 'four_any', 'four_top', 'four_lower',
|
||||
'pos_3a', 'pos_3b', 'pos_3c', 'pos_3d', 'pos_3e', 'pos_3lower',
|
||||
'pos_2a', 'pos_2b', 'pos_2c', 'pos_2d', 'pos_2e', 'pos_2any',
|
||||
];
|
||||
|
||||
foreach (OddsVersion::query()->whereIn('status', [ConfigVersionStatus::Active->value, ConfigVersionStatus::Draft->value])->cursor() as $version) {
|
||||
foreach ($codes as $code) {
|
||||
foreach (OddsStandardScopes::presetOddsForPlay($code) as $scope => $oddsValue) {
|
||||
OddsItem::query()
|
||||
->where('version_id', $version->id)
|
||||
->where('play_code', $code)
|
||||
->where('prize_scope', $scope)
|
||||
->update(['odds_value' => $oddsValue]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Existing default cap was calibrated for the prior 25x test multiplier.
|
||||
RiskCapItem::query()->where('cap_type', 'default')->update(['cap_amount' => 5_000_000_000_000]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user