Skip to content

Commit

Permalink
Merge pull request #107 from cvs-go/feature#82
Browse files Browse the repository at this point in the history
특정 사용자가 작성한 리뷰 목록 조회 API 추가
  • Loading branch information
chaewss authored Jan 11, 2024
2 parents 6a31e1c + 8b48e27 commit 82e4371
Show file tree
Hide file tree
Showing 12 changed files with 387 additions and 12 deletions.
18 changes: 18 additions & 0 deletions src/docs/asciidoc/api-doc.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,24 @@ include::{snippets}/user-controller-test/respond_200_when_read_bookmarked_produc
==== Sample Response
include::{snippets}/user-controller-test/respond_200_when_read_bookmarked_product_list_successfully/http-response.adoc[]

=== 1-11. 특정 사용자의 리뷰 목록 조회
==== Request Fields
include::{snippets}/user-controller-test/respond_200_when_read_user_review_list_successfully/request-fields.adoc[]
==== 정렬 기준 항목
|===
| sortBy 값 | 정렬 기준 | 비고

| LATEST | 최신순 | 정렬 기준 미지정시 기본값
| LIKE | 좋아요순 |
| RATING | 별점순 |
|===
==== Sample Request
include::{snippets}/user-controller-test/respond_200_when_read_user_review_list_successfully/http-request.adoc[]
==== Response Fields
include::{snippets}/user-controller-test/respond_200_when_read_user_review_list_successfully/response-fields.adoc[]
==== Sample Response
include::{snippets}/user-controller-test/respond_200_when_read_user_review_list_successfully/http-response.adoc[]

== 2. 인증
=== 2-1. 로그인
==== Request Fields
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/cvsgo/config/WebConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ public void addInterceptors(InterceptorRegistry registry) {
.addPathPatterns("/**")
.excludePathPatterns("/", "/docs/**", "/*.ico", "/api/auth/login", "/api/users",
"/api/tags", "/api/users/emails/*/exists", "/api/users/nicknames/*/exists",
"/api/products", "/api/products/*", "/api/products/*/tags");
"/api/products", "/api/products/*", "/api/products/*/tags", "/api/users/*/reviews");
}
}
13 changes: 13 additions & 0 deletions src/main/java/com/cvsgo/controller/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
import com.cvsgo.dto.SuccessResponse;
import com.cvsgo.dto.product.ReadProductResponseDto;
import com.cvsgo.dto.product.ReadUserProductRequestDto;
import com.cvsgo.dto.review.ReadUserReviewResponseDto;
import com.cvsgo.dto.review.ReviewSortBy;
import com.cvsgo.dto.user.SignUpRequestDto;
import com.cvsgo.dto.user.SignUpResponseDto;
import com.cvsgo.dto.user.UpdateUserRequestDto;
import com.cvsgo.dto.user.UserResponseDto;
import com.cvsgo.entity.User;
import com.cvsgo.service.ProductService;
import com.cvsgo.service.ReviewService;
import com.cvsgo.service.UserService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
Expand All @@ -33,8 +36,11 @@
public class UserController {

private final UserService userService;

private final ProductService productService;

private final ReviewService reviewService;

@PostMapping("/users")
@ResponseStatus(HttpStatus.CREATED)
public SuccessResponse<SignUpResponseDto> register(
Expand Down Expand Up @@ -98,4 +104,11 @@ public SuccessResponse<Page<ReadProductResponseDto>> readBookmarkedProductList(
productService.readBookmarkedProductList(userId, request, pageable));
}

@GetMapping("/users/{userId}/reviews")
public SuccessResponse<Page<ReadUserReviewResponseDto>> readUserReviewList(@LoginUser User loginUser,
@PathVariable Long userId, ReviewSortBy sortBy, Pageable pageable) {
return SuccessResponse.from(
reviewService.readUserReviewList(loginUser, userId, sortBy, pageable));
}

}
2 changes: 0 additions & 2 deletions src/main/java/com/cvsgo/dto/review/ReadReviewRequestDto.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.cvsgo.dto.review;

import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import java.util.List;
import lombok.Getter;

Expand Down
61 changes: 61 additions & 0 deletions src/main/java/com/cvsgo/dto/review/ReadUserReviewQueryDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.cvsgo.dto.review;

