183 lines
4.5 KiB
PHP
183 lines
4.5 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Services;
|
||
|
|
|
||
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||
|
|
use Illuminate\Database\Eloquent\Collection;
|
||
|
|
use Spatie\Permission\Models\Role;
|
||
|
|
|
||
|
|
class RoleService
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* 역할 목록 조회 (페이지네이션)
|
||
|
|
*/
|
||
|
|
public function getRoles(array $filters = [], int $perPage = 15): LengthAwarePaginator
|
||
|
|
{
|
||
|
|
$tenantId = session('selected_tenant_id');
|
||
|
|
|
||
|
|
$query = Role::query()
|
||
|
|
->where('guard_name', 'web')
|
||
|
|
->withCount('permissions');
|
||
|
|
|
||
|
|
// Tenant 필터링 (선택된 경우에만)
|
||
|
|
if ($tenantId) {
|
||
|
|
$query->where('tenant_id', $tenantId);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 검색 필터
|
||
|
|
if (!empty($filters['search'])) {
|
||
|
|
$search = $filters['search'];
|
||
|
|
$query->where(function ($q) use ($search) {
|
||
|
|
$q->where('name', 'like', "%{$search}%")
|
||
|
|
->orWhere('description', 'like', "%{$search}%");
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// 정렬
|
||
|
|
$sortBy = $filters['sort_by'] ?? 'id';
|
||
|
|
$sortDirection = $filters['sort_direction'] ?? 'desc';
|
||
|
|
$query->orderBy($sortBy, $sortDirection);
|
||
|
|
|
||
|
|
return $query->paginate($perPage);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 특정 역할 조회
|
||
|
|
*/
|
||
|
|
public function getRoleById(int $id): ?Role
|
||
|
|
{
|
||
|
|
$tenantId = session('selected_tenant_id');
|
||
|
|
|
||
|
|
$query = Role::query()
|
||
|
|
->where('guard_name', 'web')
|
||
|
|
->with('permissions');
|
||
|
|
|
||
|
|
// Tenant 필터링 (선택된 경우에만)
|
||
|
|
if ($tenantId) {
|
||
|
|
$query->where('tenant_id', $tenantId);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $query->find($id);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 역할 생성
|
||
|
|
*/
|
||
|
|
public function createRole(array $data): Role
|
||
|
|
{
|
||
|
|
$tenantId = session('selected_tenant_id');
|
||
|
|
|
||
|
|
$role = Role::create([
|
||
|
|
'tenant_id' => $tenantId,
|
||
|
|
'guard_name' => 'web',
|
||
|
|
'name' => $data['name'],
|
||
|
|
'description' => $data['description'] ?? null,
|
||
|
|
]);
|
||
|
|
|
||
|
|
// 권한 동기화 (있는 경우)
|
||
|
|
if (!empty($data['permissions'])) {
|
||
|
|
$role->syncPermissions($data['permissions']);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $role->fresh(['permissions']);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 역할 수정
|
||
|
|
*/
|
||
|
|
public function updateRole(int $id, array $data): bool
|
||
|
|
{
|
||
|
|
$role = $this->getRoleById($id);
|
||
|
|
|
||
|
|
if (!$role) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$updated = $role->update([
|
||
|
|
'name' => $data['name'] ?? $role->name,
|
||
|
|
'description' => $data['description'] ?? $role->description,
|
||
|
|
]);
|
||
|
|
|
||
|
|
// 권한 동기화 (있는 경우)
|
||
|
|
if (isset($data['permissions'])) {
|
||
|
|
$role->syncPermissions($data['permissions']);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $updated;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 역할 삭제
|
||
|
|
*/
|
||
|
|
public function deleteRole(int $id): bool
|
||
|
|
{
|
||
|
|
$role = $this->getRoleById($id);
|
||
|
|
|
||
|
|
if (!$role) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 권한 연결 해제
|
||
|
|
$role->permissions()->detach();
|
||
|
|
|
||
|
|
// 사용자 연결 해제
|
||
|
|
$role->users()->detach();
|
||
|
|
|
||
|
|
return $role->delete();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 역할 이름 중복 체크
|
||
|
|
*/
|
||
|
|
public function isNameExists(string $name, ?int $excludeId = null): bool
|
||
|
|
{
|
||
|
|
$tenantId = session('selected_tenant_id');
|
||
|
|
|
||
|
|
$query = Role::where('tenant_id', $tenantId)
|
||
|
|
->where('guard_name', 'web')
|
||
|
|
->where('name', $name);
|
||
|
|
|
||
|
|
if ($excludeId) {
|
||
|
|
$query->where('id', '!=', $excludeId);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $query->exists();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 활성 역할 목록 (드롭다운용)
|
||
|
|
*/
|
||
|
|
public function getActiveRoles(): Collection
|
||
|
|
{
|
||
|
|
$tenantId = session('selected_tenant_id');
|
||
|
|
|
||
|
|
$query = Role::query()->where('guard_name', 'web');
|
||
|
|
|
||
|
|
// Tenant 필터링 (선택된 경우에만)
|
||
|
|
if ($tenantId) {
|
||
|
|
$query->where('tenant_id', $tenantId);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $query->orderBy('name')->get(['id', 'name', 'description']);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 역할 통계
|
||
|
|
*/
|
||
|
|
public function getRoleStats(): array
|
||
|
|
{
|
||
|
|
$tenantId = session('selected_tenant_id');
|
||
|
|
|
||
|
|
$baseQuery = Role::query()->where('guard_name', 'web');
|
||
|
|
|
||
|
|
// Tenant 필터링 (선택된 경우에만)
|
||
|
|
if ($tenantId) {
|
||
|
|
$baseQuery->where('tenant_id', $tenantId);
|
||
|
|
}
|
||
|
|
|
||
|
|
return [
|
||
|
|
'total' => (clone $baseQuery)->count(),
|
||
|
|
'with_permissions' => (clone $baseQuery)->has('permissions')->count(),
|
||
|
|
];
|
||
|
|
}
|
||
|
|
}
|