diff --git a/app/Console/Commands/AutoSaveExp.php b/app/Console/Commands/AutoSaveExp.php index c2fd03d..1af9475 100644 --- a/app/Console/Commands/AutoSaveExp.php +++ b/app/Console/Commands/AutoSaveExp.php @@ -283,6 +283,7 @@ class AutoSaveExp extends Command return; } + // ① 今日未关闭的开放日志 → 刷新时长 $openLog = PositionDutyLog::query() ->where('user_id', $user->id) ->whereNull('logout_at') @@ -290,7 +291,6 @@ class AutoSaveExp extends Command ->first(); if ($openLog) { - // 绕过模型 cast(integer),使用 DB::table 直接执行 SQL 表达式 DB::table('position_duty_logs') ->where('id', $openLog->id) ->update(['duration_seconds' => DB::raw('GREATEST(0, TIMESTAMPDIFF(SECOND, login_at, NOW()))')]); @@ -298,17 +298,17 @@ class AutoSaveExp extends Command return; } - // 今日无日志,新建:取进房时间为 login_at(防止时长丢失) - $loginAt = $user->in_time && $user->in_time->isToday() + // ② 今日无开放日志 → 新建(login_at 优先用今日进房时间,跨天则用 now()) + $loginAt = ($user->in_time && $user->in_time->isToday()) ? $user->in_time : now(); PositionDutyLog::create([ - 'user_id' => $user->id, + 'user_id' => $user->id, 'user_position_id' => $activeUP->id, - 'login_at' => $loginAt, - 'ip_address' => '0.0.0.0', // 定时任务无 HTTP 请求,占位符 - 'room_id' => $roomId, + 'login_at' => $loginAt, + 'ip_address' => '0.0.0.0', + 'room_id' => $roomId, ]); } } diff --git a/app/Http/Controllers/ChatController.php b/app/Http/Controllers/ChatController.php index 173d232..62e3cb3 100644 --- a/app/Http/Controllers/ChatController.php +++ b/app/Http/Controllers/ChatController.php @@ -919,13 +919,25 @@ class ChatController extends Controller */ private function closeDutyLog(int $userId): void { + // 将今日开放日志关闭并结算实际时长 PositionDutyLog::query() ->where('user_id', $userId) ->whereNull('logout_at') + ->whereDate('login_at', today()) ->update([ - 'logout_at' => now(), + 'logout_at' => now(), 'duration_seconds' => DB::raw('GREATEST(0, TIMESTAMPDIFF(SECOND, login_at, NOW()))'), ]); + + // 清理历史遭留未关闭的日志(login_at 非今日),直接将它们的时长置 0,避免被算入任何榜单 + PositionDutyLog::query() + ->where('user_id', $userId) + ->whereNull('logout_at') + ->whereDate('login_at', '<', today()) + ->update([ + 'logout_at' => DB::raw('login_at'), // 时长 = 0 + 'duration_seconds' => 0, + ]); } /** @@ -947,7 +959,7 @@ class ChatController extends Controller return; } - // 今日是否已有开放日志 + // ① 优先找今日未关闭的开放日志,直接刷新时长 $openLog = PositionDutyLog::query() ->where('user_id', $user->id) ->whereNull('logout_at') @@ -955,8 +967,6 @@ class ChatController extends Controller ->first(); if ($openLog) { - // 刷新实时在线时长 - // 绕过模型 cast(integer),使用 DB::table 直接执行 SQL 表达式 DB::table('position_duty_logs') ->where('id', $openLog->id) ->update(['duration_seconds' => DB::raw('GREATEST(0, TIMESTAMPDIFF(SECOND, login_at, NOW()))')]); @@ -964,17 +974,19 @@ class ChatController extends Controller return; } - // 今日无日志 → 新建,login_at 优先用进房时间 - $loginAt = $user->in_time && $user->in_time->isToday() + // ② 今日是否已有任意日志(含已关闭的)? + // 若有:说明用户本次是重新进房,已经有历史记录,直接新建本次进房的日志段 + // 若无:说明今天第一次进房,新建,login_at 优先用 in_time + $loginAt = ($user->in_time && $user->in_time->isToday()) ? $user->in_time : now(); PositionDutyLog::create([ - 'user_id' => $user->id, + 'user_id' => $user->id, 'user_position_id' => $activeUP->id, - 'login_at' => $loginAt, - 'ip_address' => request()->ip(), - 'room_id' => $roomId, + 'login_at' => $loginAt, + 'ip_address' => request()->ip(), + 'room_id' => $roomId, ]); } } diff --git a/app/Services/AppointmentService.php b/app/Services/AppointmentService.php index cb1f82c..36f6a56 100644 --- a/app/Services/AppointmentService.php +++ b/app/Services/AppointmentService.php @@ -208,14 +208,24 @@ class AppointmentService 'revoked_by_user_id' => $operator->id, ]); - // 关闭尚未结束的 duty_log + // 关闭尚未结束的 duty_log(只结算今日,历史遗留置0) $target->activePosition?->dutyLogs() ->whereNull('logout_at') + ->whereDate('login_at', today()) ->update([ - 'logout_at' => now(), + 'logout_at' => now(), 'duration_seconds' => DB::raw('TIMESTAMPDIFF(SECOND, login_at, NOW())'), ]); + // 历史遗留未关闭日志直接清零 + $target->activePosition?->dutyLogs() + ->whereNull('logout_at') + ->whereDate('login_at', '<', today()) + ->update([ + 'logout_at' => DB::raw('login_at'), + 'duration_seconds' => 0, + ]); + // user_level 归 1(由系统经验值自然升级机制重新成长) $target->update(['user_level' => 1]); diff --git a/resources/views/admin/layouts/app.blade.php b/resources/views/admin/layouts/app.blade.php index 44a827c..17cdbf5 100644 --- a/resources/views/admin/layouts/app.blade.php +++ b/resources/views/admin/layouts/app.blade.php @@ -5,7 +5,7 @@ - 后台管理 - 飘落流星 + 后台管理 - 流星 @vite(['resources/css/app.css', 'resources/js/app.js']) @@ -15,7 +15,7 @@