diff --git a/app/common/logic/PermLogic.php b/app/common/logic/PermLogic.php index b6a2fc9..275912b 100644 --- a/app/common/logic/PermLogic.php +++ b/app/common/logic/PermLogic.php @@ -54,55 +54,70 @@ class PermLogic /** - * 构建目录/菜单树,节点包含权限与打开方式,拼接完整路径,并对子级菜单component处理 - * @param \Illuminate\Support\Collection $resources - * @param int $parentId - * @param string $parentPath + * 构建目录/菜单树,节点包含权限与打开方式,拼接完整路径,并对子级菜单 component 处理 + * + * @param \Illuminate\Support\Collection $resources 全部资源集合 + * @param int $parentId 当前父级资源 ID + * @param string $parentPath 父级完整路径(用于递归) * @return array */ - public function buildTree_bak($resources, int $parentId = 0, string $parentPath = ''): array + public function buildTree($resources, int $parentId = 0, string $parentPath = ''): array { $tree = []; + foreach ($resources as $node) { - if ($node->parent_id !== $parentId) continue; - - // 拼接完整路径 - $currentPath = $parentPath; - if ($currentPath && substr($currentPath, -1) === '/') { - $currentPath = rtrim($currentPath, '/'); + if ($node->parent_id !== $parentId) { + continue; } + + // —— 拼接当前节点的完整路径 —— + $currentPath = rtrim($parentPath, '/'); + if (!empty($node->url)) { - if (!$currentPath) { - $currentPath = $node->url; - } else { - $url = ltrim($node->url, '/'); - $currentPath = $currentPath . '/' . $url; - } + $urlSegment = ltrim($node->url, '/'); + $currentPath = $currentPath === '' + ? $urlSegment + : "{$currentPath}/{$urlSegment}"; } - // 子节点递归 + // —— 递归构建子节点 —— $children = []; - if ($node->type === 'directory') { + if (in_array($node->type, ['directory', 'menu'])) { $children = $this->buildTree($resources, $node->id, $currentPath); } - // 权限 + // —— 本级权限列表 —— $authList = $resources ->filter(fn($r) => $r->type === 'permission' && $r->parent_id === $node->id) ->map(fn($r) => [ 'id' => $r->id, 'title' => $r->name, 'auth_mark' => $r->code, - ])->values()->all(); + ]) + ->values() + ->all(); - // 判断是否有子级菜单(非权限) - $hasChildrenMenu = collect($resources)->where('parent_id', $node->id) - ->whereIn('type', ['directory', 'menu'])->isNotEmpty(); + // —— 判断是否有子目录或子菜单 —— + $hasChildrenMenu = $resources + ->where('parent_id', $node->id) + ->whereIn('type', ['directory', 'menu']) + ->isNotEmpty(); - // component 字段规则: - // 1. 存在子菜单,固定 '/index/index' - // 2. 否则为当前完整路径(或其它你想要的) - $componentValue = ($hasChildrenMenu && !$node->url && $node->type !== 'directory') ? '/index/index' : $currentPath; + // —— 计算 component 字段 —— + if ($hasChildrenMenu) { + if ($node->type === 'menu' && !empty($node->url)) { + // menu 类型且自身有 url,用自身 url(加前导 slash) + $componentValue = '/' . ltrim($node->url, '/'); + } else { + // 其它含子项的节点,固定 Layout 组件 + $componentValue = '/index/index'; + } + } else { + // 叶子节点:拼接路径,确保以 slash 开头 + $componentValue = $currentPath !== '' + ? '/' . ltrim($currentPath, '/') + : ''; + } $tree[] = [ 'id' => $node->id, @@ -119,8 +134,10 @@ class PermLogic 'children' => $children, ]; } + return $tree; } + /** * 构建目录/菜单树,节点包含权限与打开方式,拼接完整路径,并对子级菜单 component 处理 * @@ -129,7 +146,7 @@ class PermLogic * @param string $parentPath 父级完整路径(用于递归) * @return array */ - public function buildTree($resources, int $parentId = 0, string $parentPath = ''): array + public function buildTree_bak($resources, int $parentId = 0, string $parentPath = ''): array { $tree = [];