$q->where('last_visited', '>=', time() - self::ONLINE_THRESHOLD_SECONDS); $users = User::whereHas('staffOnline', $onlineSince) ->with(['staffOnline' => $onlineSince]) ->get(); $online = $users->map(fn ($user) => [ 'user_id' => $user->id, 'name' => $user->name, 'username' => $user->username, 'email' => $user->email, 'last_visited' => $user->staffOnline?->last_visited, ])->values(); return response()->json([ 'error' => false, 'data' => $online, 'total' => $online->count(), ]); } /** * POST /api/v1/administrator/staff-online/ping * Heartbeat cho JWT admin — cập nhật trạng thái online. */ public function ping(Request $request): JsonResponse { $userId = $request->user()?->id; if (!$userId) { return response()->json(['error' => true, 'message' => 'Unauthenticated'], 401); } $record = $this->staffRepository->getFirstBy(['user_id' => $userId]); if ($record) { $record->last_visited = time(); $record->save(); } else { $this->staffRepository->create([ 'sessions_id' => 'jwt-' . $userId, 'user_id' => $userId, 'last_visited' => time(), ]); } $this->staffRepository->deleteRawTime(self::ONLINE_THRESHOLD_SECONDS); return response()->json(['error' => false, 'message' => 'OK']); } }