feat:공사현장 사진대지 멀티행(N행) 사진 지원
- ConstructionSitePhotoRow 모델 추가 - 부모 모델에서 사진 컬럼 제거, rows() 관계 추가 - 서비스/컨트롤러에 행 추가/삭제 기능 추가 - 라우트를 행 기반 URL 구조로 변경 - 프론트엔드 멀티행 UI 전면 개편 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
use App\Helpers\AiTokenHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Juil\ConstructionSitePhoto;
|
||||
use App\Models\Juil\ConstructionSitePhotoRow;
|
||||
use App\Services\ConstructionSitePhotoService;
|
||||
use App\Services\GoogleCloudService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -40,7 +41,7 @@ public function list(Request $request): JsonResponse
|
||||
|
||||
public function show(int $id): JsonResponse
|
||||
{
|
||||
$photo = ConstructionSitePhoto::with('user')->find($id);
|
||||
$photo = ConstructionSitePhoto::with(['user', 'rows'])->find($id);
|
||||
|
||||
if (!$photo) {
|
||||
return response()->json([
|
||||
@@ -72,7 +73,7 @@ public function store(Request $request): JsonResponse
|
||||
], 201);
|
||||
}
|
||||
|
||||
public function uploadPhoto(Request $request, int $id): JsonResponse
|
||||
public function uploadPhoto(Request $request, int $id, int $rowId): JsonResponse
|
||||
{
|
||||
$photo = ConstructionSitePhoto::find($id);
|
||||
|
||||
@@ -83,12 +84,23 @@ public function uploadPhoto(Request $request, int $id): JsonResponse
|
||||
], 404);
|
||||
}
|
||||
|
||||
$row = ConstructionSitePhotoRow::where('id', $rowId)
|
||||
->where('construction_site_photo_id', $id)
|
||||
->first();
|
||||
|
||||
if (!$row) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '사진 행을 찾을 수 없습니다.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'type' => 'required|in:before,during,after',
|
||||
'photo' => 'required|image|mimes:jpeg,jpg,png,webp|max:10240',
|
||||
]);
|
||||
|
||||
$result = $this->service->uploadPhoto($photo, $request->file('photo'), $validated['type']);
|
||||
$result = $this->service->uploadPhoto($row, $request->file('photo'), $validated['type']);
|
||||
|
||||
if (!$result) {
|
||||
return response()->json([
|
||||
@@ -100,7 +112,7 @@ public function uploadPhoto(Request $request, int $id): JsonResponse
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => '사진이 업로드되었습니다.',
|
||||
'data' => $photo->fresh(),
|
||||
'data' => $photo->fresh()->load('rows'),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -132,7 +144,7 @@ public function update(Request $request, int $id): JsonResponse
|
||||
|
||||
public function destroy(int $id): JsonResponse
|
||||
{
|
||||
$photo = ConstructionSitePhoto::find($id);
|
||||
$photo = ConstructionSitePhoto::with('rows')->find($id);
|
||||
|
||||
if (!$photo) {
|
||||
return response()->json([
|
||||
@@ -149,7 +161,7 @@ public function destroy(int $id): JsonResponse
|
||||
]);
|
||||
}
|
||||
|
||||
public function deletePhoto(int $id, string $type): JsonResponse
|
||||
public function deletePhoto(int $id, int $rowId, string $type): JsonResponse
|
||||
{
|
||||
$photo = ConstructionSitePhoto::find($id);
|
||||
|
||||
@@ -160,6 +172,17 @@ public function deletePhoto(int $id, string $type): JsonResponse
|
||||
], 404);
|
||||
}
|
||||
|
||||
$row = ConstructionSitePhotoRow::where('id', $rowId)
|
||||
->where('construction_site_photo_id', $id)
|
||||
->first();
|
||||
|
||||
if (!$row) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '사진 행을 찾을 수 없습니다.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
if (!in_array($type, ['before', 'during', 'after'])) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
@@ -167,16 +190,16 @@ public function deletePhoto(int $id, string $type): JsonResponse
|
||||
], 422);
|
||||
}
|
||||
|
||||
$this->service->deletePhotoByType($photo, $type);
|
||||
$this->service->deletePhotoByType($row, $type);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => '사진이 삭제되었습니다.',
|
||||
'data' => $photo->fresh(),
|
||||
'data' => $photo->fresh()->load('rows'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function downloadPhoto(Request $request, int $id, string $type): Response|JsonResponse
|
||||
public function downloadPhoto(Request $request, int $id, int $rowId, string $type): Response|JsonResponse
|
||||
{
|
||||
$photo = ConstructionSitePhoto::find($id);
|
||||
|
||||
@@ -187,6 +210,17 @@ public function downloadPhoto(Request $request, int $id, string $type): Response
|
||||
], 404);
|
||||
}
|
||||
|
||||
$row = ConstructionSitePhotoRow::where('id', $rowId)
|
||||
->where('construction_site_photo_id', $id)
|
||||
->first();
|
||||
|
||||
if (!$row) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '사진 행을 찾을 수 없습니다.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
if (!in_array($type, ['before', 'during', 'after'])) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
@@ -194,7 +228,7 @@ public function downloadPhoto(Request $request, int $id, string $type): Response
|
||||
], 422);
|
||||
}
|
||||
|
||||
$path = $photo->{$type . '_photo_path'};
|
||||
$path = $row->{$type . '_photo_path'};
|
||||
|
||||
if (!$path) {
|
||||
return response()->json([
|
||||
@@ -235,6 +269,62 @@ public function downloadPhoto(Request $request, int $id, string $type): Response
|
||||
->header('Cache-Control', 'private, max-age=3600');
|
||||
}
|
||||
|
||||
public function addRow(int $id): JsonResponse
|
||||
{
|
||||
$photo = ConstructionSitePhoto::find($id);
|
||||
|
||||
if (!$photo) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '사진대지를 찾을 수 없습니다.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
$this->service->addRow($photo);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => '사진 행이 추가되었습니다.',
|
||||
'data' => $photo->fresh()->load('rows'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function deleteRow(int $id, int $rowId): JsonResponse
|
||||
{
|
||||
$photo = ConstructionSitePhoto::with('rows')->find($id);
|
||||
|
||||
if (!$photo) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '사진대지를 찾을 수 없습니다.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
if ($photo->rows->count() <= 1) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '최소 1개의 사진 행은 유지해야 합니다.',
|
||||
], 422);
|
||||
}
|
||||
|
||||
$row = $photo->rows->firstWhere('id', $rowId);
|
||||
|
||||
if (!$row) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '사진 행을 찾을 수 없습니다.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
$this->service->deleteRow($row);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => '사진 행이 삭제되었습니다.',
|
||||
'data' => $photo->fresh()->load('rows'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function logSttUsage(Request $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
|
||||
Reference in New Issue
Block a user