id; $settings = self::settings(); if (in_array($userKey, $settings['configured'] ?? [], true)) { return $userKey; } return 'role_' . SystemAccess::roleName($user); } public static function allowedKeys(User $user): ?array { if (SystemAccess::isSuperAdmin($user)) { return null; } $settings = self::settings(); $userSubject = 'user_' . $user->id; if (in_array($userSubject, $settings['configured'] ?? [], true)) { return array_values(array_unique((array) ($settings['subjects'][$userSubject] ?? []))); } $groups = UserAccessGroup::forUser($user); if ($groups->isNotEmpty()) { return $groups->flatMap(fn ($group) => $group->page_permissions ?? [])->unique()->values()->all(); } $subject = 'role_' . SystemAccess::roleName($user); if (! in_array($subject, $settings['configured'] ?? [], true)) { return null; } return array_values(array_unique((array) ($settings['subjects'][$subject] ?? []))); } public static function navigationFor(User $user): array { $navigation = BusinessNavigation::all(); $allowed = self::allowedKeys($user); if ($allowed === null) { return $navigation; } return array_values(array_filter(array_map(function (array $section) use ($allowed) { $sectionKey = $section['slug']; if (in_array($sectionKey, $allowed, true)) { return $section; } $pages = array_values(array_filter(array_map(function (array $page) use ($allowed, $sectionKey) { $pageKey = $sectionKey . '/' . $page['slug']; if (in_array($pageKey, $allowed, true)) { // 若有 children,保留 children 的精确权限过滤 if (! empty($page['children'])) { $page['children'] = array_values(array_filter($page['children'], function (array $child) use ($allowed, $sectionKey) { return in_array($sectionKey . '/' . $child['slug'], $allowed, true); })); } return $page; } // 子页面可能在 allowed 列表中(独立 URL),父级分组也允许展开 if (! empty($page['children'])) { $visibleChildren = array_values(array_filter($page['children'], function (array $child) use ($allowed, $sectionKey) { return in_array($sectionKey . '/' . $child['slug'], $allowed, true); })); if (! empty($visibleChildren)) { $page['children'] = $visibleChildren; return $page; } } return null; }, $section['pages'] ?? []))); if (! empty($pages)) { $section['pages'] = $pages; return $section; } return null; }, $navigation))); } public static function allKeys(): array { $keys = []; foreach (BusinessNavigation::all() as $section) { $keys[] = $section['slug']; foreach ($section['pages'] ?? [] as $page) { $keys[] = $section['slug'] . '/' . $page['slug']; foreach ($page['children'] ?? [] as $child) { $keys[] = $section['slug'] . '/' . $child['slug']; } } } return $keys; } }