diff --git a/resources/views/admin/game-configs/index.blade.php b/resources/views/admin/game-configs/index.blade.php index 6b51513..b49d1a3 100644 --- a/resources/views/admin/game-configs/index.blade.php +++ b/resources/views/admin/game-configs/index.blade.php @@ -408,6 +408,11 @@ 'pve_fee_level_4' => ['label' => 'AI专家 入场费', 'type' => 'number', 'unit' => '金币', 'min' => 0], 'pve_reward_level_4' => ['label' => 'AI专家 胜利奖励', 'type' => 'number', 'unit' => '金币', 'min' => 0], ], + 'idiom' => [ + 'reward_gold' => ['label' => '答对奖励金币', 'type' => 'number', 'unit' => '枚', 'min' => 0], + 'reward_exp' => ['label' => '答对奖励经验', 'type' => 'number', 'unit' => '点', 'min' => 0], + 'auto_start_interval' => ['label' => '自动出题间隔', 'type' => 'number', 'unit' => '分钟(0=仅手动)', 'min' => 0], + ], default => [], }; } diff --git a/routes/console.php b/routes/console.php index 44bf77d..b395ec0 100644 --- a/routes/console.php +++ b/routes/console.php @@ -176,6 +176,87 @@ Schedule::call(function () { } })->everyMinute()->name('lottery:check')->withoutOverlapping(); +// ──────────── 猜成语自动出题 ──────────────────────────────────── +// +// 每分钟:检查是否到时间自动出题(仅 auto_start_interval > 0 时生效) +Schedule::call(function () { + if (! \App\Models\GameConfig::isEnabled('idiom')) { + return; + } + + $config = \App\Models\GameConfig::forGame('idiom')?->params ?? []; + $interval = (int) ($config['auto_start_interval'] ?? 0); + if ($interval <= 0) { + return; // 仅手动模式 + } + + // 检查每个房间是否有进行中的回合(先只处理 1 号房间) + $roomId = 1; + $activeRound = \App\Models\IdiomGameRound::where('room_id', $roomId) + ->whereIn('status', ['pending', 'active']) + ->first(); + if ($activeRound) { + return; // 当前有未答完的题,跳过 + } + + // 检查距上一题结束/创建时间是否已达到间隔 + $lastRound = \App\Models\IdiomGameRound::where('room_id', $roomId) + ->latest() + ->first(); + if ($lastRound) { + $lastTime = $lastRound->ended_at ?? $lastRound->started_at ?? $lastRound->created_at; + if ($lastTime && $lastTime->diffInMinutes(now()) < $interval) { + return; // 还没到时间 + } + } + + // 随机选一道启用的题目 + $idiom = \App\Models\Idiom::where('is_active', true)->inRandomOrder()->first(); + if (! $idiom) { + return; // 题库为空 + } + + $rewardGold = (int) ($config['reward_gold'] ?? 50); + $rewardExp = (int) ($config['reward_exp'] ?? 30); + + // 创建新回合 + $round = \App\Models\IdiomGameRound::create([ + 'room_id' => $roomId, + 'idiom_id' => $idiom->id, + 'status' => 'active', + 'reward_gold' => $rewardGold, + 'reward_exp' => $rewardExp, + 'started_at' => now(), + ]); + + // 广播到聊天室 + broadcast(new \App\Events\IdiomGameStarted( + roomId: $roomId, + hint: $idiom->hint, + roundId: $round->id, + rewardGold: $rewardGold, + rewardExp: $rewardExp, + )); + + // 同时推一条 MessageSent 消息显示在聊天窗口 + $msg = [ + 'id' => app(\App\Services\ChatStateService::class)->nextMessageId($roomId), + 'room_id' => $roomId, + 'from_user' => '星海小博士', + 'to_user' => '大家', + 'content' => "🧩 猜成语时间!{$idiom->hint}", + 'is_secret' => false, + 'font_color' => '#7c3aed', + 'action' => '', + 'idiom_game_round_id' => $round->id, + 'idiom_reward_gold' => $rewardGold, + 'idiom_reward_exp' => $rewardExp, + 'sent_at' => now()->toDateTimeString(), + ]; + app(\App\Services\ChatStateService::class)->pushMessage($roomId, $msg); + broadcast(new \App\Events\MessageSent($roomId, $msg)); +})->everyMinute()->name('idiom:auto-start')->withoutOverlapping(); + // 每日 18:00:超级期预热广播(若当前期次为超级期,提醒用户购票) Schedule::call(function () { if (! \App\Models\GameConfig::isEnabled('lottery')) {