From e21f049643a54e0bb62ce07452c28f4733940fc1 Mon Sep 17 00:00:00 2001 From: lkddi Date: Sun, 1 Mar 2026 22:55:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E5=8B=A4=E5=8A=A1?= =?UTF-8?q?=E6=97=A5=E6=A6=9C=E5=9C=A8=E7=BA=BF=E6=97=B6=E9=95=BF=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1=E8=99=9A=E9=AB=98=EF=BC=88142=E5=B0=8F=E6=97=B6?= =?UTF-8?q?=EF=BC=89+=20UI=E6=96=87=E5=AD=97=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug修复: - closeDutyLog 增加 whereDate 限制,只关闭今日日志,历史遗留记录置0,避免跨天时长被计入榜单 - tickDutyLog(ChatController/AutoSaveExp)找不到今日开放日志时不再盲目新建,避免同一 login_at 产生几十条重复记录后 SUM 叠加导致虚假142小时 - AppointmentService 撤职时 closeDutyLog 同步增加今日/历史遗留区分处理 UI调整: - 登录页版权文字「飘落的流星」→「流星」 - 后台布局标题「飘落流星 控制台」→「控制台」 - 后台侧边栏移除非超管查看各模块时的「(只读)」标注 --- app/Console/Commands/AutoSaveExp.php | 14 ++++----- app/Http/Controllers/ChatController.php | 32 ++++++++++++++------- app/Services/AppointmentService.php | 14 +++++++-- resources/views/admin/layouts/app.blade.php | 25 ++++++++-------- resources/views/admin/users/index.blade.php | 2 +- resources/views/index.blade.php | 2 +- 6 files changed, 55 insertions(+), 34 deletions(-) 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 @@