diff --git a/app/Models/User.php b/app/Models/User.php index f91c1664..41936b20 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; @@ -62,10 +63,27 @@ protected function casts(): array } /** - * 관계: 테넌트 + * 관계: 테넌트들 (Many-to-Many via user_tenants) */ - public function tenant() + public function tenants(): BelongsToMany { - return $this->belongsTo(\App\Models\Tenants\Tenant::class, 'tenant_id'); + return $this->belongsToMany(\App\Models\Tenants\Tenant::class, 'user_tenants') + ->withTimestamps() + ->withPivot(['is_active', 'is_default', 'joined_at', 'left_at']); } -} \ No newline at end of file + + /** + * 현재 선택된 테넌트 (세션 기반) + */ + public function currentTenant() + { + $tenantId = session('selected_tenant_id'); + + if (! $tenantId) { + return $this->tenants()->where('is_default', true)->first() + ?? $this->tenants()->first(); + } + + return $this->tenants()->find($tenantId); + } +} diff --git a/app/Services/UserService.php b/app/Services/UserService.php new file mode 100644 index 00000000..894b54a6 --- /dev/null +++ b/app/Services/UserService.php @@ -0,0 +1,145 @@ +whereHas('tenants', function ($q) use ($tenantId) { + $q->where('tenants.id', $tenantId); + }); + } + + // 검색 필터 + if (! empty($filters['search'])) { + $search = $filters['search']; + $query->where(function ($q) use ($search) { + $q->where('name', 'like', "%{$search}%") + ->orWhere('email', 'like', "%{$search}%") + ->orWhere('phone', 'like', "%{$search}%") + ->orWhere('user_id', 'like', "%{$search}%"); + }); + } + + // 활성 상태 필터 + if (isset($filters['is_active'])) { + $query->where('is_active', $filters['is_active']); + } + + return $query->orderBy('created_at', 'desc')->paginate($perPage); + } + + /** + * 사용자 상세 조회 + */ + public function getUserById(int $id): ?User + { + return User::find($id); + } + + /** + * 사용자 생성 + */ + public function createUser(array $data): User + { + $tenantId = session('selected_tenant_id'); + + // 비밀번호 해싱 + if (isset($data['password'])) { + $data['password'] = Hash::make($data['password']); + } + + // is_active 처리 + $data['is_active'] = isset($data['is_active']) && $data['is_active'] == '1'; + + // 생성자 정보 + $data['created_by'] = auth()->id(); + + // 사용자 생성 + $user = User::create($data); + + // user_tenants pivot에 관계 추가 + if ($tenantId) { + $user->tenants()->attach($tenantId, [ + 'is_active' => true, + 'is_default' => true, + 'joined_at' => now(), + ]); + } + + return $user; + } + + /** + * 사용자 수정 + */ + public function updateUser(int $id, array $data): bool + { + $user = $this->getUserById($id); + if (! $user) { + return false; + } + + // 비밀번호가 입력된 경우만 업데이트 + if (! empty($data['password'])) { + $data['password'] = Hash::make($data['password']); + } else { + unset($data['password']); + } + + // is_active 처리 + $data['is_active'] = isset($data['is_active']) && $data['is_active'] == '1'; + + // 수정자 정보 + $data['updated_by'] = auth()->id(); + + return $user->update($data); + } + + /** + * 사용자 삭제 (Soft Delete) + */ + public function deleteUser(int $id): bool + { + $user = $this->getUserById($id); + if (! $user) { + return false; + } + + $user->deleted_by = auth()->id(); + $user->save(); + + return $user->delete(); + } + + /** + * 활성 사용자 목록 조회 (드롭다운용) + */ + public function getActiveUsers() + { + $tenantId = session('selected_tenant_id'); + $query = User::query()->where('is_active', true); + + // 테넌트 필터링 (user_tenants pivot을 통한 필터링) + if ($tenantId) { + $query->whereHas('tenants', function ($q) use ($tenantId) { + $q->where('tenants.id', $tenantId); + }); + } + + return $query->orderBy('name')->get(); + } +}