From 91e3ec8cf1ad5e02f316ca6eaf25afd42e25a5d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Fri, 6 Feb 2026 09:10:07 +0900 Subject: [PATCH] =?UTF-8?q?feat:=ED=9C=B4=EC=9D=BC=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=EB=B0=A9=EC=A7=80=20=EB=B0=8F=20=EB=85=84?= =?UTF-8?q?=EB=8F=84=EB=B3=84=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - store/bulkStore 메소드에 중복 휴일 등록 방지 로직 추가 - 년도별 일괄 삭제 기능 (destroyByYear) 추가 - 휴일관리 UI에 년도 전체 삭제 버튼 추가 Co-Authored-By: Claude Opus 4.5 --- .../Controllers/System/HolidayController.php | 57 ++++++++++++++++++- .../views/system/holidays/index.blade.php | 28 +++++++++ routes/web.php | 1 + 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/System/HolidayController.php b/app/Http/Controllers/System/HolidayController.php index 812b424a..2d88475d 100644 --- a/app/Http/Controllers/System/HolidayController.php +++ b/app/Http/Controllers/System/HolidayController.php @@ -61,6 +61,20 @@ public function store(Request $request): JsonResponse $tenantId = session('selected_tenant_id', 1); + // 중복 체크: 같은 날짜 + 같은 이름 + $exists = Holiday::forTenant($tenantId) + ->where('start_date', $request->input('startDate')) + ->where('end_date', $request->input('endDate')) + ->where('name', $request->input('name')) + ->exists(); + + if ($exists) { + return response()->json([ + 'success' => false, + 'message' => '동일한 휴일이 이미 등록되어 있습니다.', + ], 422); + } + $holiday = Holiday::create([ 'tenant_id' => $tenantId, 'start_date' => $request->input('startDate'), @@ -132,8 +146,21 @@ public function bulkStore(Request $request): JsonResponse $tenantId = session('selected_tenant_id', 1); $count = 0; + $skipped = 0; foreach ($request->input('holidays') as $item) { + // 중복 체크 + $exists = Holiday::forTenant($tenantId) + ->where('start_date', $item['startDate']) + ->where('end_date', $item['endDate']) + ->where('name', $item['name']) + ->exists(); + + if ($exists) { + $skipped++; + continue; + } + Holiday::create([ 'tenant_id' => $tenantId, 'start_date' => $item['startDate'], @@ -146,9 +173,37 @@ public function bulkStore(Request $request): JsonResponse $count++; } + $message = "{$count}건의 휴일이 등록되었습니다."; + if ($skipped > 0) { + $message .= " (중복 {$skipped}건 제외)"; + } + return response()->json([ 'success' => true, - 'message' => "{$count}건의 휴일이 등록되었습니다.", + 'message' => $message, + ]); + } + + /** + * 해당 연도의 모든 휴일 삭제 + */ + public function destroyByYear(Request $request): JsonResponse + { + $request->validate([ + 'year' => 'required|integer|min:2000|max:2100', + ]); + + $tenantId = session('selected_tenant_id', 1); + $year = $request->input('year'); + + $count = Holiday::forTenant($tenantId) + ->forYear($year) + ->delete(); + + return response()->json([ + 'success' => true, + 'message' => "{$year}년도 휴일 {$count}건이 삭제되었습니다.", + 'data' => ['deleted' => $count], ]); } } diff --git a/resources/views/system/holidays/index.blade.php b/resources/views/system/holidays/index.blade.php index 8d7f80dd..d04f07bc 100644 --- a/resources/views/system/holidays/index.blade.php +++ b/resources/views/system/holidays/index.blade.php @@ -180,6 +180,26 @@ function HolidayManagement() { } }; + const handleDeleteYear = async () => { + if (!confirm(`${selectedYear}년도의 모든 휴일(${totalHolidays}건)을 삭제하시겠습니까?\n\n이 작업은 되돌릴 수 없습니다.`)) return; + try { + const res = await fetch(`/system/holidays/year/${selectedYear}`, { + method: 'DELETE', + headers: { 'X-CSRF-TOKEN': csrfToken }, + }); + const data = await res.json(); + if (res.ok) { + alert(data.message); + fetchHolidays(selectedYear); + } else { + alert(data.message || '삭제에 실패했습니다.'); + } + } catch (err) { + console.error('연도별 삭제 실패:', err); + alert('삭제에 실패했습니다.'); + } + }; + // 대량 등록 파싱 const parseBulkText = (text) => { const lines = text.trim().split('\n').filter(l => l.trim()); @@ -420,6 +440,14 @@ className={`relative h-9 flex flex-col items-center justify-center rounded curso ); })} + {totalHolidays > 0 && ( + + )} diff --git a/routes/web.php b/routes/web.php index 166a74a5..051504ca 100644 --- a/routes/web.php +++ b/routes/web.php @@ -401,6 +401,7 @@ Route::put('/{id}', [HolidayController::class, 'update'])->name('update'); Route::delete('/{id}', [HolidayController::class, 'destroy'])->name('destroy'); Route::post('/bulk', [HolidayController::class, 'bulkStore'])->name('bulk'); + Route::delete('/year/{year}', [HolidayController::class, 'destroyByYear'])->name('destroy-year'); }); // 명함 OCR API