fix:카테고리 스코프 분류 버그 수정, 복사 시 소프트삭제 복원, UI 개선

- isset→array_key_exists: description NULL인 그룹 스코프 오분류 수정
- 글로벌+테넌트 필터 버튼 추가 (공통코드/카테고리)
- 전체선택 체크박스를 헤더 아이콘 앞에 배치
- 스크롤 영역 calc(100vh-180px) 화면 기준으로 변경
- 복사 시 소프트삭제된 동일 코드 존재하면 복원 처리

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-31 04:51:32 +09:00
parent df762d6cf4
commit d43f8d0ba1
5 changed files with 87 additions and 13 deletions

View File

@@ -174,19 +174,42 @@ public function copyToTenant(int $id): JsonResponse
$globalCategory = GlobalCategory::findOrFail($id);
// 이미 존재하는지 확인
// 활성 레코드 확인
$exists = Category::query()
->where('tenant_id', $tenantId)
->where('code_group', $globalCategory->code_group)
->where('code', $globalCategory->code)
->whereNull('deleted_at')
->exists();
if ($exists) {
return response()->json(['success' => false, 'message' => '이미 존재하는 카테고리입니다.'], 400);
}
// 복사 (parent_id는 복사하지 않음 - 개별 복사이므로)
// 소프트 삭제된 레코드 확인 → 복원
$trashed = Category::withoutGlobalScopes()->onlyTrashed()
->where('tenant_id', $tenantId)
->where('code_group', $globalCategory->code_group)
->where('code', $globalCategory->code)
->first();
if ($trashed) {
$trashed->restore();
$trashed->update([
'name' => $globalCategory->name,
'profile_code' => $globalCategory->profile_code,
'description' => $globalCategory->description,
'is_active' => $globalCategory->is_active,
'sort_order' => $globalCategory->sort_order,
'updated_by' => Auth::id(),
]);
return response()->json([
'success' => true,
'message' => '삭제된 카테고리를 복원하였습니다.',
]);
}
// 신규 복사
Category::create([
'tenant_id' => $tenantId,
'parent_id' => null,
@@ -234,12 +257,11 @@ public function bulkCopyToTenant(Request $request): JsonResponse
DB::beginTransaction();
try {
foreach ($globalCategories as $gc) {
// 이미 존재하는지 확인
// 활성 레코드 확인
$exists = Category::query()
->where('tenant_id', $tenantId)
->where('code_group', $gc->code_group)
->where('code', $gc->code)
->whereNull('deleted_at')
->exists();
if ($exists) {
@@ -247,6 +269,28 @@ public function bulkCopyToTenant(Request $request): JsonResponse
continue;
}
// 소프트 삭제된 레코드 확인 → 복원
$trashed = Category::withoutGlobalScopes()->onlyTrashed()
->where('tenant_id', $tenantId)
->where('code_group', $gc->code_group)
->where('code', $gc->code)
->first();
if ($trashed) {
$trashed->restore();
$trashed->update([
'name' => $gc->name,
'profile_code' => $gc->profile_code,
'description' => $gc->description,
'is_active' => $gc->is_active,
'sort_order' => $gc->sort_order,
'updated_by' => Auth::id(),
]);
$idMap[$gc->id] = $trashed->id;
$copied++;
continue;
}
// parent_id 매핑
$parentId = null;
if ($gc->parent_id && isset($idMap[$gc->parent_id])) {

View File

@@ -136,8 +136,8 @@ public function index(Request $request): View|Response
$codeGroups = [];
$groupScopes = [];
foreach ($allGroupKeys as $group) {
$inGlobal = isset($globalGroupDescs[$group]);
$inTenant = isset($tenantGroupDescs[$group]);
$inGlobal = array_key_exists($group, $globalGroupDescs);
$inTenant = array_key_exists($group, $tenantGroupDescs);
$codeGroups[$group] = ! empty($globalGroupDescs[$group])
? $globalGroupDescs[$group]

View File

@@ -65,8 +65,8 @@ public function index(Request $request): View|Response
$codeGroups = [];
$groupScopes = [];
foreach ($allGroupKeys as $group) {
$inGlobal = isset($globalGroupDescs[$group]);
$inTenant = isset($tenantGroupDescs[$group]);
$inGlobal = array_key_exists($group, $globalGroupDescs);
$inTenant = array_key_exists($group, $tenantGroupDescs);
// 라벨: 글로벌 description 우선 → 테넌트 → 커스텀 → 키 자체
$codeGroups[$group] = ! empty($globalGroupDescs[$group])