Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public class QReview extends EntityPathBase<Review> {

public final NumberPath<Long> id = createNumber("id", Long.class);

public final BooleanPath isDeleted = createBoolean("isDeleted");

public final ListPath<com.gongspot.project.domain.media.entity.Media, com.gongspot.project.domain.media.entity.QMedia> mediaList = this.<com.gongspot.project.domain.media.entity.Media, com.gongspot.project.domain.media.entity.QMedia>createList("mediaList", com.gongspot.project.domain.media.entity.Media.class, com.gongspot.project.domain.media.entity.QMedia.class, PathInits.DIRECT2);

public final ListPath<com.gongspot.project.common.enums.MoodEnum, EnumPath<com.gongspot.project.common.enums.MoodEnum>> mood = this.<com.gongspot.project.common.enums.MoodEnum, EnumPath<com.gongspot.project.common.enums.MoodEnum>>createList("mood", com.gongspot.project.common.enums.MoodEnum.class, EnumPath.class, PathInits.DIRECT2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public enum ErrorStatus implements BaseErrorCode {
REVIEW_NOT_FOUND(HttpStatus.NOT_FOUND, "REVIEW4001", "리뷰를 찾을 수 없습니다."),
REVIEW_ALREADY_EXISTS(HttpStatus.CONFLICT, "REVIEW4002", "이미 해당 장소에 리뷰를 작성했습니다."),
REVIEW_SAVE_FAIL(HttpStatus.BAD_REQUEST, "REVIEW4003", "리뷰 저장에 실패했습니다."),
UNAUTHORIZED_REVIEW_DELETION(HttpStatus.UNAUTHORIZED, "REVIEW4004", "본인의 리뷰만 삭제할 수 있습니다."),

// Media Error
MEDIA_NOT_FOUND(HttpStatus.NOT_FOUND, "MEDIA4001", "미디어를 찾을 수 없습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ public ApiResponse<ReviewResponseDTO.GetReviewListDTO> getReviewList(
@PathVariable("placeId") Long placeId,
@RequestParam(name = "page", defaultValue = "0") int page) {

ReviewResponseDTO.GetReviewListDTO result = reviewQueryService.getReviewList(placeId, page);
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Long userId = user.getId();

ReviewResponseDTO.GetReviewListDTO result = reviewQueryService.getReviewList(placeId, page, userId);
return ApiResponse.onSuccess(result);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
Expand Down Expand Up @@ -40,4 +41,22 @@ public ApiResponse<Void> createReview(
reviewCommandService.saveReview(userId, placeId, review, reviewPictures);
return ApiResponse.onSuccess();
}

@DeleteMapping("/admin/{reviewId}")
@PreAuthorize("hasRole('ROLE_ADMIN')")
@Operation(summary = "리뷰 삭제 (관리자)", description = "관리자가 리뷰를 삭제합니다.")
public ApiResponse<Void> deleteReviewByAdmin(@PathVariable("reviewId") Long reviewId) {
reviewCommandService.deleteReviewByAdmin(reviewId);
return ApiResponse.onSuccess();
}

@PatchMapping("/{reviewId}")
@PreAuthorize("isAuthenticated()")
@Operation(summary = "내 리뷰 삭제", description = "본인의 리뷰를 삭제합니다.")
public ApiResponse<Void> deleteMyReview(@PathVariable("reviewId") Long reviewId) {
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Long userId = user.getId();
reviewCommandService.softDeleteReview(userId, reviewId);
return ApiResponse.onSuccess();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@

public class ReviewConverter {

public static ReviewResponseDTO.GetReviewDTO toGetReviewDTO(Review review, List<Media> reviewMediaList) {
public static ReviewResponseDTO.GetReviewDTO toGetReviewDTO(Review review, List<Media> reviewMediaList, Long currentUserId) {

List<String> imageUrls = new ArrayList<>();
if (reviewMediaList != null && !reviewMediaList.isEmpty()) {
imageUrls = reviewMediaList.stream()
.map(Media::getUrl)
.collect(Collectors.toList());
}
Boolean isMyReview = review.getUser().getId().equals(currentUserId);

return ReviewResponseDTO.GetReviewDTO.builder()
.reviewId(review.getId())
Expand All @@ -38,6 +39,7 @@ public static ReviewResponseDTO.GetReviewDTO toGetReviewDTO(Review review, List<
.rating(review.getRating())
.reviewImageUrl(imageUrls)
.content(review.getContent())
.isMyReview(isMyReview)
.build();
}

Expand Down Expand Up @@ -166,15 +168,16 @@ public static ReviewResponseDTO.GetReviewListDTO toGetReviewListDTO(
Double averageRating,
List<ReviewResponseDTO.CategoryCountDTO> categoryList,
Map<Integer, Long> ratingCounts,
int totalReviewCount
int totalReviewCount,
Long currentUserId
) {

Map<Long, List<Media>> reviewMediaMap = mediaList.stream()
.collect(Collectors.groupingBy(media -> media.getReview().getId()));


List<ReviewResponseDTO.GetReviewDTO> reviewDTOs = reviews.stream()
.map(review -> toGetReviewDTO(review, reviewMediaMap.getOrDefault(review.getId(), new ArrayList<>())))
.map(review -> toGetReviewDTO(review, reviewMediaMap.getOrDefault(review.getId(), new ArrayList<>()),currentUserId))
.collect(Collectors.toList());

return ReviewResponseDTO.GetReviewListDTO.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public static class GetReviewDTO {
Integer rating;
List<String> reviewImageUrl;
String content;
Boolean isMyReview;
}

@Builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.List;

@Getter
@Setter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
Expand Down Expand Up @@ -58,6 +59,9 @@ public class Review extends BaseEntity {
@Column(name = "content", length = 500)
private String content;

@Column(name = "is_deleted")
private Boolean isDeleted = false;

@OneToMany(mappedBy = "review", cascade = CascadeType.ALL)
private List<Media> mediaList;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@

public interface ReviewCommandService {
void saveReview(Long userId, Long placeId, ReviewRequestDTO.ReviewRegisterDTO reqDTO, List<MultipartFile> reviewPictures);
void deleteReviewByAdmin(Long reviewId);
void softDeleteReview(Long userId, Long reviewId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
Expand Down Expand Up @@ -85,4 +86,25 @@ public void saveReview(Long userId, Long placeId, ReviewRequestDTO.ReviewRegiste
throw new BusinessException(ErrorStatus.REVIEW_SAVE_FAIL);
}
}

@Transactional
public void deleteReviewByAdmin(Long reviewId) {
Review review = reviewRepository.findById(reviewId)
.orElseThrow(() -> new BusinessException(ErrorStatus.REVIEW_NOT_FOUND));

reviewRepository.delete(review);
}

@Transactional
public void softDeleteReview(Long userId, Long reviewId) {
Review review = reviewRepository.findById(reviewId)
.orElseThrow(() -> new BusinessException(ErrorStatus.REVIEW_NOT_FOUND));

if (!review.getUser().getId().equals(userId)) {
throw new BusinessException(ErrorStatus.UNAUTHORIZED_REVIEW_DELETION);
}

review.setIsDeleted(true);
reviewRepository.save(review);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

public interface ReviewQueryService {
ReviewResponseDTO.CongestionListDTO getCongestionList(Long userId, Long placeId, int page);
ReviewResponseDTO.GetReviewListDTO getReviewList(Long placeId, int page);
ReviewResponseDTO.GetReviewListDTO getReviewList(Long placeId, int page,Long currentUserId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public ReviewResponseDTO.CongestionListDTO getCongestionList(Long userId, Long p
}

@Override
public ReviewResponseDTO.GetReviewListDTO getReviewList(Long placeId, int page) {
public ReviewResponseDTO.GetReviewListDTO getReviewList(Long placeId, int page, Long currentUserId) {
Place place = placeRepository.findById(placeId)
.orElseThrow(() -> new BusinessException(ErrorStatus.PLACE_NOT_FOUND));

Expand Down Expand Up @@ -73,7 +73,8 @@ public ReviewResponseDTO.GetReviewListDTO getReviewList(Long placeId, int page)
averageRating,
categoryList,
ratingCounts,
allReviews.size()
allReviews.size(),
currentUserId
);
}

Expand Down