From 76ad18486945498b3774a22da0c65854fef3a9c4 Mon Sep 17 00:00:00 2001 From: dayeon <99ekdus@naver.com> Date: Wed, 4 Jun 2025 18:49:51 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20ReviewService=EC=97=90=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=82=AD=EC=A0=9C=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80=20#42?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pteam/review/service/ReviewService.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/demo/pteam/review/service/ReviewService.java b/src/main/java/com/demo/pteam/review/service/ReviewService.java index 16a6d133..82507cf3 100644 --- a/src/main/java/com/demo/pteam/review/service/ReviewService.java +++ b/src/main/java/com/demo/pteam/review/service/ReviewService.java @@ -17,6 +17,7 @@ import com.demo.pteam.schedule.repository.entity.ScheduleEntity; import jakarta.persistence.EntityNotFoundException; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -28,7 +29,7 @@ import java.util.List; import java.util.stream.Collectors; - +@Slf4j @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -223,6 +224,35 @@ public ReviewImageUploadResponseDto uploadReviewImage(MultipartFile multipartFil } } + /** + * 리뷰 임시 이미지 삭제 + * @param imageId 삭제할 이미지 ID + * @param userId 현재 인증된 사용자 ID + */ + @Transactional + public void deleteReviewImage(Long imageId, Long userId) { + ReviewImageEntity imageEntity = reviewImageRepository.findById(imageId) + .orElseThrow(() -> new ApiException(ReviewErrorCode.IMAGE_NOT_FOUND)); + + if (!imageEntity.getUserId().equals(userId)) { + throw new ApiException(ReviewErrorCode.NOT_IMAGE_OWNER); + } + + if (imageEntity.getReview() != null) { + throw new ApiException(ReviewErrorCode.IMAGE_ALREADY_LINKED); + } + + // 파일 스토리지에서 삭제 + try { + fileStorageService.deleteFile(imageEntity.getImageUrl()); + } catch (IOException e) { + log.error("Failed to delete image file: {}", e.getMessage()); + } + + // DB에서 삭제 + reviewImageRepository.delete(imageEntity); + } + // 메서드 From efe5717146a5eba394db2cd5b852125dc0551ef8 Mon Sep 17 00:00:00 2001 From: dayeon <99ekdus@naver.com> Date: Wed, 4 Jun 2025 18:50:24 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20ReviewController=EC=97=90=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=82=AD=EC=A0=9C=20=EC=97=94?= =?UTF-8?q?=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=B6=94=EA=B0=80=20#42?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/com/demo/pteam/review/controller/ReviewController.java b/src/main/java/com/demo/pteam/review/controller/ReviewController.java index a0a70f0d..77548d12 100644 --- a/src/main/java/com/demo/pteam/review/controller/ReviewController.java +++ b/src/main/java/com/demo/pteam/review/controller/ReviewController.java @@ -106,4 +106,20 @@ public ResponseEntity> uploadReviewIma ApiResponse apiResponse = ApiResponse.success("이미지가 성공적으로 업로드되었습니다.", responseDto); return ResponseEntity.status(HttpStatus.CREATED).body(apiResponse); } + + @DeleteMapping("/images/{imageId}") + public ResponseEntity> deleteReviewImage( + @PathVariable Long imageId, + @AuthenticationPrincipal UserDetails userDetails) { + + // TODO + // 현재 인증된 사용자 ID 가져오기 + // Long userId = ((CustomUserDetails) userDetails).getId(); + Long userId = null; + + reviewService.deleteReviewImage(imageId, userId); + + ApiResponse apiResponse = ApiResponse.success("이미지가 성공적으로 삭제되었습니다.", null); + return ResponseEntity.ok(apiResponse); + } } From 72a52269a24d20e1c1bfc655f653861e7e19f112 Mon Sep 17 00:00:00 2001 From: dayeon <99ekdus@naver.com> Date: Fri, 11 Jul 2025 18:27:47 +0900 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=EB=A6=AC=EB=B7=B0=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EC=8B=9C=20=EC=97=B0=EA=B2=B0=EB=90=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=99=84=EC=A0=84=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?#38=20-=20=EC=8B=A4=EC=A0=9C=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20-=20DB=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=A0=88=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/demo/pteam/review/service/ReviewService.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/demo/pteam/review/service/ReviewService.java b/src/main/java/com/demo/pteam/review/service/ReviewService.java index 82507cf3..d7c3bf75 100644 --- a/src/main/java/com/demo/pteam/review/service/ReviewService.java +++ b/src/main/java/com/demo/pteam/review/service/ReviewService.java @@ -171,10 +171,16 @@ public void deleteReview(Long reviewId, Long userId) { throw new ApiException(ReviewErrorCode.NOT_REVIEW_OWNER); } - // 리뷰 이미지 연결 해제 List images = reviewImageRepository.findByReviewId(reviewId); - images.forEach(image -> image.updateReview(null)); + images.forEach(image -> { + try { + fileStorageService.deleteFile(image.getImageUrl()); + } catch (IOException e) { + log.error("Failed to delete image file: {}", e.getMessage()); + } + }); + reviewImageRepository.deleteAll(images); reviewRepository.delete(reviewEntity); }