diff --git a/.env.example b/.env.example index 77fc5a3..649f6c0 100644 --- a/.env.example +++ b/.env.example @@ -76,6 +76,11 @@ LOTTERY_DEFAULT_CURRENCY=NPR # 本地开发:Bearer dev:{数据库 players.id}(仅 APP_ENV=local 且为 true 时生效) LOTTERY_PLAYER_AUTH_DEV_BYPASS=false +# db:seed — 管理员种子为 admin@admin.com / 123456(非 production);勿用于生产库 +# db:seed — 演示玩家钱包余额(最小货币单位整数) +# DEV_SEED_WALLET_BALANCE_MINOR=125000 +# DEV_SEED_WALLET_FROZEN_MINOR=0 + # JWT 内站点/玩家字段名(与主站签发约定一致) # LOTTERY_JWT_ALGORITHM=HS256 # LOTTERY_JWT_CLAIM_SITE_CODE=site_code diff --git a/database/seeders/AdminRbacAndUserSeeder.php b/database/seeders/AdminRbacAndUserSeeder.php new file mode 100644 index 0000000..42a8ba9 --- /dev/null +++ b/database/seeders/AdminRbacAndUserSeeder.php @@ -0,0 +1,71 @@ +updateOrInsert( + ['slug' => 'super_admin'], + [ + 'name' => 'Super Admin', + 'created_at' => $now, + 'updated_at' => $now, + ], + ); + /** @var int $rid */ + $rid = (int) DB::table('admin_roles')->where('slug', 'super_admin')->value('id'); + + $perms = [ + ['slug' => 'admin.dashboard', 'name' => 'Dashboard'], + ['slug' => 'admin.players.read', 'name' => 'View players'], + ['slug' => 'admin.wallet.read', 'name' => 'View wallets'], + ]; + foreach ($perms as $p) { + DB::table('admin_permissions')->updateOrInsert( + ['slug' => $p['slug']], + [ + 'name' => $p['name'], + 'created_at' => $now, + 'updated_at' => $now, + ], + ); + } + + $pidRows = DB::table('admin_permissions')->whereIn('slug', array_column($perms, 'slug'))->pluck('id'); + foreach ($pidRows as $pid) { + DB::table('admin_role_permissions')->updateOrInsert( + ['role_id' => $rid, 'permission_id' => $pid], + [], + ); + } + + $email = 'admin@admin.com'; + AdminUser::query()->updateOrCreate( + ['email' => $email], + [ + 'name' => 'admin', + /** 明文;模型 casts `password => hashed`,勿在生产库使用种子弱口令 */ + 'password' => '123456', + 'status' => 0, + ], + ); + + /** @var int $uid */ + $uid = (int) AdminUser::query()->where('email', $email)->value('id'); + DB::table('admin_user_roles')->updateOrInsert( + ['admin_user_id' => $uid, 'role_id' => $rid], + [], + ); + } +} diff --git a/database/seeders/CurrencySeeder.php b/database/seeders/CurrencySeeder.php new file mode 100644 index 0000000..594897a --- /dev/null +++ b/database/seeders/CurrencySeeder.php @@ -0,0 +1,46 @@ + 'NPR', + 'name' => 'Nepalese Rupee', + 'decimal_places' => 2, + 'is_enabled' => true, + 'is_bettable' => true, + ], + [ + 'code' => 'USD', + 'name' => 'US Dollar', + 'decimal_places' => 2, + 'is_enabled' => true, + 'is_bettable' => false, + ], + ]; + + foreach ($rows as $row) { + DB::table('currencies')->updateOrInsert( + ['code' => $row['code']], + [ + 'name' => $row['name'], + 'decimal_places' => $row['decimal_places'], + 'is_enabled' => $row['is_enabled'], + 'is_bettable' => $row['is_bettable'], + 'created_at' => now(), + 'updated_at' => now(), + ], + ); + } + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index be72158..f195525 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -11,6 +11,18 @@ class DatabaseSeeder extends Seeder public function run(): void { - // 后台账号:后续可加 AdminUserSeeder;玩家:players 由 SSO 映射写入 + // 全环境可用的基础枚举数据 + $this->call([ + CurrencySeeder::class, + PlayTypeSeeder::class, + ]); + + // 演示管理员 + 演示玩家:**勿在生产库执行**(或确保 APP_ENV≠production) + if (! app()->environment('production')) { + $this->call([ + AdminRbacAndUserSeeder::class, + DevPlayerAndWalletSeeder::class, + ]); + } } } diff --git a/database/seeders/DevPlayerAndWalletSeeder.php b/database/seeders/DevPlayerAndWalletSeeder.php new file mode 100644 index 0000000..59fb316 --- /dev/null +++ b/database/seeders/DevPlayerAndWalletSeeder.php @@ -0,0 +1,49 @@ +updateOrCreate( + [ + 'site_code' => 'demo', + 'site_player_id' => 'demo-player-001', + ], + [ + 'username' => 'demo_player', + 'nickname' => 'Demo Player', + 'default_currency' => $currency, + 'status' => 0, + ], + ); + + PlayerWallet::query()->updateOrCreate( + [ + 'player_id' => $player->id, + 'wallet_type' => 'lottery', + 'currency_code' => $currency, + ], + [ + /** 最小货币单位整数:示例 125000,仅演示;可由 .env 覆盖 */ + 'balance' => (int) env('DEV_SEED_WALLET_BALANCE_MINOR', 125_000), + 'frozen_balance' => (int) env('DEV_SEED_WALLET_FROZEN_MINOR', 0), + 'status' => 0, + 'version' => 0, + ], + ); + } +} diff --git a/database/seeders/PlayTypeSeeder.php b/database/seeders/PlayTypeSeeder.php new file mode 100644 index 0000000..b35f71f --- /dev/null +++ b/database/seeders/PlayTypeSeeder.php @@ -0,0 +1,79 @@ + now(), 'updated_at' => now()]; + + $rows = [ + [ + 'play_code' => 'big', + 'category' => 'standard', + 'dimension' => 2, + 'bet_mode' => null, + 'display_name_zh' => 'Big', + 'display_name_en' => 'Big', + 'display_name_ne' => 'Big', + 'is_enabled' => true, + 'sort_order' => 10, + 'supports_multi_number' => false, + 'reserved_rule_json' => null, + ], + [ + 'play_code' => 'small', + 'category' => 'standard', + 'dimension' => 2, + 'bet_mode' => null, + 'display_name_zh' => 'Small', + 'display_name_en' => 'Small', + 'display_name_ne' => 'Small', + 'is_enabled' => true, + 'sort_order' => 20, + 'supports_multi_number' => false, + 'reserved_rule_json' => null, + ], + [ + 'play_code' => 'head', + 'category' => 'digit', + 'dimension' => 2, + 'bet_mode' => null, + 'display_name_zh' => 'Head', + 'display_name_en' => 'Head', + 'display_name_ne' => 'Head', + 'is_enabled' => true, + 'sort_order' => 30, + 'supports_multi_number' => false, + 'reserved_rule_json' => null, + ], + [ + 'play_code' => 'tail', + 'category' => 'digit', + 'dimension' => 2, + 'bet_mode' => null, + 'display_name_zh' => 'Tail', + 'display_name_en' => 'Tail', + 'display_name_ne' => 'Tail', + 'is_enabled' => true, + 'sort_order' => 40, + 'supports_multi_number' => false, + 'reserved_rule_json' => null, + ], + ]; + + foreach ($rows as $row) { + DB::table('play_types')->updateOrInsert( + ['play_code' => $row['play_code']], + array_merge($row, $defaults), + ); + } + } +}