- Validator::make를 FormRequest로 분리 (6개 생성) - 하드코딩 한글 문자열을 i18n 키로 교체 - RoleMenuPermission 데드코드 제거 - Role 모델 SpatieRole 상속으로 일원화 - 권한 변경 후 캐시 무효화 추가 (AccessService::bumpVersion) - 미문서화 8개 Swagger 엔드포인트 추가 - 역할/권한 라우트에 perm.map+permission 미들웨어 추가
163 lines
4.5 KiB
PHP
163 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Authz;
|
|
|
|
use App\Models\Permissions\Role;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Spatie\Permission\PermissionRegistrar;
|
|
|
|
class RoleService
|
|
{
|
|
protected static string $guard = 'api';
|
|
|
|
/** 목록 */
|
|
public static function index(array $params = [])
|
|
{
|
|
$tenantId = (int) app('tenant_id');
|
|
$page = (int) ($params['page'] ?? 1);
|
|
$size = (int) ($params['size'] ?? 10);
|
|
$q = trim((string) ($params['q'] ?? ''));
|
|
|
|
$query = Role::query()
|
|
->where('tenant_id', $tenantId)
|
|
->where('guard_name', self::$guard)
|
|
->withCount(['permissions', 'users']);
|
|
|
|
// 검색 필터
|
|
if ($q !== '') {
|
|
$query->where(function ($w) use ($q) {
|
|
$w->where('name', 'like', "%{$q}%")
|
|
->orWhere('description', 'like', "%{$q}%");
|
|
});
|
|
}
|
|
|
|
// 숨김 상태 필터
|
|
if (isset($params['is_hidden'])) {
|
|
$isHidden = filter_var($params['is_hidden'], FILTER_VALIDATE_BOOLEAN);
|
|
$query->where('is_hidden', $isHidden);
|
|
}
|
|
|
|
$list = $query->orderByDesc('id')
|
|
->paginate($size, ['*'], 'page', $page);
|
|
|
|
return $list;
|
|
}
|
|
|
|
/** 생성 */
|
|
public static function store(array $params = [])
|
|
{
|
|
$tenantId = (int) app('tenant_id');
|
|
$userId = app('api_user');
|
|
|
|
// Spatie 팀(테넌트) 컨텍스트
|
|
app(PermissionRegistrar::class)->setPermissionsTeamId($tenantId);
|
|
|
|
$role = Role::create([
|
|
'tenant_id' => $tenantId,
|
|
'guard_name' => self::$guard,
|
|
'name' => $params['name'],
|
|
'description' => $params['description'] ?? null,
|
|
'is_hidden' => $params['is_hidden'] ?? false,
|
|
'created_by' => $userId,
|
|
]);
|
|
|
|
return $role->loadCount(['permissions', 'users']);
|
|
}
|
|
|
|
/** 단건 */
|
|
public static function show(int $id)
|
|
{
|
|
$tenantId = (int) app('tenant_id');
|
|
|
|
$role = Role::where('tenant_id', $tenantId)
|
|
->where('guard_name', self::$guard)
|
|
->withCount(['permissions', 'users'])
|
|
->find($id);
|
|
|
|
if (! $role) {
|
|
return ['error' => __('error.role.not_found'), 'code' => 404];
|
|
}
|
|
|
|
return $role;
|
|
}
|
|
|
|
/** 수정 */
|
|
public static function update(int $id, array $params = [])
|
|
{
|
|
$tenantId = (int) app('tenant_id');
|
|
$userId = app('api_user');
|
|
|
|
$role = Role::where('tenant_id', $tenantId)
|
|
->where('guard_name', self::$guard)
|
|
->find($id);
|
|
|
|
if (! $role) {
|
|
return ['error' => __('error.role.not_found'), 'code' => 404];
|
|
}
|
|
|
|
$updateData = $params;
|
|
$updateData['updated_by'] = $userId;
|
|
|
|
$role->fill($updateData)->save();
|
|
|
|
return $role->fresh()->loadCount(['permissions', 'users']);
|
|
}
|
|
|
|
/** 삭제 (Soft Delete) */
|
|
public static function destroy(int $id)
|
|
{
|
|
$tenantId = (int) app('tenant_id');
|
|
$userId = app('api_user');
|
|
|
|
$role = Role::where('tenant_id', $tenantId)
|
|
->where('guard_name', self::$guard)
|
|
->find($id);
|
|
|
|
if (! $role) {
|
|
return ['error' => __('error.role.not_found'), 'code' => 404];
|
|
}
|
|
|
|
DB::transaction(function () use ($role, $userId) {
|
|
// 권한 연결 해제
|
|
$role->permissions()->detach();
|
|
|
|
// Soft Delete
|
|
$role->update(['deleted_by' => $userId]);
|
|
$role->delete();
|
|
});
|
|
|
|
AccessService::bumpVersion($tenantId);
|
|
app(PermissionRegistrar::class)->forgetCachedPermissions();
|
|
|
|
return 'success';
|
|
}
|
|
|
|
/** 통계 조회 */
|
|
public static function stats()
|
|
{
|
|
$tenantId = (int) app('tenant_id');
|
|
|
|
$baseQuery = Role::where('tenant_id', $tenantId)
|
|
->where('guard_name', self::$guard);
|
|
|
|
return [
|
|
'total' => (clone $baseQuery)->count(),
|
|
'visible' => (clone $baseQuery)->where('is_hidden', false)->count(),
|
|
'hidden' => (clone $baseQuery)->where('is_hidden', true)->count(),
|
|
'with_users' => (clone $baseQuery)->has('users')->count(),
|
|
];
|
|
}
|
|
|
|
/** 활성 역할 목록 (드롭다운용) */
|
|
public static function active()
|
|
{
|
|
$tenantId = (int) app('tenant_id');
|
|
|
|
return Role::where('tenant_id', $tenantId)
|
|
->where('guard_name', self::$guard)
|
|
->where('is_hidden', false)
|
|
->orderBy('name')
|
|
->get(['id', 'name', 'description']);
|
|
}
|
|
}
|