diff --git a/app/Http/Controllers/Admin/GameConfigController.php b/app/Http/Controllers/Admin/GameConfigController.php new file mode 100644 index 0000000..0f35ed5 --- /dev/null +++ b/app/Http/Controllers/Admin/GameConfigController.php @@ -0,0 +1,72 @@ +get(); + + return view('admin.game-configs.index', compact('games')); + } + + /** + * 切换游戏开启/关闭状态。 + */ + public function toggle(GameConfig $gameConfig): JsonResponse + { + $gameConfig->update(['enabled' => ! $gameConfig->enabled]); + $gameConfig->clearCache(); + + return response()->json([ + 'ok' => true, + 'enabled' => $gameConfig->enabled, + 'message' => $gameConfig->enabled + ? "「{$gameConfig->name}」已开启" + : "「{$gameConfig->name}」已关闭", + ]); + } + + /** + * 保存游戏核心参数。 + * + * 接收前端提交的 params JSON 对象并合并至现有配置。 + */ + public function updateParams(Request $request, GameConfig $gameConfig): RedirectResponse + { + $request->validate([ + 'params' => 'required|array', + ]); + + // 合并参数,保留已有键,只更新传入的键 + $current = $gameConfig->params ?? []; + $updated = array_merge($current, $request->input('params')); + + $gameConfig->update(['params' => $updated]); + $gameConfig->clearCache(); + + return back()->with('success', "「{$gameConfig->name}」参数已保存!"); + } +} diff --git a/app/Models/GameConfig.php b/app/Models/GameConfig.php new file mode 100644 index 0000000..c8ec343 --- /dev/null +++ b/app/Models/GameConfig.php @@ -0,0 +1,80 @@ + 'boolean', + 'params' => 'array', + ]; + } + + // ─── 静态工具方法 ───────────────────────────────────────────────── + + /** + * 根据游戏标识获取配置(带缓存)。 + * + * @param string $key 游戏标识,如 'baccarat' + */ + public static function forGame(string $key): ?static + { + return Cache::remember("game_config:{$key}", 60, fn () => static::where('game_key', $key)->first()); + } + + /** + * 判断游戏是否已开启。 + */ + public static function isEnabled(string $key): bool + { + return (bool) static::forGame($key)?->enabled; + } + + /** + * 获取指定游戏的某个参数值,不存在时返回默认值。 + * + * @param string $key 游戏标识 + * @param string $param 参数名 + * @param mixed $default 默认值 + */ + public static function param(string $key, string $param, mixed $default = null): mixed + { + return static::forGame($key)?->params[$param] ?? $default; + } + + /** + * 清除游戏配置缓存。 + */ + public function clearCache(): void + { + Cache::forget("game_config:{$this->game_key}"); + } +} diff --git a/database/migrations/2026_03_01_201417_create_game_configs_table.php b/database/migrations/2026_03_01_201417_create_game_configs_table.php new file mode 100644 index 0000000..9d84420 --- /dev/null +++ b/database/migrations/2026_03_01_201417_create_game_configs_table.php @@ -0,0 +1,40 @@ +id(); + $table->string('game_key', 50)->unique()->comment('游戏唯一标识(如 baccarat、slot_machine)'); + $table->string('name', 100)->comment('游戏中文名'); + $table->string('icon', 10)->default('🎮')->comment('游戏图标 Emoji'); + $table->text('description')->nullable()->comment('游戏简介'); + $table->boolean('enabled')->default(false)->comment('是否开启'); + $table->json('params')->nullable()->comment('游戏核心参数(JSON)'); + $table->timestamps(); + }); + } + + /** + * 回滚迁移。 + */ + public function down(): void + { + Schema::dropIfExists('game_configs'); + } +}; diff --git a/database/seeders/GameConfigSeeder.php b/database/seeders/GameConfigSeeder.php new file mode 100644 index 0000000..4fc852e --- /dev/null +++ b/database/seeders/GameConfigSeeder.php @@ -0,0 +1,128 @@ + 'baccarat', + 'name' => '百家乐', + 'icon' => '🎲', + 'description' => '系统每隔一段时间自动开一局,玩家在倒计时内押注大/小/豹子,骰子结果决定胜负。', + 'enabled' => false, + 'params' => [ + 'interval_minutes' => 2, // 多少分钟开一局 + 'bet_window_seconds' => 60, // 每局押注窗口(秒) + 'min_bet' => 100, // 最低押注金币 + 'max_bet' => 50000, // 最高押注金币 + 'payout_big' => 1, // 大:1:1 赔率 + 'payout_small' => 1, // 小:1:1 赔率 + 'payout_triple' => 24, // 豹子:1:24 赔率 + 'kill_points' => [3, 18], // 庄家收割点数(全灭) + ], + ], + + // ─── 老虎机 ────────────────────────────────────────────── + [ + 'game_key' => 'slot_machine', + 'name' => '老虎机', + 'icon' => '🎰', + 'description' => '消耗金币转动老虎机,三列图案匹配可获得不同倍率奖励,三个7大奖全服广播。', + 'enabled' => false, + 'params' => [ + 'cost_per_spin' => 100, // 每次旋转消耗 + 'house_edge_percent' => 15, // 庄家边际(%) + 'daily_limit' => 100, // 每日最多转动次数(0=不限) + 'jackpot_payout' => 100, // 三个7 赔率 + 'triple_payout' => 50, // 三个💎 赔率 + 'same_payout' => 10, // 其他三同 赔率 + 'pair_payout' => 2, // 两同 赔率 + 'curse_enabled' => true, // 是否开启诅咒(三💀扣双倍) + ], + ], + + // ─── 神秘箱子 ──────────────────────────────────────────── + [ + 'game_key' => 'mystery_box', + 'name' => '神秘箱子', + 'icon' => '📦', + 'description' => '管理员随时投放或系统定时自动投放神秘箱,最快发送暗号的用户开箱获得奖励。', + 'enabled' => false, + 'params' => [ + 'auto_drop_enabled' => false, // 是否自动定时投放 + 'auto_interval_hours' => 2, // 自动投放间隔(小时) + 'claim_window_seconds' => 60, // 领取窗口(秒) + 'min_reward' => 500, // 普通箱最低奖励 + 'max_reward' => 2000, // 普通箱最高奖励 + 'rare_min_reward' => 5000, // 稀有箱最低奖励 + 'rare_max_reward' => 20000, // 稀有箱最高奖励 + 'trap_chance_percent' => 10, // 黑化箱触发概率(%) + ], + ], + + // ─── 赛马竞猜 ──────────────────────────────────────────── + [ + 'game_key' => 'horse_racing', + 'name' => '赛马竞猜', + 'icon' => '🐎', + 'description' => '系统定期举办赛马,用户在倒计时内下注,按注池赔率结算,跑马过程 WebSocket 实时播报。', + 'enabled' => false, + 'params' => [ + 'interval_minutes' => 30, // 多少分钟一场 + 'bet_window_seconds' => 90, // 押注窗口(秒) + 'race_duration' => 30, // 跑马动画时长(秒) + 'horse_count' => 4, // 参赛马匹数量 + 'min_bet' => 100, // 最低押注 + 'max_bet' => 100000, // 最高押注 + 'house_take_percent' => 5, // 庄家抽水(%) + ], + ], + + // ─── 神秘占卜 ──────────────────────────────────────────── + [ + 'game_key' => 'fortune_telling', + 'name' => '神秘占卜', + 'icon' => '🔮', + 'description' => '每日一次免费占卜,系统生成玄学签文并赋予当日加成效果(幸运/倒霉)。额外占卜消耗金币。', + 'enabled' => false, + 'params' => [ + 'free_count_per_day' => 1, // 每日免费次数 + 'extra_cost' => 500, // 额外次数消耗金币 + 'buff_duration_hours' => 24, // 加成效果持续时间 + 'jackpot_chance' => 5, // 上上签概率(%) + 'good_chance' => 20, // 上签概率(%) + 'bad_chance' => 20, // 下签概率(%) + 'curse_chance' => 5, // 大凶签概率(%) + ], + ], + ]; + + foreach ($games as $game) { + GameConfig::updateOrCreate( + ['game_key' => $game['game_key']], + $game, + ); + } + } +} diff --git a/resources/views/admin/game-configs/index.blade.php b/resources/views/admin/game-configs/index.blade.php new file mode 100644 index 0000000..5feae73 --- /dev/null +++ b/resources/views/admin/game-configs/index.blade.php @@ -0,0 +1,254 @@ +@extends('admin.layouts.app') + +@section('title', '游戏管理') + +@section('content') +
统一管理聊天室所有娱乐游戏的开关状态与核心参数,所有游戏默认关闭。
+php artisan db:seed
+ --class=GameConfigSeeder
+