refactor: [hr] 사원 첨부파일을 GCS 듀얼 저장 방식으로 변경
- 업로드: 로컬 + GCS 동시 저장 (gcs_object_name, gcs_uri 기록) - 다운로드: GCS Signed URL 우선, 로컬 폴백 - 삭제: GCS + 로컬 모두 삭제, soft delete 처리 - DashboardCalendarController 패턴 준용
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Boards\File;
|
use App\Models\Boards\File;
|
||||||
|
use App\Services\GoogleCloudStorageService;
|
||||||
use App\Services\HR\EmployeeService;
|
use App\Services\HR\EmployeeService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -256,9 +257,9 @@ public function destroy(Request $request, int $id): JsonResponse|Response
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 사원 첨부파일 업로드
|
* 사원 첨부파일 업로드 (로컬 + GCS 듀얼 저장)
|
||||||
*/
|
*/
|
||||||
public function uploadFile(Request $request, int $id): JsonResponse
|
public function uploadFile(Request $request, int $id, GoogleCloudStorageService $gcs): JsonResponse
|
||||||
{
|
{
|
||||||
$employee = $this->employeeService->getEmployeeById($id);
|
$employee = $this->employeeService->getEmployeeById($id);
|
||||||
if (! $employee) {
|
if (! $employee) {
|
||||||
@@ -275,8 +276,18 @@ public function uploadFile(Request $request, int $id): JsonResponse
|
|||||||
|
|
||||||
foreach ($request->file('files') as $file) {
|
foreach ($request->file('files') as $file) {
|
||||||
$storedName = Str::random(40).'.'.$file->getClientOriginalExtension();
|
$storedName = Str::random(40).'.'.$file->getClientOriginalExtension();
|
||||||
$path = "tenants/{$tenantId}/employees/{$employee->id}";
|
$storagePath = "employees/{$tenantId}/{$employee->id}/{$storedName}";
|
||||||
$file->storeAs($path, $storedName, 'tenant');
|
|
||||||
|
// 로컬 저장
|
||||||
|
Storage::disk('tenant')->put($storagePath, file_get_contents($file));
|
||||||
|
|
||||||
|
// GCS 업로드
|
||||||
|
$gcsUri = null;
|
||||||
|
$gcsObjectName = null;
|
||||||
|
if ($gcs->isAvailable()) {
|
||||||
|
$gcsObjectName = $storagePath;
|
||||||
|
$gcsUri = $gcs->upload($file->getRealPath(), $gcsObjectName);
|
||||||
|
}
|
||||||
|
|
||||||
$fileRecord = File::create([
|
$fileRecord = File::create([
|
||||||
'tenant_id' => $tenantId,
|
'tenant_id' => $tenantId,
|
||||||
@@ -284,10 +295,12 @@ public function uploadFile(Request $request, int $id): JsonResponse
|
|||||||
'document_type' => 'employee_profile',
|
'document_type' => 'employee_profile',
|
||||||
'original_name' => $file->getClientOriginalName(),
|
'original_name' => $file->getClientOriginalName(),
|
||||||
'stored_name' => $storedName,
|
'stored_name' => $storedName,
|
||||||
'file_path' => $path.'/'.$storedName,
|
'file_path' => $storagePath,
|
||||||
'mime_type' => $file->getMimeType(),
|
'mime_type' => $file->getMimeType(),
|
||||||
'file_size' => $file->getSize(),
|
'file_size' => $file->getSize(),
|
||||||
'file_type' => strtolower($file->getClientOriginalExtension()),
|
'file_type' => strtolower($file->getClientOriginalExtension()),
|
||||||
|
'gcs_object_name' => $gcsObjectName,
|
||||||
|
'gcs_uri' => $gcsUri,
|
||||||
'uploaded_by' => auth()->id(),
|
'uploaded_by' => auth()->id(),
|
||||||
'created_by' => auth()->id(),
|
'created_by' => auth()->id(),
|
||||||
]);
|
]);
|
||||||
@@ -303,9 +316,9 @@ public function uploadFile(Request $request, int $id): JsonResponse
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 사원 첨부파일 삭제
|
* 사원 첨부파일 삭제 (GCS + 로컬 모두 삭제)
|
||||||
*/
|
*/
|
||||||
public function deleteFile(int $id, int $fileId): JsonResponse
|
public function deleteFile(int $id, int $fileId, GoogleCloudStorageService $gcs): JsonResponse
|
||||||
{
|
{
|
||||||
$tenantId = session('selected_tenant_id');
|
$tenantId = session('selected_tenant_id');
|
||||||
|
|
||||||
@@ -319,16 +332,27 @@ public function deleteFile(int $id, int $fileId): JsonResponse
|
|||||||
return response()->json(['success' => false, 'message' => '파일을 찾을 수 없습니다.'], 404);
|
return response()->json(['success' => false, 'message' => '파일을 찾을 수 없습니다.'], 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
Storage::disk('tenant')->delete($file->file_path);
|
// GCS 삭제
|
||||||
|
if ($gcs->isAvailable() && $file->gcs_object_name) {
|
||||||
|
$gcs->delete($file->gcs_object_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 로컬 삭제
|
||||||
|
if ($file->file_path && Storage::disk('tenant')->exists($file->file_path)) {
|
||||||
|
Storage::disk('tenant')->delete($file->file_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
$file->deleted_by = auth()->id();
|
||||||
|
$file->save();
|
||||||
$file->delete();
|
$file->delete();
|
||||||
|
|
||||||
return response()->json(['success' => true, 'message' => '파일이 삭제되었습니다.']);
|
return response()->json(['success' => true, 'message' => '파일이 삭제되었습니다.']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 사원 첨부파일 다운로드
|
* 사원 첨부파일 다운로드 (GCS Signed URL 우선, 로컬 폴백)
|
||||||
*/
|
*/
|
||||||
public function downloadFile(int $id, int $fileId)
|
public function downloadFile(int $id, int $fileId, GoogleCloudStorageService $gcs)
|
||||||
{
|
{
|
||||||
$tenantId = session('selected_tenant_id');
|
$tenantId = session('selected_tenant_id');
|
||||||
|
|
||||||
@@ -342,12 +366,21 @@ public function downloadFile(int $id, int $fileId)
|
|||||||
abort(404, '파일을 찾을 수 없습니다.');
|
abort(404, '파일을 찾을 수 없습니다.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$disk = Storage::disk('tenant');
|
// GCS Signed URL로 리다이렉트
|
||||||
if (! $disk->exists($file->file_path)) {
|
if ($gcs->isAvailable() && $file->gcs_object_name) {
|
||||||
abort(404, '파일이 서버에 존재하지 않습니다.');
|
$signedUrl = $gcs->getSignedUrl($file->gcs_object_name, 60);
|
||||||
|
if ($signedUrl) {
|
||||||
|
return redirect($signedUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $disk->download($file->file_path, $file->original_name);
|
// 로컬 폴백
|
||||||
|
$disk = Storage::disk('tenant');
|
||||||
|
if ($file->file_path && $disk->exists($file->file_path)) {
|
||||||
|
return $disk->download($file->file_path, $file->original_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
abort(404, '파일이 서버에 존재하지 않습니다.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user