From 631287e75eb56d260b7982a5f26ec38266535a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Fri, 13 Feb 2026 07:09:14 +0900 Subject: [PATCH] =?UTF-8?q?fix:=EC=82=AC=EC=9D=B4=EB=93=9C=EB=B0=94=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4=20prefix=20=EB=A7=A4=EC=B9=AD=20=EC=8B=9C=20?= =?UTF-8?q?=EB=8D=94=20=EA=B5=AC=EC=B2=B4=EC=A0=81=EC=9D=B8=20=EB=A9=94?= =?UTF-8?q?=EB=89=B4=20=EC=9A=B0=EC=84=A0=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /esign/templates/5/fields 접속 시 /esign, /esign/templates 둘 다 활성화되던 문제 수정. 더 구체적인 prefix 메뉴가 있으면 덜 구체적인 메뉴는 비활성화. Co-Authored-By: Claude Opus 4.6 --- app/Services/SidebarMenuService.php | 36 ++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/app/Services/SidebarMenuService.php b/app/Services/SidebarMenuService.php index 33b693e7..50ee70ba 100644 --- a/app/Services/SidebarMenuService.php +++ b/app/Services/SidebarMenuService.php @@ -172,10 +172,11 @@ public function isMenuActive(Menu $menu): bool return true; } - // prefix 매칭: 다른 메뉴가 현재 URL에 정확히 매칭되면 prefix 매칭 비활성화 - // (예: /esign/create 접속 시, /esign 메뉴가 prefix로 잘못 활성화되는 것 방지) + // prefix 매칭: 더 구체적인 메뉴가 있으면 덜 구체적인 prefix 매칭 비활성화 + // (예: /esign/templates/5/fields 접속 시, /esign/templates 메뉴만 활성화, /esign 메뉴는 비활성) if (str_starts_with($currentPath, $menu->url.'/')) { - return !self::hasExactMenuMatch($currentPath); + return !self::hasExactMenuMatch($currentPath) + && !self::hasMoreSpecificPrefixMenu($currentPath, $menu->url); } return false; @@ -261,6 +262,35 @@ private static function hasExactMenuMatch(string $currentPath): bool return self::$exactMatchCache; } + /** + * 현재 경로에 대해 더 구체적인 prefix를 가진 메뉴가 있는지 확인 + * (예: 현재 메뉴 URL이 /esign이고, /esign/templates 메뉴도 있으면 true) + */ + private static array $prefixMenuCache = []; + + private static function hasMoreSpecificPrefixMenu(string $currentPath, string $menuUrl): bool + { + $cacheKey = $currentPath . '|' . $menuUrl; + if (isset(self::$prefixMenuCache[$cacheKey])) { + return self::$prefixMenuCache[$cacheKey]; + } + + $tenantId = auth()->user()?->tenant_id ?? 1; + + // 현재 경로의 prefix이면서 이 메뉴 URL보다 긴 URL을 가진 활성 메뉴가 있는지 확인 + $result = Menu::withoutGlobalScopes() + ->where('tenant_id', $tenantId) + ->where('is_active', true) + ->whereNotNull('url') + ->where('url', '!=', $menuUrl) + ->whereRaw('LENGTH(url) > ?', [strlen($menuUrl)]) + ->whereRaw("? LIKE CONCAT(url, '/%')", [$currentPath]) + ->exists(); + + self::$prefixMenuCache[$cacheKey] = $result; + return $result; + } + /** * 메뉴 또는 자식 메뉴가 활성 상태인지 확인 */