Skip to content

Commit

Permalink
FEAT: 리뷰 수정 로직 변경
Browse files Browse the repository at this point in the history
<body>
- updateReview
  - RequestPart -> RequestBody 변경
  - update 진행 후 사용하지 않는 image 삭제하는 로직 추가

<footer>
- 관련: #186
  • Loading branch information
luke0408 committed Feb 29, 2024
1 parent 5526e54 commit c4b9a64
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
Expand Down Expand Up @@ -128,19 +129,21 @@ public ResponseDto<Void> deleteReview(@PathVariable Long reviewId) {

/* 리뷰 수정 */
@PutMapping("/{reviewId}")
public ResponseDto<Void> updateReview(@PathVariable Long reviewId,
@RequestPart(value = "files") List<MultipartFile> images,
@Valid @RequestPart(value = "key") UpdateReviewRequestDto request, BindingResult bindingResult) {
public ResponseDto<Void> updateReview(
@PathVariable Long reviewId,
@Valid @RequestBody UpdateReviewRequestDto request,
BindingResult bindingResult
) {
this.checkRequestValidation(bindingResult);
this.reviewService.checkReviewOwner(reviewId);
this.reviewService.updateReview(reviewId, request, images);
this.reviewService.updateReview(reviewId, request);
return ResponseDto.onSuccess(null);
}

@PostMapping("/image/{reviewId}")
public ResponseDto<String> getTemporaryReviewImageUrl(
@PathVariable Long reviewId,
@RequestPart(value = "file") MultipartFile images
@PathVariable Long reviewId,
@RequestPart(value = "file") MultipartFile images
) {
String imageUrl = this.reviewService.getTemporaryReviewImageUrl(reviewId, images);
return ResponseDto.onSuccess(imageUrl);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ public class UpdateReviewRequestDto {

private List<Long> specData; // specData id 리스트

private List<Integer> imageIndex; // 바꾸고자 하는 이미지의 인덱스
private List<String> imageList; // 이미지 리스트

@Builder
public UpdateReviewRequestDto(Category category, String productName, LocalDate boughtAt, String manufacturer,
Integer price, Integer storeName, String comparedProductName, String shortReview, Double starPoint,
String goodPoint, String badPoint, List<Long> specData, List<Integer> imageIndex) {
String goodPoint, String badPoint, List<Long> specData, List<String> imageList) {
this.category = category;
this.productName = productName;
this.boughtAt = boughtAt;
Expand All @@ -66,6 +66,6 @@ public UpdateReviewRequestDto(Category category, String productName, LocalDate b
this.goodPoint = goodPoint;
this.badPoint = badPoint;
this.specData = specData;
this.imageIndex = imageIndex;
this.imageList = imageList;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -414,20 +414,34 @@ private void checkUploadReviewImagesRequestValidation(List<MultipartFile> images
}

@Transactional
public void updateReview(Long reviewId, UpdateReviewRequestDto request, List<MultipartFile> images) {
public void updateReview(Long reviewId, UpdateReviewRequestDto request) {
Review review = this.findReviewById(reviewId);

// 1. 리뷰 데이터 업데이트
this.updateReviewData(request, review);

// 2. 리뷰 이미지 업데이트
List<Integer> targetImageIds = request.getImageIndex();
this.updateReviewImages(review, targetImageIds, images);
this.updateReviewImages(review, request.getImageList());

// 3. 리뷰 스펙 데이터 업데이트
List<ReviewSpecData> nowReviewSpecDataList = reviewSpecDataRepository.findAllByReview(review);
List<SpecData> newSpecDataList = this.specConnector.findAllSpecDataByIds(request.getSpecData());
this.updateReviewSpecData(review, nowReviewSpecDataList, newSpecDataList);

reviewRepository.save(review);

this.clearS3ReviewImage(review);
}

private void clearS3ReviewImage(Review review) {
List<String> s3ReviewImageUrls = this.getReviewImageUrls(review);
List<String> activeReviewImageUrls = review.getReviewImages().stream()
.map(ReviewImage::getImgUrl)
.collect(Collectors.toList());

s3ReviewImageUrls.stream()
.filter(s3ReviewImageUrl -> !activeReviewImageUrls.contains(s3ReviewImageUrl))
.forEach(s3Service::deleteImages);
}

private void updateReviewData(UpdateReviewRequestDto request, Review review) {
Expand All @@ -439,41 +453,14 @@ private void updateReviewData(UpdateReviewRequestDto request, Review review) {
review.updateReview(request, manufacturer);
}

private void updateReviewImages(Review review, List<Integer> targetImageIds, List<MultipartFile> images) {
/*
* 1. targetImageIds 가 null 일때,
* 1-1. images 도 null 이면 이미지 업데이트 없이 리턴
* 1-2. images 가 null 이 아니면 에러 리턴
* 2. targetImageIds 가 null 이 아닐때,
* 2-1. images 가 null 이면 에러 리턴
* 2-2. images 와 targetImageIds 의 길이가 다르면 에러 리턴
* 2-3. images 와 targetImageIds 의 길이가 같으면 이미지 업데이트 진행
* 3. 이미지 업데이트 진행시 (* targetImageIds 와 images 의 순서는 같음)
* 3-1. 현재 review image 에 해당하지 않는 targetImageId 는 insert
* 3-2. 현재 review image 에 해당하는 targetImageId 는 update
*/

if (targetImageIds.isEmpty() && images.isEmpty()) {
} else if (targetImageIds.size() == images.size()) {
List<ReviewImage> reviewImages = review.getReviewImages();

for (int i = 0; i < targetImageIds.size(); i++) {

int targetImageId = targetImageIds.get(i);
MultipartFile image = images.get(i);

if (reviewImages.stream().anyMatch(ri -> ri.getOrderNum() == targetImageId)) {
ReviewImage reviewImage = reviewImageRepository.findByReviewAndOrderNum(review, targetImageId);
s3Service.updateImage(image, reviewImage);
} else {
reviewImageRepository.save(s3Service.uploadImage(image, review, targetImageId));
}
}

} else {
throw new ReviewHandler(_REVIEW_UPDATE_IMAGE_ARGUMENT_ERROR);
}
private void updateReviewImages(Review review, List<String> imageList) {
List<ReviewImage> nowReviewImages = review.getReviewImages();
reviewImageRepository.deleteAll(nowReviewImages);

List<ReviewImage> newReviewImages = imageList.stream()
.map(image -> ReviewImage.createReviewImage(review, image, imageList.indexOf(image)))
.collect(Collectors.toList());
reviewImageRepository.saveAll(newReviewImages);
}

private void updateReviewSpecData(Review review, List<ReviewSpecData> nowReviewSpecDataList,
Expand Down Expand Up @@ -529,4 +516,8 @@ public void checkReviewOwner(Long reviewId) {
throw new ReviewHandler(_REVIEW_WRITER_IS_NOT_MATCH);
}
}

public List<String> getReviewImageUrls(Review review) {
return s3Service.getReviewImageUrlsInS3(review);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.example.betteriter.infra.s3;

import java.util.List;

import com.example.betteriter.fo_domain.review.domain.Review;
import com.example.betteriter.fo_domain.review.domain.ReviewImage;
import com.example.betteriter.fo_domain.user.domain.Users;
Expand All @@ -16,4 +18,6 @@ public interface ImageUploadService {
void deleteImages(String imageUrl);

String uploadTemporaryImage(MultipartFile image, Review review);

List<String> getReviewImageUrlsInS3(Review review);
}
25 changes: 25 additions & 0 deletions src/main/java/com/example/betteriter/infra/s3/S3Service.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@
import static com.example.betteriter.global.common.code.status.ErrorStatus.*;

import java.io.InputStream;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.amazonaws.SdkClientException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ListObjectsV2Request;
import com.amazonaws.services.s3.model.ListObjectsV2Result;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.example.betteriter.fo_domain.review.domain.Review;
import com.example.betteriter.fo_domain.review.domain.ReviewImage;
import com.example.betteriter.fo_domain.review.exception.ReviewHandler;
Expand Down Expand Up @@ -68,6 +73,26 @@ public String uploadTemporaryImage(MultipartFile image, Review review) {
return getImageUrl(image, key);
}

@Override
public List<String> getReviewImageUrlsInS3(Review review) {
log.info("1");
ListObjectsV2Request request = new ListObjectsV2Request()
.withBucketName(bucketName)
.withPrefix(FOLDER + "/" + review.getId().toString() + "/");

log.info("2");
ListObjectsV2Result result = s3Client.listObjectsV2(request);

log.info("3");
List<S3ObjectSummary> objects = result.getObjectSummaries();

log.info("4");
return objects.stream()
.map(S3ObjectSummary::getKey)
.map(this::getImageUrl)
.collect(Collectors.toList());
}

private static String getUserProfileImageKey(MultipartFile image, Users user) {
String originalFilename = getFilename(image);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ void updateReviewDataInSuccess() {
.goodPoint("goodPoint2")
.badPoint("badPoint2")
.specData(null)
.imageIndex(new ArrayList<>())
.imageList(new ArrayList<>())
.build();

List<MultipartFile> images = new ArrayList<>();
Expand All @@ -670,7 +670,7 @@ void updateReviewDataInSuccess() {
.willReturn(Optional.of(review));

// when
this.reviewService.updateReview(review.getId(), request, images);
this.reviewService.updateReview(review.getId(), request);

// then
verify(this.manufacturerConnector, times(1)).findManufacturerByName(anyString());
Expand Down Expand Up @@ -702,7 +702,7 @@ void updateReviewDataWithSpecDataInSuccess() {
.goodPoint("goodPoint2")
.badPoint("badPoint2")
.specData(List.of(1L, 3L))
.imageIndex(new ArrayList<>())
.imageList(new ArrayList<>())
.build();

List<MultipartFile> images = new ArrayList<>();
Expand All @@ -714,7 +714,7 @@ void updateReviewDataWithSpecDataInSuccess() {
.willReturn(Optional.of(review));

// when
this.reviewService.updateReview(review.getId(), request, images);
this.reviewService.updateReview(review.getId(), request);

// then
verify(this.manufacturerConnector, times(1)).findManufacturerByName(anyString());
Expand Down

0 comments on commit c4b9a64

Please sign in to comment.