feat(idiom): add scheduled auto-start task (everyMinute)
This commit is contained in:
@@ -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 => [],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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')) {
|
||||
|
||||
Reference in New Issue
Block a user