feat(idiom): add scheduled auto-start task (everyMinute)

This commit is contained in:
pllx
2026-04-28 23:48:32 +08:00
parent 4ff62e29bd
commit b886d98d8c
2 changed files with 86 additions and 0 deletions
@@ -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 => [],
};
}
+81
View File
@@ -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')) {