Skip to content

Commit 4bdc1e0

Browse files
authored
feat(be): 상점 리뷰 리스트 조회 로직 (#145)
* feat: getStoreReviews 서비스 구현 # Conflicts: # backend/src/main/java/com/deliveranything/domain/review/controller/ApiV1ReviewController.java # Conflicts: # backend/src/main/java/com/deliveranything/domain/review/service/ReviewService.java * feat: getStoreReviews 토대 구현 * feat: 쿼리 dsl 구현 * refactor: 쿼리 로직 개선 * fix: 충돌 해결 & Delivery 로직 내 리뷰 파일명 수정
1 parent 2d583e2 commit 4bdc1e0

File tree

10 files changed

+227
-72
lines changed

10 files changed

+227
-72
lines changed

backend/src/main/java/com/deliveranything/domain/delivery/controller/DeliveryController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import com.deliveranything.domain.delivery.service.DeliveryService;
66
import com.deliveranything.domain.review.dto.ReviewRatingAndListResponseDto;
77
import com.deliveranything.domain.review.dto.ReviewResponse;
8-
import com.deliveranything.domain.review.enums.ReviewSortType;
8+
import com.deliveranything.domain.review.enums.MyReviewSortType;
99
import com.deliveranything.domain.review.service.ReviewService;
1010
import com.deliveranything.global.common.ApiResponse;
1111
import io.swagger.v3.oas.annotations.Operation;
@@ -53,7 +53,7 @@ public ResponseEntity<ApiResponse<Void>> updateDeliveryArea(
5353
@GetMapping("/reviews")
5454
public ResponseEntity<ApiResponse<ReviewRatingAndListResponseDto>> getReviews(
5555
@RequestParam Long userId, // profileId 고려 -> 인증객체
56-
@RequestParam(required = false, defaultValue = "LATEST") ReviewSortType sort,
56+
@RequestParam(required = false, defaultValue = "LATEST") MyReviewSortType sort,
5757
@RequestParam(required = false) String cursor,
5858
@RequestParam(required = false, defaultValue = "10") Integer size
5959
) {

backend/src/main/java/com/deliveranything/domain/review/controller/ApiV1ReviewController.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
import com.deliveranything.domain.review.dto.ReviewLikeResponse;
66
import com.deliveranything.domain.review.dto.ReviewResponse;
77
import com.deliveranything.domain.review.dto.ReviewUpdateRequest;
8-
import com.deliveranything.domain.review.enums.ReviewSortType;
98
import com.deliveranything.domain.review.service.ReviewService;
109
import com.deliveranything.global.common.ApiResponse;
11-
import com.deliveranything.global.common.CursorPageResponse;
1210
import io.swagger.v3.oas.annotations.Operation;
1311
import io.swagger.v3.oas.annotations.tags.Tag;
1412
import lombok.RequiredArgsConstructor;
@@ -21,7 +19,6 @@
2119
import org.springframework.web.bind.annotation.PostMapping;
2220
import org.springframework.web.bind.annotation.RequestBody;
2321
import org.springframework.web.bind.annotation.RequestMapping;
24-
import org.springframework.web.bind.annotation.RequestParam;
2522
import org.springframework.web.bind.annotation.RestController;
2623

2724
@RestController
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.deliveranything.domain.review.dto;
22

3-
import com.deliveranything.domain.review.enums.ReviewSortType;
3+
import com.deliveranything.domain.review.enums.MyReviewSortType;
44

55
public record ReviewListRequest(
6-
ReviewSortType sort,
6+
MyReviewSortType sort,
77
String cursor,
88
Integer size
99
) {}

backend/src/main/java/com/deliveranything/domain/review/dto/ReviewResponse.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ public record ReviewResponse(
1313
ReviewTargetType targetType,
1414
Long targetId,
1515
LocalDateTime createdAt,
16-
LocalDateTime updatedAt
16+
LocalDateTime updatedAt,
17+
Long likeCount
1718
// , UserResponse
1819
) {
1920

20-
public static ReviewResponse from(Review review, List<String> photoUrls) {
21+
public static ReviewResponse from(Review review, List<String> photoUrls, Long likeCount) {
2122
return new ReviewResponse(
2223
review.getId(),
2324
review.getRating(),
@@ -26,7 +27,8 @@ public static ReviewResponse from(Review review, List<String> photoUrls) {
2627
review.getTargetType(),
2728
review.getTargetId(),
2829
review.getCreatedAt(),
29-
review.getUpdatedAt()
30+
review.getUpdatedAt(),
31+
likeCount
3032
//userResponse
3133
);
3234
}

backend/src/main/java/com/deliveranything/domain/review/enums/ReviewSortType.java renamed to backend/src/main/java/com/deliveranything/domain/review/enums/MyReviewSortType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.deliveranything.domain.review.enums;
22

3-
public enum ReviewSortType {
3+
public enum MyReviewSortType {
44
LATEST, // 최신순
55
OLDEST, // 오래된순
66
RATING_DESC, // 별점 높은순
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.deliveranything.domain.review.enums;
2+
3+
public enum StoreReviewSortType {
4+
LATEST, // 최신순
5+
OLDEST, // 오래된순
6+
RATING_DESC, // 별점 높은순
7+
RATING_ASC, // 별점 낮은순
8+
LIKED_DESC // 좋아요 높은순
9+
}
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
package com.deliveranything.domain.review.repository;
22

33
import com.deliveranything.domain.review.entity.Review;
4-
import com.deliveranything.domain.review.enums.ReviewSortType;
4+
import com.deliveranything.domain.review.enums.MyReviewSortType;
5+
import com.deliveranything.domain.review.enums.StoreReviewSortType;
56
import com.deliveranything.domain.user.entity.User;
67
import com.deliveranything.domain.user.enums.ProfileType;
78
import java.util.List;
89

910
public interface ReviewRepositoryCustom {
1011

11-
List<Review> findReviewsByProfile(User user, ProfileType profileType, ReviewSortType sort,
12+
List<Review> findReviewsByProfile(User user, ProfileType profileType, MyReviewSortType sort,
1213
String[] cursor, int size);
1314

1415
void updateLikeCount(Long reviewId, int likeCount);
16+
17+
List<Review> getStoreReviews(Long storeId, StoreReviewSortType sort, String[] decodedCursor, int size);
1518
}

backend/src/main/java/com/deliveranything/domain/review/repository/ReviewRepositoryImpl.java

Lines changed: 91 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
import com.deliveranything.domain.review.entity.QReview;
44
import com.deliveranything.domain.review.entity.Review;
5-
import com.deliveranything.domain.review.enums.ReviewSortType;
5+
import com.deliveranything.domain.review.enums.MyReviewSortType;
6+
import com.deliveranything.domain.review.enums.StoreReviewSortType;
67
import com.deliveranything.domain.store.store.entity.QStore;
78
import com.deliveranything.domain.user.entity.User;
89
import com.deliveranything.domain.user.entity.profile.QRiderProfile;
@@ -11,7 +12,6 @@
1112
import com.querydsl.core.types.dsl.BooleanExpression;
1213
import com.querydsl.jpa.impl.JPAQueryFactory;
1314
import java.time.LocalDateTime;
14-
import java.util.ArrayList;
1515
import java.util.List;
1616
import lombok.RequiredArgsConstructor;
1717

@@ -21,7 +21,8 @@ public class ReviewRepositoryImpl implements ReviewRepositoryCustom {
2121
private final JPAQueryFactory queryFactory;
2222

2323
@Override
24-
public List<Review> findReviewsByProfile(User user, ProfileType profileType, ReviewSortType sort,
24+
public List<Review> findReviewsByProfile(User user, ProfileType profileType,
25+
MyReviewSortType sort,
2526
String[] cursor, int pageSize) {
2627
QReview review = QReview.review;
2728
QRiderProfile riderProfile = QRiderProfile.riderProfile;
@@ -70,4 +71,91 @@ public void updateLikeCount(Long reviewId, int likeCount) {
7071
.where(review.id.eq(reviewId))
7172
.execute();
7273
}
74+
75+
@Override
76+
public List<Review> getStoreReviews(Long storeId, StoreReviewSortType sort,
77+
String[] decodedCursor, int pageSize) {
78+
QReview review = QReview.review;
79+
80+
// 커서 값 초기화
81+
Long cursorId = null;
82+
Integer cursorValue = null; // rating 또는 likeCount 기준
83+
LocalDateTime cursorCreatedAt = null;
84+
85+
// decodedCursor가 존재하면 값 파싱
86+
if (decodedCursor != null && decodedCursor.length > 0) {
87+
switch (sort) {
88+
case LATEST:
89+
case OLDEST:
90+
cursorCreatedAt = LocalDateTime.parse(decodedCursor[0]);
91+
cursorId = Long.parseLong(decodedCursor[1]);
92+
break;
93+
case RATING_DESC:
94+
case RATING_ASC:
95+
cursorValue = Integer.parseInt(decodedCursor[0]);
96+
cursorId = Long.parseLong(decodedCursor[1]);
97+
break;
98+
case LIKED_DESC:
99+
cursorValue = Integer.parseInt(decodedCursor[0]);
100+
cursorId = Long.parseLong(decodedCursor[1]);
101+
break;
102+
}
103+
}
104+
105+
// 커서 조건 생성
106+
BooleanExpression cursorCondition = null;
107+
if (cursorId != null) {
108+
cursorCondition = switch (sort) {
109+
case LATEST -> review.createdAt.lt(cursorCreatedAt)
110+
.or(review.createdAt.eq(cursorCreatedAt)
111+
.and(review.id.lt(cursorId)));
112+
case OLDEST -> review.createdAt.gt(cursorCreatedAt)
113+
.or(review.createdAt.eq(cursorCreatedAt)
114+
.and(review.id.gt(cursorId)));
115+
case RATING_DESC -> review.rating.lt(cursorValue)
116+
.or(review.rating.eq(cursorValue)
117+
.and(review.id.lt(cursorId)));
118+
case RATING_ASC -> review.rating.gt(cursorValue)
119+
.or(review.rating.eq(cursorValue)
120+
.and(review.id.gt(cursorId)));
121+
case LIKED_DESC -> review.likeCount.lt(cursorValue)
122+
.or(review.likeCount.eq(cursorValue)
123+
.and(review.id.lt(cursorId)));
124+
};
125+
}
126+
127+
// 정렬 기준 생성 (복합 정렬)
128+
OrderSpecifier<?> primary = null, secondary = null;
129+
130+
switch (sort) {
131+
case LATEST:
132+
primary = review.createdAt.desc();
133+
secondary = review.id.desc();
134+
break;
135+
case OLDEST:
136+
primary = review.createdAt.asc();
137+
secondary = review.id.asc();
138+
break;
139+
case RATING_DESC:
140+
primary = review.rating.desc();
141+
secondary = review.id.desc();
142+
break;
143+
case RATING_ASC:
144+
primary = review.rating.asc();
145+
secondary = review.id.asc();
146+
break;
147+
case LIKED_DESC:
148+
primary = review.likeCount.desc();
149+
secondary = review.id.desc();
150+
break;
151+
}
152+
153+
// 실제 조회
154+
return queryFactory
155+
.selectFrom(review)
156+
.where(review.targetId.eq(storeId), cursorCondition)
157+
.orderBy(primary, secondary)
158+
.limit(pageSize + 1)
159+
.fetch();
160+
}
73161
}

0 commit comments

Comments
 (0)