refactor: [equipment] 사진 업로드를 R2(FileStorageSystem) 기반으로 전환

- GCS 스텁 코드를 Cloudflare R2 기반 실제 파일 업로드로 교체
- File 모델 import를 Boards\File에서 Commons\File로 수정
- StoreEquipmentPhotoRequest FormRequest 추가 (파일 검증)
- 다중 파일 업로드 지원 (최대 10장 제한)
- softDeleteFile 패턴 적용 (삭제 시 soft delete)
- ItemsFileController 패턴 준용 (R2 저장, 랜덤 파일명)
This commit is contained in:
김보곤
2026-03-12 13:45:15 +09:00
parent 723b5a8e1a
commit 2d32faa9b5
4 changed files with 150 additions and 23 deletions

View File

@@ -4,9 +4,9 @@
use App\Helpers\ApiResponse;
use App\Http\Controllers\Controller;
use App\Http\Requests\Equipment\StoreEquipmentPhotoRequest;
use App\Services\Equipment\EquipmentPhotoService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class EquipmentPhotoController extends Controller
{
@@ -20,10 +20,10 @@ public function index(int $id): JsonResponse
);
}
public function store(Request $request, int $id): JsonResponse
public function store(StoreEquipmentPhotoRequest $request, int $id): JsonResponse
{
return ApiResponse::handle(
fn () => $this->service->store($id, $request->all()),
fn () => $this->service->store($id, $request->file('files')),
__('message.equipment.photo_uploaded')
);
}

View File

@@ -0,0 +1,53 @@
<?php
namespace App\Http\Requests\Equipment;
use App\Models\Commons\File;
use Illuminate\Foundation\Http\FormRequest;
class StoreEquipmentPhotoRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
$equipmentId = $this->route('id');
$currentCount = File::where('document_id', $equipmentId)
->where('document_type', 'equipment')
->whereNull('deleted_at')
->count();
$maxFiles = 10 - $currentCount;
return [
'files' => ['required', 'array', 'min:1', "max:{$maxFiles}"],
'files.*' => [
'required',
'file',
'mimes:jpg,jpeg,png,gif,bmp,webp',
'max:10240', // 10MB
],
];
}
public function attributes(): array
{
return [
'files' => '사진 파일',
'files.*' => '사진 파일',
];
}
public function messages(): array
{
return [
'files.required' => __('error.file.required'),
'files.max' => __('error.equipment.photo_limit_exceeded'),
'files.*.mimes' => __('error.file.invalid_type'),
'files.*.max' => __('error.file.size_exceeded'),
];
}
}