middleware('auth:api'); $this->middleware('permission:platform.users.view,api')->only(['index', 'show']); $this->middleware('permission:platform.users.manage,api')->only(['store', 'update', 'destroy', 'syncPermissions']); } #[Apidoc\Title('用户列表'), Apidoc\Method('GET'), Apidoc\Url('/users')] public function index(Request $request): JsonResponse { $validated = $request->validate([ 'per_page' => ['nullable', 'integer', 'min:1', 'max:100'], 'sort_by' => ['nullable', 'string', 'in:id,nickname,email,phone,created_at'], 'sort_order' => ['nullable', 'string', 'in:asc,desc'], ]); $sortBy = $validated['sort_by'] ?? 'created_at'; $sortOrder = $validated['sort_order'] ?? 'desc'; $perPage = (int) ($validated['per_page'] ?? 20); $users = User::query() ->with('roles') ->orderBy($sortBy, $sortOrder) ->paginate($perPage); return response()->json(['code' => 0, 'message' => 'ok', 'data' => $users]); } #[Apidoc\Title('创建用户'), Apidoc\Method('POST'), Apidoc\Url('/users')] public function store(StoreUserRequest $request): JsonResponse { $user = User::query()->create($request->validated()); if ($request->filled('role_ids')) { $user->syncRoles($request->validated('role_ids')); } $this->auditLog($request, 'user_create', ['metadata' => ['target_user_id' => $user->id]]); return response()->json(['code' => 0, 'message' => 'ok', 'data' => $user->load('roles')], 201); } #[Apidoc\Title('用户详情'), Apidoc\Method('GET'), Apidoc\Url('/users/{id}')] public function show(int $id): JsonResponse { $user = User::query()->with(['roles', 'permissions', 'serverResources'])->findOrFail($id); return response()->json(['code' => 0, 'message' => 'ok', 'data' => $user]); } #[Apidoc\Title('更新用户'), Apidoc\Method('PUT'), Apidoc\Url('/users/{id}')] public function update(UpdateUserRequest $request, int $id): JsonResponse { $user = User::query()->findOrFail($id); $user->fill($request->safe()->except(['role_ids'])); if ($request->filled('password')) { $user->password = $request->validated('password'); } $user->save(); if ($request->has('role_ids')) { $user->syncRoles($request->validated('role_ids')); } $this->auditLog($request, 'user_update', ['metadata' => ['target_user_id' => $user->id]]); return response()->json(['code' => 0, 'message' => 'ok', 'data' => $user->load('roles')]); } #[Apidoc\Title('同步用户权限'), Apidoc\Method('PUT'), Apidoc\Url('/users/{id}/permissions')] public function syncPermissions(Request $request, int $id): JsonResponse { $validated = $request->validate([ 'permission_ids' => ['present', 'array'], 'permission_ids.*' => ['integer', 'exists:permissions,id'], ]); $user = User::query()->findOrFail($id); $user->syncPermissions($validated['permission_ids']); $this->syncServerResourcePermissionsByDirectPermissions($user, $validated['permission_ids']); $this->auditLog($request, 'user_permissions_update', ['metadata' => ['target_user_id' => $user->id, 'permission_ids' => $validated['permission_ids']]]); return response()->json(['code' => 0, 'message' => 'ok', 'data' => $user->load(['roles', 'permissions'])]); } #[Apidoc\Title('删除用户'), Apidoc\Method('DELETE'), Apidoc\Url('/users/{id}')] public function destroy(Request $request, int $id): JsonResponse { $user = User::query()->findOrFail($id); $this->auditLog($request, 'user_delete', ['metadata' => ['target_user_id' => $user->id]]); $user->delete(); return response()->json(['code' => 0, 'message' => 'ok', 'data' => null]); } private function syncServerResourcePermissionsByDirectPermissions(User $user, array $permissionIds): void { $resourcePermissions = Permission::query() ->select(['id', 'name', 'description']) ->whereIn('id', $permissionIds) ->where('guard_name', 'api') ->where('name', 'like', 'resource.servers.use.%') ->get(); $grantedResourceIds = $resourcePermissions ->map(fn (Permission $permission): ?int => $this->resourceIdFromPermissionDescription((string) $permission->description)) ->filter(fn (?int $resourceId): bool => $resourceId !== null) ->map(fn (int $resourceId): int => (int) $resourceId) ->values() ->all(); if (count($grantedResourceIds) > 0) { $existingResourceIds = ServerResource::query() ->whereIn('id', $grantedResourceIds) ->whereNotNull('parent_id') ->pluck('id') ->map(fn (int $resourceId): int => (int) $resourceId) ->all(); foreach ($existingResourceIds as $resourceId) { UserServerPermission::query()->updateOrCreate( [ 'user_id' => $user->id, 'server_resource_id' => $resourceId, ], [ 'can_ssh' => true, 'can_sftp' => true, 'can_rdp' => true, ] ); } } $managedResourceIds = Permission::query() ->where('guard_name', 'api') ->where('name', 'like', 'resource.servers.use.%') ->where('description', 'like', '服务器资源访问权限(资源ID:%') ->pluck('description') ->map(fn (string $description): ?int => $this->resourceIdFromPermissionDescription($description)) ->filter(fn (?int $resourceId): bool => $resourceId !== null) ->map(fn (int $resourceId): int => $resourceId) ->values() ->all(); if (count($managedResourceIds) > 0) { UserServerPermission::query() ->where('user_id', $user->id) ->whereIn('server_resource_id', $managedResourceIds) ->whereNotIn('server_resource_id', $grantedResourceIds) ->update([ 'can_ssh' => false, 'can_sftp' => false, 'can_rdp' => false, ]); } } private function resourceIdFromPermissionDescription(string $description): ?int { if (! preg_match('/资源ID:\s*(\d+)/u', $description, $matches)) { return null; } return isset($matches[1]) ? (int) $matches[1] : null; } }