middleware('auth:api'); $this->middleware('permission:platform.logs.view,api')->only(['index']); $this->middleware('permission:platform.logs.manage,api')->only(['store']); } #[Apidoc\Title('日志查询'), Apidoc\Method('GET'), Apidoc\Url('/logs')] public function index(LogQueryRequest $request): JsonResponse { $sortBy = $request->string('sort_by')->toString() ?: 'requested_at'; $sortOrder = $request->string('sort_order')->toString() ?: 'desc'; $query = AccessLog::query()->with(['user', 'serverResource', 'bastionAccount']); if ($request->filled('from')) { $query->where('requested_at', '>=', $request->date('from')); } if ($request->filled('to')) { $query->where('requested_at', '<=', $request->date('to')); } if ($request->filled('action')) { $query->where('action', 'like', '%'.$request->string('action')->toString().'%'); } if ($request->filled('actions')) { $query->whereIn('action', $request->array('actions')); } if ($request->filled('user_id')) { $query->where('user_id', $request->integer('user_id')); } if ($request->filled('user_ids')) { $query->whereIn('user_id', $request->array('user_ids')); } if ($request->filled('server_resource_id')) { $query->where('server_resource_id', $request->integer('server_resource_id')); } if ($request->filled('server_resource_ids')) { $query->whereIn('server_resource_id', $request->array('server_resource_ids')); } if ($request->filled('protocol')) { $query->where('protocol', $request->string('protocol')->toString()); } if ($sortBy === 'user') { $query->leftJoin('users', 'users.id', '=', 'access_logs.user_id') ->select('access_logs.*') ->orderBy('users.nickname', $sortOrder); } elseif ($sortBy === 'resource') { $query->leftJoin('server_resources', 'server_resources.id', '=', 'access_logs.server_resource_id') ->select('access_logs.*') ->orderBy('server_resources.name', $sortOrder); } elseif ($sortBy === 'account') { $query->leftJoin('bastion_accounts', 'bastion_accounts.id', '=', 'access_logs.bastion_account_id') ->select('access_logs.*') ->orderBy('bastion_accounts.name', $sortOrder); } else { $column = in_array($sortBy, ['id', 'requested_at', 'action', 'protocol'], true) ? $sortBy : 'requested_at'; $query->orderBy('access_logs.'.$column, $sortOrder); } $logs = $query->paginate($request->integer('per_page', 20)); $userIds = AccessLog::query() ->whereNotNull('user_id') ->distinct() ->pluck('user_id') ->map(fn (int $id): int => (int) $id) ->all(); $serverResourceIds = AccessLog::query() ->whereNotNull('server_resource_id') ->distinct() ->pluck('server_resource_id') ->map(fn (int $id): int => (int) $id) ->all(); return response()->json([ 'code' => 0, 'message' => 'ok', 'data' => $logs, 'filter_options' => [ 'actions' => AccessLog::query() ->whereNotNull('action') ->where('action', '!=', '') ->distinct() ->orderBy('action') ->pluck('action') ->values(), 'users' => User::query() ->select(['id', 'nickname', 'email']) ->whereIn('id', $userIds) ->orderBy('id') ->get(), 'server_resources' => ServerResource::query() ->select(['id', 'name', 'internal_ip']) ->whereIn('id', $serverResourceIds) ->orderBy('id') ->get(), 'protocols' => AccessLog::query() ->whereNotNull('protocol') ->where('protocol', '!=', '') ->distinct() ->orderBy('protocol') ->pluck('protocol') ->values(), ], ]); } #[Apidoc\Title('新增日志'), Apidoc\Method('POST'), Apidoc\Url('/logs')] public function store(StoreAccessLogRequest $request): JsonResponse { $log = AccessLog::query()->create($request->validated()); return response()->json(['code' => 0, 'message' => 'ok', 'data' => $log], 201); } }