Files
sam-manage/app/Models/Tenants/Tenant.php
hskwon f49cfd982a 테넌트 관리 기능 수정 및 ViewServiceProvider 변수명 충돌 해결
주요 변경사항:
- Spatie Laravel Permission 패키지 설치 (v6.23.0)
- admin 프로젝트에서 필수 Traits 및 Scopes 복사
  - ModelTrait, BelongsToTenant, HasTenantFilter, UppercaseAttributes
  - TenantScope
- Tenant 모델 관계 수정 (hasMany → belongsToMany via user_tenants)
- Tenant 모델 null 처리 추가 (status_label, created_at)
- Laravel 12 bootstrap/app.php에 API 라우트 등록
- API 라우트 미들웨어 수정 (auth:sanctum → web,auth)
- HTMX 라이브러리 및 CSRF 토큰 헤더 추가

ViewServiceProvider 수정:
- 전역 View Composer의 $tenants 변수를 $globalTenants로 변경
- 페이지별 페이지네이션된 $tenants 변수와의 충돌 방지
- tenant-selector.blade.php에서 $globalTenants 사용

버그 수정:
- Collection::hasPages() 오류 해결 (ViewComposer 변수 덮어쓰기 문제)
- 테넌트 목록 무한 로딩 스피너 해결
- 500 Internal Server Error 해결
2025-11-24 11:17:31 +09:00

135 lines
3.1 KiB
PHP

<?php
namespace App\Models\Tenants;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
class Tenant extends Model
{
use SoftDeletes;
protected $table = 'tenants';
protected $fillable = [
// 기본 정보
'company_name',
'code',
'email',
'phone',
// 회사 정보
'business_num',
'corp_reg_no',
'ceo_name',
'address',
'homepage',
'fax',
// 구독 정보
'tenant_st_code',
'billing_tp_code',
'max_users',
'trial_ends_at',
'expires_at',
'last_paid_at',
// 관리 메모
'admin_memo',
];
protected $casts = [
'max_users' => 'integer',
'trial_ends_at' => 'datetime',
'expires_at' => 'datetime',
'last_paid_at' => 'datetime',
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
/**
* 활성 테넌트만 조회 (삭제되지 않은 모든 테넌트)
*/
public function scopeActive($query)
{
return $query->whereNull('deleted_at');
}
/**
* 관계: 사용자 (Many-to-Many via user_tenants)
*/
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class, 'user_tenants');
}
/**
* 관계: 부서
*/
public function departments(): HasMany
{
return $this->hasMany(\App\Models\Tenants\Department::class, 'tenant_id');
}
/**
* 관계: 메뉴
*/
public function menus(): HasMany
{
return $this->hasMany(\App\Models\Commons\Menu::class, 'tenant_id');
}
/**
* 관계: 역할
*/
public function roles(): HasMany
{
return $this->hasMany(\App\Models\Permissions\Role::class, 'tenant_id');
}
/**
* 상태 배지 색상 (Blade 뷰에서 사용)
*/
public function getStatusBadgeColorAttribute(): string
{
return match($this->tenant_st_code) {
'active' => 'success',
'trial' => 'warning',
'suspended', 'expired' => 'error',
default => 'neutral',
};
}
/**
* 상태 한글명 (Blade 뷰에서 사용)
*/
public function getStatusLabelAttribute(): string
{
return match($this->tenant_st_code) {
'trial' => '트라이얼',
'active' => '활성',
'suspended' => '정지',
'expired' => '만료',
default => $this->tenant_st_code ?? '미설정',
};
}
/**
* 결제 유형 한글명 (Blade 뷰에서 사용)
*/
public function getBillingTypeLabelAttribute(): ?string
{
if (!$this->billing_tp_code) {
return null;
}
return match($this->billing_tp_code) {
'monthly' => '월간',
'yearly' => '연간',
'free' => '무료',
default => $this->billing_tp_code,
};
}
}