fix : 메뉴 모델 및 일부 서비스파일 response 오류 수정

This commit is contained in:
2025-08-16 04:16:34 +09:00
parent 73d06e03b0
commit 6f1842181e
5 changed files with 312 additions and 211 deletions

View File

@@ -2,19 +2,26 @@
namespace App\Services;
use App\Helpers\ApiResponse;
use App\Models\Commons\Department;
use App\Models\Commons\DepartmentUser;
use App\Models\Commons\DepartmentPermission;
use App\Models\Commons\DepartmentUser;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Carbon\Carbon;
class DepartmentService
{
/**
* 공통 검증 헬퍼: 실패 시 JsonResponse 반환
*/
private static function v(array $params, array $rules)
{
$v = Validator::make($params, $rules);
if ($v->fails()) abort(422, $v->errors()->first());
if ($v->fails()) {
return ApiResponse::error($v->errors()->first(), 422);
}
return $v->validated();
}
@@ -27,18 +34,27 @@ public static function index(array $params)
'page' => 'nullable|integer|min:1',
'per_page' => 'nullable|integer|min:1|max:200',
]);
if ($p instanceof JsonResponse) return $p;
$q = Department::query();
if (isset($p['is_active'])) $q->where('is_active', (int)$p['is_active']);
if (isset($p['is_active'])) {
$q->where('is_active', (int)$p['is_active']);
}
if (!empty($p['q'])) {
$q->where(function($w) use ($p) {
$w->where('name','like','%'.$p['q'].'%')
->orWhere('code','like','%'.$p['q'].'%');
$q->where(function ($w) use ($p) {
$w->where('name', 'like', '%' . $p['q'] . '%')
->orWhere('code', 'like', '%' . $p['q'] . '%');
});
}
return $q->orderBy('sort_order')->orderBy('name')->paginate($p['per_page'] ?? 20);
$q->orderBy('sort_order')->orderBy('name');
$perPage = $p['per_page'] ?? 20;
$page = $p['page'] ?? null;
// 페이징 객체는 'result'로 반환
return ApiResponse::response('result', $q->paginate($perPage, ['*'], 'page', $page));
}
/** 생성 */
@@ -52,10 +68,11 @@ public static function store(array $params)
'sort_order' => 'nullable|integer',
'created_by' => 'nullable|integer|min:1',
]);
if ($p instanceof JsonResponse) return $p;
if (!empty($p['code'])) {
$exists = Department::query()->where('code', $p['code'])->exists();
if ($exists) abort(409, '이미 존재하는 부서 코드입니다.');
if ($exists) return ApiResponse::error('이미 존재하는 부서 코드입니다.', 409);
}
$dept = Department::create([
@@ -68,20 +85,28 @@ public static function store(array $params)
'updated_by' => $p['created_by'] ?? null,
]);
return self::show($dept->id, []);
return ApiResponse::response('result', $dept->fresh());
}
/** 단건 */
public static function show(int $id, array $params)
{
$dept = Department::query()->find($id);
if (!$dept) abort(404, '부서를 찾을 수 없습니다.');
return $dept;
if (!$id) return ApiResponse::error('id가 필요합니다.', 400);
$q = Department::query()->where('id', $id);
$res = ApiResponse::response('first', $q);
if (empty($res['data'])) {
return ApiResponse::error('부서를 찾을 수 없습니다.', 404);
}
return $res;
}
/** 수정 */
public static function update(int $id, array $params)
{
if (!$id) return ApiResponse::error('id가 필요합니다.', 400);
$p = self::v($params, [
'code' => 'nullable|string|max:50',
'name' => 'nullable|string|max:100',
@@ -90,16 +115,17 @@ public static function update(int $id, array $params)
'sort_order' => 'nullable|integer',
'updated_by' => 'nullable|integer|min:1',
]);
if ($p instanceof JsonResponse) return $p;
$dept = Department::query()->find($id);
if (!$dept) abort(404, '부서를 찾을 수 없습니다.');
if (!$dept) return ApiResponse::error('부서를 찾을 수 없습니다.', 404);
if (array_key_exists('code', $p) && !is_null($p['code'])) {
$exists = Department::query()
->where('code', $p['code'])
->where('id','!=',$id)
->where('id', '!=', $id)
->exists();
if ($exists) abort(409, '이미 존재하는 부서 코드입니다.');
if ($exists) return ApiResponse::error('이미 존재하는 부서 코드입니다.', 409);
}
$dept->fill([
@@ -111,18 +137,21 @@ public static function update(int $id, array $params)
'updated_by' => $p['updated_by'] ?? $dept->updated_by,
])->save();
return $dept->fresh();
return ApiResponse::response('result', $dept->fresh());
}
/** 삭제(soft) */
public static function destroy(int $id, array $params)
{
if (!$id) return ApiResponse::error('id가 필요합니다.', 400);
$p = self::v($params, [
'deleted_by' => 'nullable|integer|min:1',
]);
if ($p instanceof JsonResponse) return $p;
$dept = Department::query()->find($id);
if (!$dept) abort(404, '부서를 찾을 수 없습니다.');
if (!$dept) return ApiResponse::error('부서를 찾을 수 없습니다.', 404);
if (!empty($p['deleted_by'])) {
$dept->deleted_by = $p['deleted_by'];
@@ -130,7 +159,7 @@ public static function destroy(int $id, array $params)
}
$dept->delete();
return ['id'=>$id, 'deleted_at'=>now()->toDateTimeString()];
return ApiResponse::response('result', ['id' => $id, 'deleted_at' => now()->toDateTimeString()]);
}
/** 부서 사용자 목록 */
@@ -140,15 +169,18 @@ public static function listUsers(int $deptId, array $params)
'page' => 'nullable|integer|min:1',
'per_page' => 'nullable|integer|min:1|max:200',
]);
if ($p instanceof JsonResponse) return $p;
$dept = Department::query()->find($deptId);
if (!$dept) abort(404, '부서를 찾을 수 없습니다.');
if (!$dept) return ApiResponse::error('부서를 찾을 수 없습니다.', 404);
return $dept->departmentUsers()
->with('user')
->orderByDesc('is_primary')
->orderBy('id')
->paginate($p['per_page'] ?? 20);
$builder = $dept->departmentUsers()->with('user')
->orderByDesc('is_primary')->orderBy('id');
$perPage = $p['per_page'] ?? 20;
$page = $p['page'] ?? null;
return ApiResponse::response('result', $builder->paginate($perPage, ['*'], 'page', $page));
}
/** 사용자 배정 (단건) */
@@ -159,24 +191,25 @@ public static function attachUser(int $deptId, array $params)
'is_primary' => 'nullable|in:0,1',
'joined_at' => 'nullable|date',
]);
if ($p instanceof JsonResponse) return $p;
$dept = Department::query()->find($deptId);
if (!$dept) abort(404, '부서를 찾을 수 없습니다.');
if (!$dept) return ApiResponse::error('부서를 찾을 수 없습니다.', 404);
return DB::transaction(function () use ($dept, $p) {
$result = DB::transaction(function () use ($dept, $p) {
$du = DepartmentUser::withTrashed()
->where('department_id', $dept->id)
->where('user_id', $p['user_id'])
->first();
if ($du && is_null($du->deleted_at)) {
abort(409, '이미 배정된 사용자입니다.');
return ApiResponse::error('이미 배정된 사용자입니다.', 409);
}
if (!empty($p['is_primary']) && (int)$p['is_primary'] === 1) {
DepartmentUser::whereNull('deleted_at')
->where('user_id', $p['user_id'])
->update(['is_primary'=>0]);
->update(['is_primary' => 0]);
}
$payload = [
@@ -194,8 +227,13 @@ public static function attachUser(int $deptId, array $params)
DepartmentUser::create($payload);
}
return ['department_id'=>$dept->id, 'user_id'=>$p['user_id']];
return ['department_id' => $dept->id, 'user_id' => $p['user_id']];
});
// 트랜잭션 내부에서 에러 응답이 나올 수 있으므로 분기
if ($result instanceof JsonResponse) return $result;
return ApiResponse::response('result', $result);
}
/** 사용자 제거(soft) */
@@ -206,10 +244,14 @@ public static function detachUser(int $deptId, int $userId, array $params)
->where('user_id', $userId)
->first();
if (!$du) abort(404, '배정된 사용자를 찾을 수 없습니다.');
if (!$du) return ApiResponse::error('배정된 사용자를 찾을 수 없습니다.', 404);
$du->delete();
return ['user_id'=>$userId, 'deleted_at'=>now()->toDateTimeString()];
return ApiResponse::response('result', [
'user_id' => $userId,
'deleted_at' => now()->toDateTimeString(),
]);
}
/** 주부서 설정/해제 */
@@ -218,14 +260,17 @@ public static function setPrimary(int $deptId, int $userId, array $params)
$p = self::v($params, [
'is_primary' => 'required|in:0,1',
]);
if ($p instanceof JsonResponse) return $p;
return DB::transaction(function () use ($deptId, $userId, $p) {
$result = DB::transaction(function () use ($deptId, $userId, $p) {
$du = DepartmentUser::whereNull('deleted_at')
->where('department_id', $deptId)
->where('user_id', $userId)
->first();
if (!$du) abort(404, '배정된 사용자를 찾을 수 없습니다.');
if (!$du) {
return ApiResponse::error('배정된 사용자를 찾을 수 없습니다.', 404);
}
if ((int)$p['is_primary'] === 1) {
DepartmentUser::whereNull('deleted_at')
@@ -236,8 +281,12 @@ public static function setPrimary(int $deptId, int $userId, array $params)
$du->is_primary = (int)$p['is_primary'];
$du->save();
return ['user_id'=>$userId,'department_id'=>$deptId,'is_primary'=>$du->is_primary];
return ['user_id' => $userId, 'department_id' => $deptId, 'is_primary' => $du->is_primary];
});
if ($result instanceof JsonResponse) return $result;
return ApiResponse::response('result', $result);
}
/** 부서 권한 목록 */
@@ -249,9 +298,10 @@ public static function listPermissions(int $deptId, array $params)
'page' => 'nullable|integer|min:1',
'per_page' => 'nullable|integer|min:1|max:200',
]);
if ($p instanceof JsonResponse) return $p;
$dept = Department::query()->find($deptId);
if (!$dept) abort(404, '부서를 찾을 수 없습니다.');
if (!$dept) return ApiResponse::error('부서를 찾을 수 없습니다.', 404);
$q = DepartmentPermission::query()
->whereNull('deleted_at')
@@ -260,7 +310,12 @@ public static function listPermissions(int $deptId, array $params)
if (isset($p['menu_id'])) $q->where('menu_id', $p['menu_id']);
if (isset($p['is_allowed'])) $q->where('is_allowed', (int)$p['is_allowed']);
return $q->orderByDesc('is_allowed')->orderBy('permission_id')->paginate($p['per_page'] ?? 20);
$q->orderByDesc('is_allowed')->orderBy('permission_id');
$perPage = $p['per_page'] ?? 20;
$page = $p['page'] ?? null;
return ApiResponse::response('result', $q->paginate($perPage, ['*'], 'page', $page));
}
/** 권한 부여/차단 upsert */
@@ -271,9 +326,10 @@ public static function upsertPermission(int $deptId, array $params)
'menu_id' => 'nullable|integer|min:1',
'is_allowed' => 'nullable|in:0,1',
]);
if ($p instanceof JsonResponse) return $p;
$dept = Department::query()->find($deptId);
if (!$dept) abort(404, '부서를 찾을 수 없습니다.');
if (!$dept) return ApiResponse::error('부서를 찾을 수 없습니다.', 404);
$payload = [
'department_id' => $deptId,
@@ -286,6 +342,7 @@ public static function upsertPermission(int $deptId, array $params)
$model->deleted_at = null;
$model->save();
// 변경 후 목록 반환
return self::listPermissions($deptId, []);
}
@@ -295,6 +352,7 @@ public static function revokePermission(int $deptId, int $permissionId, array $p
$p = self::v($params, [
'menu_id' => 'nullable|integer|min:1',
]);
if ($p instanceof JsonResponse) return $p;
$q = DepartmentPermission::whereNull('deleted_at')
->where('department_id', $deptId)
@@ -303,14 +361,14 @@ public static function revokePermission(int $deptId, int $permissionId, array $p
if (isset($p['menu_id'])) $q->where('menu_id', $p['menu_id']);
$rows = $q->get();
if ($rows->isEmpty()) abort(404, '대상 권한을 찾을 수 없습니다.');
if ($rows->isEmpty()) return ApiResponse::error('대상 권한을 찾을 수 없습니다.', 404);
foreach ($rows as $row) $row->delete();
return [
return ApiResponse::response('result', [
'permission_id' => $permissionId,
'menu_id' => $p['menu_id'] ?? null,
'deleted_count' => $rows->count(),
];
]);
}
}