From aab609f69b2f1695ef63a8973658a3570e0b7ee9 Mon Sep 17 00:00:00 2001 From: lkddi Date: Sat, 25 Apr 2026 00:27:08 +0800 Subject: [PATCH] =?UTF-8?q?ai=E5=B0=8F=E7=8F=AD=E9=95=BF=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=AD=BE=E5=88=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Commands/AiHeartbeatCommand.php | 54 +++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/app/Console/Commands/AiHeartbeatCommand.php b/app/Console/Commands/AiHeartbeatCommand.php index d57a274..e675b7e 100644 --- a/app/Console/Commands/AiHeartbeatCommand.php +++ b/app/Console/Commands/AiHeartbeatCommand.php @@ -18,10 +18,12 @@ use App\Enums\CurrencySource; use App\Events\MessageSent; use App\Jobs\SaveMessageJob; use App\Models\Autoact; +use App\Models\DailySignIn; use App\Models\Sysparam; use App\Models\User; use App\Services\AiFinanceService; use App\Services\ChatStateService; +use App\Services\SignInService; use App\Services\UserCurrencyService; use App\Services\VipService; use Illuminate\Console\Command; @@ -49,6 +51,7 @@ class AiHeartbeatCommand extends Command private readonly VipService $vipService, private readonly UserCurrencyService $currencyService, private readonly AiFinanceService $aiFinance, + private readonly SignInService $signInService, ) { parent::__construct(); } @@ -72,6 +75,9 @@ class AiHeartbeatCommand extends Command // 心跳开始前,若手上金币已高于 100 万,则先把超出的部分转入银行。 $this->aiFinance->bankExcessGold($user); + // 2.5 自动每日签到(今日已签时 claim() 幂等返回,不重复发奖) + $this->performDailySignIn($user); + // 3. 常规心跳经验与金币发放 // (模拟前端每30-60秒发一次心跳的过程,此处每分钟跑一次,发放单人心跳奖励) $expGain = $this->parseRewardValue(Sysparam::getValue('exp_per_heartbeat', '1')); @@ -213,6 +219,54 @@ class AiHeartbeatCommand extends Command return (int) $raw; } + /** + * 尝试为 AI小班长 执行今日签到,成功时广播签到通知。 + */ + private function performDailySignIn(User $user): void + { + // 先检查今日是否已签,避免每分钟都调用事务 + $alreadySigned = DailySignIn::query() + ->where('user_id', $user->id) + ->whereDate('sign_in_date', today()) + ->exists(); + + if ($alreadySigned) { + return; + } + + // 获取活跃房间作为签到归属(默认房间 1) + $activeRoomIds = $this->chatState->getAllActiveRoomIds(); + $roomId = ! empty($activeRoomIds) ? (int) $activeRoomIds[0] : 1; + + $dailySignIn = $this->signInService->claim($user, $roomId); + + // 仅当本次心跳实际完成签到时才广播(幂等保护) + if (! $dailySignIn->wasRecentlyCreated) { + return; + } + + $rewardParts = []; + if ($dailySignIn->gold_reward > 0) { + $rewardParts[] = $dailySignIn->gold_reward.' 金币'; + } + if ($dailySignIn->exp_reward > 0) { + $rewardParts[] = $dailySignIn->exp_reward.' 经验'; + } + if ($dailySignIn->charm_reward > 0) { + $rewardParts[] = $dailySignIn->charm_reward.' 魅力'; + } + $rewardText = $rewardParts === [] ? '签到记录' : implode(' + ', $rewardParts); + + $identityText = $dailySignIn->identity_badge_name + ? ',获得身份 '.e($dailySignIn->identity_badge_name) + : ''; + + $content = '【'.e($user->username).'】完成今日签到,连续签到 ' + .$dailySignIn->streak_days.' 天,获得 '.$rewardText.$identityText.'。'; + + $this->broadcastSystemMessage('签到播报', $content, '#0f766e'); + } + /** * 往所有活跃房间发送系统广播消息 */