import com.cvsgo.entity.ProductBookmark;
import com.cvsgo.entity.ReviewLike;
import com.querydsl.core.annotations.QueryProjection;
import java.time.LocalDateTime;
import lombok.Getter;

@Getter
public class ReadUserReviewQueryDto {

private final Long reviewId;

private final Long productId;

private final String productName;

private final String manufacturerName;

private final String productImageUrl;

private final Long reviewerId;

private final String reviewerNickname;

private final String reviewerProfileImageUrl;

private final Long likeCount;

private final Integer rating;

private final String reviewContent;

private final Boolean isReviewLiked;

private final Boolean isProductBookmarked;

private final LocalDateTime createdAt;

@QueryProjection
public ReadUserReviewQueryDto(Long reviewId, Long productId, String productName,
String manufacturerName, String productImageUrl, Long reviewerId, String reviewerNickname,
String reviewerProfileImageUrl, Long likeCount, Integer rating,
String reviewContent, LocalDateTime createdAt, ReviewLike reviewLike,
ProductBookmark productBookmark) {
this.reviewId = reviewId;
this.productId = productId;
this.productName = productName;
this.manufacturerName = manufacturerName;
this.productImageUrl = productImageUrl;
this.reviewerId = reviewerId;
this.reviewerNickname = reviewerNickname;
this.reviewerProfileImageUrl = reviewerProfileImageUrl;
this.likeCount = likeCount;
this.rating = rating;
this.reviewContent = reviewContent;
this.createdAt = createdAt;
this.isReviewLiked = reviewLike != null;
this.isProductBookmarked = productBookmark != null;
}
}
86 changes: 86 additions & 0 deletions src/main/java/com/cvsgo/dto/review/ReadUserReviewResponseDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.cvsgo.dto.review;

import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDateTime;
import java.util.List;
import lombok.Builder;
import lombok.Getter;

@Getter
public class ReadUserReviewResponseDto {

private final Long productId;

private final String productName;

private final String productManufacturer;

private final String productImageUrl;

private final Long reviewId;

private final Long reviewerId;

private final String reviewerNickname;

private final String reviewerProfileImageUrl;

private final Long reviewLikeCount;

private final Integer reviewRating;

private final String reviewContent;

private final Boolean isReviewLiked;

private final Boolean isProductBookmarked;

private final List<String> reviewImageUrls;

@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "Asia/Seoul")
private final LocalDateTime createdAt;

@Builder
public ReadUserReviewResponseDto(Long productId, String productName, String productManufacturer,
String productImageUrl, Long reviewId, Long reviewerId, String reviewerNickname,
String reviewerProfileImageUrl,
Long reviewLikeCount, Integer reviewRating, String reviewContent, Boolean isReviewLiked,
Boolean isProductBookmarked, List<String> reviewImageUrls, LocalDateTime createdAt) {
this.productId = productId;
this.productName = productName;
this.productManufacturer = productManufacturer;
this.productImageUrl = productImageUrl;
this.reviewId = reviewId;
this.reviewerId = reviewerId;
this.reviewerNickname = reviewerNickname;
this.reviewerProfileImageUrl = reviewerProfileImageUrl;
this.reviewLikeCount = reviewLikeCount;
this.reviewRating = reviewRating;
this.reviewContent = reviewContent;
this.isReviewLiked = isReviewLiked;
this.isProductBookmarked = isProductBookmarked;
this.reviewImageUrls = reviewImageUrls;
this.createdAt = createdAt;
}

