diff --git a/app/Events/ScreenCleared.php b/app/Events/ScreenCleared.php new file mode 100644 index 0000000..d8451ae --- /dev/null +++ b/app/Events/ScreenCleared.php @@ -0,0 +1,59 @@ + + */ + public function broadcastOn(): array + { + return [ + new PresenceChannel('room.'.$this->roomId), + ]; + } + + /** + * 广播数据 + * + * @return array + */ + public function broadcastWith(): array + { + return [ + 'operator' => $this->operator, + ]; + } +} diff --git a/app/Http/Controllers/AdminCommandController.php b/app/Http/Controllers/AdminCommandController.php index ee0c4da..efbaf90 100644 --- a/app/Http/Controllers/AdminCommandController.php +++ b/app/Http/Controllers/AdminCommandController.php @@ -323,6 +323,39 @@ class AdminCommandController extends Controller return response()->json(['status' => 'success', 'message' => '公告已发送']); } + /** + * 管理员全员清屏 + * + * 清除 Redis 中该房间的聊天记录缓存,并广播清屏事件通知所有用户前端清除消息。 + * 前端只清除普通消息,保留悄悄话。 + * + * @param Request $request 请求对象,需包含 room_id + * @return JsonResponse 操作结果 + */ + public function clearScreen(Request $request): JsonResponse + { + $request->validate([ + 'room_id' => 'required|integer', + ]); + + $admin = Auth::user(); + $roomId = $request->input('room_id'); + $superLevel = (int) Sysparam::getValue('superlevel', '100'); + + // 需要站长权限才能全员清屏 + if ($admin->user_level < $superLevel) { + return response()->json(['status' => 'error', 'message' => '仅站长可执行全员清屏'], 403); + } + + // 清除 Redis 中该房间的消息缓存 + $this->chatState->clearMessages($roomId); + + // 广播清屏事件 + broadcast(new \App\Events\ScreenCleared($roomId, $admin->username)); + + return response()->json(['status' => 'success', 'message' => '已执行全员清屏']); + } + /** * 权限检查:管理员是否可对目标用户执行指定操作 * diff --git a/app/Services/ChatStateService.php b/app/Services/ChatStateService.php index d963bd2..edb08a1 100644 --- a/app/Services/ChatStateService.php +++ b/app/Services/ChatStateService.php @@ -104,6 +104,17 @@ class ChatStateService Redis::ltrim($key, -$maxKeep, -1); } + /** + * 清除指定房间的所有消息缓存(管理员全员清屏)。 + * + * @param int $roomId 房间ID + */ + public function clearMessages(int $roomId): void + { + $key = "room:{$roomId}:messages"; + Redis::del($key); + } + /** * 获取指定房间的新发言记录。 * 在高频长轮询或前端断线重连拉取时使用。 diff --git a/resources/js/chat.js b/resources/js/chat.js index 07da39c..a75170c 100644 --- a/resources/js/chat.js +++ b/resources/js/chat.js @@ -56,6 +56,13 @@ export function initChat(roomId) { window.dispatchEvent( new CustomEvent("chat:title-updated", { detail: e }), ); + }) + // 监听管理员全员清屏 + .listen("ScreenCleared", (e) => { + console.log("全员清屏:", e); + window.dispatchEvent( + new CustomEvent("chat:screen-cleared", { detail: e }), + ); }); } diff --git a/resources/views/chat/partials/input-bar.blade.php b/resources/views/chat/partials/input-bar.blade.php index 9d115f9..057b8a6 100644 --- a/resources/views/chat/partials/input-bar.blade.php +++ b/resources/views/chat/partials/input-bar.blade.php @@ -95,6 +95,9 @@ + @endif