From 975a90d1f82c16afa9e646f708a9a293479c3eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Thu, 5 Mar 2026 16:21:48 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[approval]=20=EA=B8=B0=EC=95=88?= =?UTF-8?q?=ED=95=A8=20=EC=9E=91=EC=84=B1=EC=9E=90=20=EC=97=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EC=8A=88=ED=8D=BC=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90=20=EC=98=81=EA=B5=AC=EC=82=AD=EC=A0=9C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기안함 테이블에 작성자 열 추가 - 슈퍼관리자: 전체 기안문서 조회 + 영구삭제 버튼 - forceDestroy API 엔드포인트 추가 (연관 Leave/Steps 함께 삭제) - 기안함에서 휴가신청 시 Leave 자동 생성 로직 추가 --- .../Api/Admin/ApprovalApiController.php | 27 +++++++++++++++++ app/Services/ApprovalService.php | 29 +++++++++++++++++-- resources/views/approvals/drafts.blade.php | 26 +++++++++++++++++ routes/api.php | 5 ++-- 4 files changed, 82 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Api/Admin/ApprovalApiController.php b/app/Http/Controllers/Api/Admin/ApprovalApiController.php index 574b0fd2..91b783e6 100644 --- a/app/Http/Controllers/Api/Admin/ApprovalApiController.php +++ b/app/Http/Controllers/Api/Admin/ApprovalApiController.php @@ -180,6 +180,33 @@ public function destroy(int $id): JsonResponse } } + /** + * 영구삭제 (슈퍼관리자 전용) + */ + public function forceDestroy(int $id): JsonResponse + { + if (! auth()->user()->isSuperAdmin()) { + return response()->json([ + 'success' => false, + 'message' => '슈퍼관리자만 영구삭제할 수 있습니다.', + ], 403); + } + + try { + $this->service->forceDeleteApproval($id); + + return response()->json([ + 'success' => true, + 'message' => '결재 문서가 영구삭제되었습니다.', + ]); + } catch (\Throwable $e) { + return response()->json([ + 'success' => false, + 'message' => '영구삭제에 실패했습니다.', + ], 500); + } + } + // ========================================================================= // 워크플로우 // ========================================================================= diff --git a/app/Services/ApprovalService.php b/app/Services/ApprovalService.php index 7fe77405..f9cabe36 100644 --- a/app/Services/ApprovalService.php +++ b/app/Services/ApprovalService.php @@ -23,10 +23,14 @@ class ApprovalService */ public function getMyDrafts(array $filters = [], int $perPage = 15): LengthAwarePaginator { - $userId = auth()->id(); + $user = auth()->user(); - $query = Approval::with(['form', 'steps.approver']) - ->byDrafter($userId); + $query = Approval::with(['form', 'drafter', 'steps.approver']); + + // 슈퍼관리자는 전체 조회, 일반 사용자는 본인 기안만 + if (! $user->isSuperAdmin()) { + $query->byDrafter($user->id); + } $this->applyFilters($query, $filters); @@ -220,6 +224,25 @@ public function deleteApproval(int $id, ?User $user = null): bool return $approval->delete(); } + /** + * 영구삭제 (슈퍼관리자 전용) + */ + public function forceDeleteApproval(int $id): bool + { + $approval = Approval::withTrashed()->with('form')->findOrFail($id); + + // 연동 Leave 정리 + $leave = \App\Models\HR\Leave::where('approval_id', $approval->id)->first(); + if ($leave) { + $leave->update(['deleted_by' => auth()->id()]); + $leave->delete(); + } + + $approval->steps()->withTrashed()->forceDelete(); + + return $approval->forceDelete(); + } + // ========================================================================= // 워크플로우 // ========================================================================= diff --git a/resources/views/approvals/drafts.blade.php b/resources/views/approvals/drafts.blade.php index fb22c513..fd811937 100644 --- a/resources/views/approvals/drafts.blade.php +++ b/resources/views/approvals/drafts.blade.php @@ -392,6 +392,8 @@ class="toss-input-sm" style="padding-left: 32px;"> @push('scripts')