public static ReadUserReviewResponseDto of(ReadUserReviewQueryDto readUserReviewQueryDto,
List<String> reviewImageUrls) {
return ReadUserReviewResponseDto.builder()
.productName(readUserReviewQueryDto.getProductName())
.productId(readUserReviewQueryDto.getProductId())
.reviewContent(readUserReviewQueryDto.getReviewContent())
.productImageUrl(readUserReviewQueryDto.getProductImageUrl())
.productManufacturer(readUserReviewQueryDto.getManufacturerName())
.reviewId(readUserReviewQueryDto.getReviewId())
.reviewerId(readUserReviewQueryDto.getReviewerId())
.reviewerNickname(readUserReviewQueryDto.getReviewerNickname())
.reviewerProfileImageUrl(readUserReviewQueryDto.getReviewerProfileImageUrl())
.reviewRating(readUserReviewQueryDto.getRating())
.reviewLikeCount(readUserReviewQueryDto.getLikeCount())
.createdAt(readUserReviewQueryDto.getCreatedAt())
.isProductBookmarked(readUserReviewQueryDto.getIsProductBookmarked())
.isReviewLiked(readUserReviewQueryDto.getIsReviewLiked())
.reviewImageUrls(reviewImageUrls)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.cvsgo.dto.review.ReadProductReviewRequestDto;
import com.cvsgo.dto.review.ReadReviewQueryDto;
import com.cvsgo.dto.review.ReadReviewRequestDto;
import com.cvsgo.dto.review.ReadUserReviewQueryDto;
import com.cvsgo.dto.review.ReviewSortBy;
import com.cvsgo.entity.User;
import java.util.List;
import org.springframework.data.domain.Pageable;
Expand All @@ -18,6 +20,11 @@ List<ReadReviewQueryDto> findAllByFilter(User loginUser, ReadReviewRequestDto fi
List<ReadProductReviewQueryDto> findAllByProductIdAndFilter(User loginUser, Long productId,
ReadProductReviewRequestDto filter, Pageable pageable);

List<ReadUserReviewQueryDto> findAllByUser(User loginUser, User reviewer, ReviewSortBy sortBy,
Pageable pageable);

Long countByProductIdAndFilter(Long productId, ReadProductReviewRequestDto filter);

Long countByUser(User user);

}
45 changes: 45 additions & 0 deletions src/main/java/com/cvsgo/repository/ReviewCustomRepositoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@

import com.cvsgo.dto.review.QReadProductReviewQueryDto;
import com.cvsgo.dto.review.QReadReviewQueryDto;
import com.cvsgo.dto.review.QReadUserReviewQueryDto;
import com.cvsgo.dto.review.ReadProductReviewQueryDto;
import com.cvsgo.dto.review.ReadProductReviewRequestDto;
import com.cvsgo.dto.review.ReadReviewQueryDto;
import com.cvsgo.dto.review.ReadUserReviewQueryDto;
import com.cvsgo.dto.review.ReviewSortBy;
import com.cvsgo.dto.review.ReadReviewRequestDto;
import com.cvsgo.entity.User;
Expand Down Expand Up @@ -106,6 +108,38 @@ public List<ReadProductReviewQueryDto> findAllByProductIdAndFilter(User loginUse
.fetch();
}

public List<ReadUserReviewQueryDto> findAllByUser(User loginUser, User reviewer,
ReviewSortBy sortBy, Pageable pageable) {
return queryFactory.select(new QReadUserReviewQueryDto(
review.id,
product.id,
product.name,
product.manufacturer.name,
product.imageUrl,
review.user.id,
review.user.nickname,
review.user.profileImageUrl,
review.likeCount,
review.rating,
review.content,
review.createdAt,
reviewLike,
productBookmark))
.from(review)
.join(user).on(user.eq(review.user))
.join(product).on(review.product.eq(product))
.leftJoin(reviewLike).on(reviewLike.review.eq(review).and(reviewLikeUserEq(reviewer)))
.leftJoin(productBookmark)
.on(productBookmark.product.eq(review.product).and(productBookmarkUserEq(loginUser)))
.where(
review.user.eq(reviewer)
)
.orderBy(sortBy(sortBy))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
}

public Long countByProductIdAndFilter(Long productId, ReadProductReviewRequestDto filter) {
return queryFactory.select(review.count())
.from(review)
Expand All @@ -119,6 +153,17 @@ public Long countByProductIdAndFilter(Long productId, ReadProductReviewRequestDt
.fetchOne();
}

public Long countByUser(User reviewer) {
return queryFactory.select(review.count())
.from(review)
.join(user).on(user.eq(review.user))
.join(product).on(review.product.eq(product))
.where(
review.user.eq(reviewer)
)
.fetchOne();
}

private OrderSpecifier<?> sortBy(ReviewSortBy sortBy) {
return sortBy != null ?
switch (sortBy) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/cvsgo/repository/ReviewRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public interface ReviewRepository extends JpaRepository<Review, Long>, ReviewCus

boolean existsByProductAndUser(Product product, User user);

long countByUser(User user);
Long countByUser(User user);

@Lock(LockModeType.OPTIMISTIC)
@Query(value = "select p from Review p where p.id = :id")
Expand Down
Loading

0 comments on commit 82e4371

Please sign in to comment.