MenuService.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. declare (strict_types=1);
  3. namespace app\service;
  4. use think\facade\Config;
  5. class MenuService
  6. {
  7. /**
  8. * 获取所有菜单配置
  9. */
  10. public static function getAllMenus(): array
  11. {
  12. return Config::get('menu.menus', []);
  13. }
  14. /**
  15. * 根据用户权限过滤菜单
  16. */
  17. public static function getMenusByPermission($userInfo): array
  18. {
  19. $allMenus = self::getAllMenus();
  20. return self::filterMenusByPermission($allMenus, $userInfo);
  21. }
  22. /**
  23. * 递归过滤菜单权限
  24. */
  25. private static function filterMenusByPermission($menus, $userInfo): array
  26. {
  27. $filteredMenus = [];
  28. foreach ($menus as $menu) {
  29. // 如果菜单指定了控制器,需要检查权限
  30. if (!empty($menu['controller'])) {
  31. if (!self::hasControllerPermission($userInfo, $menu['controller'])) {
  32. continue;
  33. }
  34. }
  35. // 处理子菜单
  36. if (isset($menu['children']) && is_array($menu['children'])) {
  37. $children = self::filterMenusByPermission($menu['children'], $userInfo);
  38. // 如果有子菜单权限,才显示父菜单
  39. if (!empty($children)) {
  40. $menu['children'] = $children;
  41. $filteredMenus[] = $menu;
  42. }
  43. } else {
  44. // 没有子菜单的情况
  45. if (empty($menu['controller']) || self::hasControllerPermission($userInfo, $menu['controller'])) {
  46. $filteredMenus[] = $menu;
  47. }
  48. }
  49. }
  50. return $filteredMenus;
  51. }
  52. /**
  53. * 检查用户是否有控制器权限
  54. */
  55. private static function hasControllerPermission($userInfo, $controller): bool
  56. {
  57. // 超级管理员拥有所有权限
  58. $superAdminRoleId = Config::get('permission.super_admin_role_id', 1);
  59. if ($userInfo['user_role'] == $superAdminRoleId) {
  60. return true;
  61. }
  62. // 获取用户角色权限
  63. $role = \app\model\UserRoleModel::getRoleById($userInfo['user_role'], $userInfo['merchant_id']);
  64. if (!$role) {
  65. return false;
  66. }
  67. $privileges = $role->privileges;
  68. // 检查是否有对应控制器的权限
  69. return isset($privileges[$controller]) && is_array($privileges[$controller]) && !empty($privileges[$controller]);
  70. }
  71. /**
  72. * 获取菜单树形结构(用于前端显示)
  73. */
  74. public static function getMenuTree($userInfo): array
  75. {
  76. $menus = self::getMenusByPermission($userInfo);
  77. return self::buildMenuTree($menus);
  78. }
  79. /**
  80. * 构建菜单树形结构
  81. */
  82. private static function buildMenuTree($menus): array
  83. {
  84. $tree = [];
  85. foreach ($menus as $menu) {
  86. $item = [
  87. 'id' => $menu['id'],
  88. 'title' => $menu['title'],
  89. 'icon' => $menu['icon'] ?? '',
  90. 'url' => $menu['url'] ?? '',
  91. 'controller' => $menu['controller'] ?? '',
  92. 'level' => $menu['level'],
  93. 'sort' => $menu['sort'] ?? 0,
  94. ];
  95. if (isset($menu['children']) && is_array($menu['children'])) {
  96. $item['children'] = self::buildMenuTree($menu['children']);
  97. $item['spread'] = false; // 默认不展开
  98. }
  99. $tree[] = $item;
  100. }
  101. // 按sort字段排序
  102. usort($tree, function($a, $b) {
  103. return ($a['sort'] ?? 0) - ($b['sort'] ?? 0);
  104. });
  105. return $tree;
  106. }
  107. /**
  108. * 获取所有控制器权限配置
  109. */
  110. public static function getControllerPermissions(): array
  111. {
  112. return Config::get('menu.controller_permissions', []);
  113. }
  114. /**
  115. * 根据菜单ID获取菜单信息
  116. */
  117. public static function getMenuById($menuId): ?array
  118. {
  119. $allMenus = self::getAllMenus();
  120. return self::findMenuById($allMenus, $menuId);
  121. }
  122. /**
  123. * 递归查找菜单
  124. */
  125. private static function findMenuById($menus, $menuId): ?array
  126. {
  127. foreach ($menus as $menu) {
  128. if ($menu['id'] == $menuId) {
  129. return $menu;
  130. }
  131. if (isset($menu['children']) && is_array($menu['children'])) {
  132. $found = self::findMenuById($menu['children'], $menuId);
  133. if ($found) {
  134. return $found;
  135. }
  136. }
  137. }
  138. return null;
  139. }
  140. /**
  141. * 获取面包屑导航
  142. */
  143. public static function getBreadcrumb($menuId): array
  144. {
  145. $breadcrumb = [];
  146. $allMenus = self::getAllMenus();
  147. $path = self::getMenuPath($allMenus, $menuId);
  148. foreach ($path as $menu) {
  149. $breadcrumb[] = [
  150. 'id' => $menu['id'],
  151. 'title' => $menu['title'],
  152. 'url' => $menu['url'] ?? ''
  153. ];
  154. }
  155. return $breadcrumb;
  156. }
  157. /**
  158. * 获取菜单路径
  159. */
  160. private static function getMenuPath($menus, $menuId, $path = []): array
  161. {
  162. foreach ($menus as $menu) {
  163. $currentPath = array_merge($path, [$menu]);
  164. if ($menu['id'] == $menuId) {
  165. return $currentPath;
  166. }
  167. if (isset($menu['children']) && is_array($menu['children'])) {
  168. $found = self::getMenuPath($menu['children'], $menuId, $currentPath);
  169. if (!empty($found)) {
  170. return $found;
  171. }
  172. }
  173. }
  174. return [];
  175. }
  176. }