feat: menus 테이블 options JSON 컬럼 추가
- menus 테이블에 options JSON 컬럼 추가 (확장 데이터 저장용) - Menu 모델에 options 헬퍼 메서드 추가 - getOption(), setOption() - getRouteName(), getSection(), getMenuType() - requiresRole(), getBladeComponent(), getCssClass() - getMeta(), setMeta() - JSON 컬럼 기반 스코프 메서드 추가 - scopeSection(), scopeMenuType(), scopeRequiringRole()
This commit is contained in:
@@ -19,7 +19,7 @@ class Menu extends Model
|
||||
|
||||
protected $fillable = [
|
||||
'tenant_id', 'parent_id', 'global_menu_id', 'name', 'url', 'is_active', 'sort_order',
|
||||
'hidden', 'is_customized', 'is_external', 'external_url', 'icon',
|
||||
'hidden', 'is_customized', 'is_external', 'external_url', 'icon', 'options',
|
||||
'created_by', 'updated_by', 'deleted_by',
|
||||
];
|
||||
|
||||
@@ -35,6 +35,7 @@ class Menu extends Model
|
||||
'hidden' => 'boolean',
|
||||
'is_customized' => 'boolean',
|
||||
'is_external' => 'boolean',
|
||||
'options' => 'array',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -135,6 +136,140 @@ public function scopeRoots($query)
|
||||
*/
|
||||
public static function getSyncFields(): array
|
||||
{
|
||||
return ['name', 'url', 'icon', 'sort_order', 'is_active', 'hidden', 'is_external', 'external_url'];
|
||||
return ['name', 'url', 'icon', 'sort_order', 'is_active', 'hidden', 'is_external', 'external_url', 'options'];
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Options JSON 헬퍼 메서드
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* options에서 특정 키 값 조회
|
||||
*/
|
||||
public function getOption(string $key, mixed $default = null): mixed
|
||||
{
|
||||
return data_get($this->options, $key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* options에 특정 키 값 설정
|
||||
*/
|
||||
public function setOption(string $key, mixed $value): static
|
||||
{
|
||||
$options = $this->options ?? [];
|
||||
data_set($options, $key, $value);
|
||||
$this->options = $options;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 라우트명 조회 (mng, api, react 등에서 사용)
|
||||
*/
|
||||
public function getRouteName(): ?string
|
||||
{
|
||||
return $this->getOption('route_name');
|
||||
}
|
||||
|
||||
/**
|
||||
* 메뉴 섹션 조회 (main, tools, labs 등)
|
||||
*/
|
||||
public function getSection(): string
|
||||
{
|
||||
return $this->getOption('section', 'main');
|
||||
}
|
||||
|
||||
/**
|
||||
* 메뉴 타입 조회 (normal, tool, lab 등)
|
||||
*/
|
||||
public function getMenuType(): string
|
||||
{
|
||||
return $this->getOption('menu_type', 'normal');
|
||||
}
|
||||
|
||||
/**
|
||||
* 필요 역할 조회
|
||||
*/
|
||||
public function getRequiresRole(): ?string
|
||||
{
|
||||
return $this->getOption('requires_role');
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 역할이 필요한지 확인
|
||||
*/
|
||||
public function requiresRole(?string $role = null): bool
|
||||
{
|
||||
$requiredRole = $this->getRequiresRole();
|
||||
|
||||
if ($requiredRole === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($role === null) {
|
||||
return true; // 역할이 필요함
|
||||
}
|
||||
|
||||
return $requiredRole === $role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blade 컴포넌트명 조회
|
||||
*/
|
||||
public function getBladeComponent(): ?string
|
||||
{
|
||||
return $this->getOption('blade_component');
|
||||
}
|
||||
|
||||
/**
|
||||
* CSS 클래스 조회
|
||||
*/
|
||||
public function getCssClass(): ?string
|
||||
{
|
||||
return $this->getOption('css_class');
|
||||
}
|
||||
|
||||
/**
|
||||
* meta 데이터 조회 (앱별 커스텀 데이터)
|
||||
*/
|
||||
public function getMeta(?string $key = null, mixed $default = null): mixed
|
||||
{
|
||||
if ($key === null) {
|
||||
return $this->getOption('meta', []);
|
||||
}
|
||||
|
||||
return $this->getOption("meta.{$key}", $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta 데이터 설정
|
||||
*/
|
||||
public function setMeta(string $key, mixed $value): static
|
||||
{
|
||||
return $this->setOption("meta.{$key}", $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 섹션 메뉴만 조회
|
||||
*/
|
||||
public function scopeSection($query, string $section)
|
||||
{
|
||||
return $query->whereJsonContains('options->section', $section);
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 메뉴 타입만 조회
|
||||
*/
|
||||
public function scopeMenuType($query, string $type)
|
||||
{
|
||||
return $query->whereJsonContains('options->menu_type', $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 역할이 필요한 메뉴만 조회
|
||||
*/
|
||||
public function scopeRequiringRole($query, string $role)
|
||||
{
|
||||
return $query->whereJsonContains('options->requires_role', $role);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user