From 762caac938d8038dd9ab5ca445def8fdf191258b Mon Sep 17 00:00:00 2001 From: lkddi Date: Tue, 14 Apr 2026 21:09:37 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=AE=A1=E7=90=86=E9=A6=96?= =?UTF-8?q?=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Admin/DashboardController.php | 19 ++++++ resources/views/admin/dashboard.blade.php | 6 ++ .../Feature/AdminDashboardControllerTest.php | 65 +++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 tests/Feature/Feature/AdminDashboardControllerTest.php diff --git a/app/Http/Controllers/Admin/DashboardController.php b/app/Http/Controllers/Admin/DashboardController.php index 905e9cd..0306f45 100644 --- a/app/Http/Controllers/Admin/DashboardController.php +++ b/app/Http/Controllers/Admin/DashboardController.php @@ -13,18 +13,37 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use App\Models\Room; use App\Models\User; +use App\Services\ChatStateService; use Illuminate\View\View; +/** + * 类功能:负责后台首页仪表盘的汇总统计展示。 + */ class DashboardController extends Controller { + /** + * 注入聊天室状态服务,供仪表盘读取实时在线数据。 + */ + public function __construct( + private readonly ChatStateService $chatState, + ) {} + /** * 显示后台首页与全局统计 */ public function index(): View { + $onlineUsernames = collect(); + + foreach ($this->chatState->getAllActiveRoomIds() as $roomId) { + // 使用在线名单服务的懒清理结果,保证统计口径与聊天室在线列表一致。 + $onlineUsernames = $onlineUsernames->merge(array_keys($this->chatState->getRoomUsers($roomId))); + } + $stats = [ 'total_users' => User::count(), 'total_rooms' => Room::count(), + 'online_users' => $onlineUsernames->unique()->count(), // 更多统计指标以后再发掘 ]; diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index 0be6e0c..e516af0 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -13,6 +13,12 @@

总计聊天频道数

{{ $stats['total_rooms'] }}

+ +
+

当前在线人数

+

{{ $stats['online_users'] }}

+

按 Redis 在线心跳实时去重统计

+
diff --git a/tests/Feature/Feature/AdminDashboardControllerTest.php b/tests/Feature/Feature/AdminDashboardControllerTest.php new file mode 100644 index 0000000..c42b0dd --- /dev/null +++ b/tests/Feature/Feature/AdminDashboardControllerTest.php @@ -0,0 +1,65 @@ +create([ + 'id' => 1, + 'username' => 'site-owner', + ]); + + $roomOne = Room::create(['room_name' => '后台房间一']); + $roomTwo = Room::create(['room_name' => '后台房间二']); + + // 同一用户重复出现在多个房间时,仪表盘应按全局去重后的在线人数展示。 + Redis::hset("room:{$roomOne->id}:users", 'alice', json_encode(['username' => 'alice'], JSON_UNESCAPED_UNICODE)); + Redis::setex("room:{$roomOne->id}:alive:alice", 90, 1); + Redis::hset("room:{$roomTwo->id}:users", 'alice', json_encode(['username' => 'alice'], JSON_UNESCAPED_UNICODE)); + Redis::setex("room:{$roomTwo->id}:alive:alice", 90, 1); + Redis::hset("room:{$roomTwo->id}:users", 'bob', json_encode(['username' => 'bob'], JSON_UNESCAPED_UNICODE)); + Redis::setex("room:{$roomTwo->id}:alive:bob", 90, 1); + + $response = $this->actingAs($siteOwner)->get(route('admin.dashboard')); + + $response->assertOk(); + $response->assertSee('当前在线人数'); + $response->assertSee('2'); + } +}