| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- <?php
- declare (strict_types=1);
- namespace app\service;
- use app\service\PermissionService;
- use think\facade\Config;
- class MenuService
- {
- /**
- * 获取所有菜单配置
- */
- public static function getAllMenus(): array
- {
- return Config::get('menu.menus', []);
- }
-
- /**
- * 获取用户菜单列表(基于权限过滤)
- */
- public static function getUserMenus(int $userId): array
- {
- $roleId = getUserRoleId($userId);
- if (!$roleId) {
- return [];
- }
-
- // 超级管理员返回所有菜单
- if (PermissionService::isSuperAdmin($roleId)) {
- return self::getAllMenus();
- }
-
- // 获取用户权限
- $permissions = PermissionService::getUserPermissions($roleId);
-
- // 获取所有菜单并根据权限过滤
- $allMenus = self::getAllMenus();
- return self::buildMenuTree(self::filterMenusByPermissions($allMenus, $permissions));
- }
-
- /**
- * 根据权限过滤菜单
- */
- private static function filterMenusByPermissions(array $menus, array $permissions): array
- {
- $filtered = [];
-
- foreach ($menus as $menu) {
- // 如果有子菜单,先递归过滤子菜单
- if (!empty($menu['children'])) {
- $filteredChildren = self::filterMenusByPermissions($menu['children'], $permissions);
-
- // 如果子菜单被过滤后还有内容,则保留父菜单
- if (!empty($filteredChildren)) {
- $menu['children'] = $filteredChildren;
- $filtered[] = $menu;
- }
- }
- // 如果菜单有控制器,检查用户是否有该控制器的任意权限
- elseif (!empty($menu['controller'])) {
- if (self::hasControllerPermission($menu['controller'], $permissions)) {
- $filtered[] = $menu;
- }
- }
- // 没有控制器也没有子菜单的菜单(可能是分隔符或静态链接)
- else {
- $filtered[] = $menu;
- }
- }
-
- return $filtered;
- }
-
- /**
- * 检查用户是否有指定控制器的任意权限
- */
- private static function hasControllerPermission(string $controller, array $permissions): bool
- {
- $controllerLower = strtolower($controller);
-
- // 检查用户权限中是否有该控制器的任意操作权限
- foreach ($permissions as $permission) {
- // 权限格式: controller.action
- if (strpos($permission, $controllerLower . '.') === 0) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * 获取菜单树形结构(用于前端展示)
- */
- public static function getMenuTree(int $userId): array
- {
- $menus = self::getUserMenus($userId);
- return self::buildMenuTree($menus);
- }
-
- /**
- * 构建菜单树
- */
- private static function buildMenuTree(array $menus): array
- {
- $tree = [];
-
- foreach ($menus as $menu) {
- $node = [
- 'title' => $menu['title'],
- 'icon' => $menu['icon'] ?? '',
- 'url' => $menu['url'] ?? '',
- ];
-
- if (!empty($menu['children'])) {
- $node['children'] = self::buildMenuTree($menu['children']);
- }
-
- $tree[] = $node;
- }
-
- return $tree;
- }
-
- /**
- * 根据ID获取菜单
- */
- public static function getMenuById(int $menuId): ?array
- {
- return self::findMenuInTree(self::getAllMenus(), $menuId);
- }
-
- /**
- * 在菜单树中查找指定ID的菜单
- */
- private static function findMenuInTree(array $menus, int $menuId): ?array
- {
- foreach ($menus as $menu) {
- if ($menu['id'] == $menuId) {
- return $menu;
- }
-
- if (!empty($menu['children'])) {
- $found = self::findMenuInTree($menu['children'], $menuId);
- if ($found) {
- return $found;
- }
- }
- }
-
- return null;
- }
- }
|