From 0d12295495ee7196e487d5c4c9d376d2e8725ae6 Mon Sep 17 00:00:00 2001 From: hskwon Date: Tue, 2 Dec 2025 20:43:29 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20GlobalMenu=20=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20Menu=20=EA=B4=80=EA=B3=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - GlobalMenu 모델 생성 - Menu.globalMenu() 관계를 GlobalMenu 모델로 변경 --- app/Models/Commons/GlobalMenu.php | 149 ++++++++++++++++++++++++++++++ app/Models/Commons/Menu.php | 18 +--- 2 files changed, 150 insertions(+), 17 deletions(-) create mode 100644 app/Models/Commons/GlobalMenu.php diff --git a/app/Models/Commons/GlobalMenu.php b/app/Models/Commons/GlobalMenu.php new file mode 100644 index 00000000..3debf8d2 --- /dev/null +++ b/app/Models/Commons/GlobalMenu.php @@ -0,0 +1,149 @@ + 'boolean', + 'hidden' => 'boolean', + 'is_external' => 'boolean', + ]; + + /** + * 동기화 비교 대상 필드 + */ + public static function getSyncFields(): array + { + return ['name', 'url', 'icon', 'sort_order', 'is_active', 'hidden', 'is_external', 'external_url']; + } + + /** + * 상위 메뉴 + */ + public function parent(): BelongsTo + { + return $this->belongsTo(GlobalMenu::class, 'parent_id'); + } + + /** + * 하위 메뉴 목록 + */ + public function children(): HasMany + { + return $this->hasMany(GlobalMenu::class, 'parent_id'); + } + + /** + * 이 글로벌 메뉴로부터 복제된 테넌트 메뉴 목록 + */ + public function tenantMenus(): HasMany + { + return $this->hasMany(Menu::class, 'global_menu_id'); + } + + /** + * 활성화된 메뉴만 조회 + */ + public function scopeActive($query) + { + return $query->where('is_active', true); + } + + /** + * 숨겨지지 않은 메뉴만 조회 + */ + public function scopeVisible($query) + { + return $query->where('hidden', false); + } + + /** + * 최상위 메뉴만 조회 + */ + public function scopeRoots($query) + { + return $query->whereNull('parent_id'); + } + + /** + * 정렬된 메뉴 조회 + */ + public function scopeOrdered($query) + { + return $query->orderBy('sort_order')->orderBy('id'); + } + + /** + * 메뉴 레벨 계산 (대메뉴=1, 중메뉴=2, 소메뉴=3) + */ + public function getLevel(): int + { + if (is_null($this->parent_id)) { + return 1; + } + + $parent = $this->parent; + if ($parent && is_null($parent->parent_id)) { + return 2; + } + + return 3; + } + + /** + * 계층 구조로 정렬된 전체 메뉴 트리 조회 + */ + public static function getMenuTree(): array + { + $menus = static::with('children.children') + ->whereNull('parent_id') + ->active() + ->visible() + ->ordered() + ->get(); + + return $menus->toArray(); + } +} \ No newline at end of file diff --git a/app/Models/Commons/Menu.php b/app/Models/Commons/Menu.php index 08c4aa77..6dad10a0 100644 --- a/app/Models/Commons/Menu.php +++ b/app/Models/Commons/Menu.php @@ -63,23 +63,7 @@ public function tenant() */ public function globalMenu() { - return $this->belongsTo(Menu::class, 'global_menu_id'); - } - - /** - * 이 글로벌 메뉴에서 복제된 테넌트 메뉴들 - */ - public function tenantMenus() - { - return $this->hasMany(Menu::class, 'global_menu_id'); - } - - /** - * 글로벌 메뉴인지 확인 - */ - public function isGlobal(): bool - { - return is_null($this->tenant_id); + return $this->belongsTo(GlobalMenu::class, 'global_menu_id'); } /**