From 999478734f75247280a305417765654d332c17f6 Mon Sep 17 00:00:00 2001 From: momnpa333 Date: Sun, 2 Jun 2024 02:44:36 +0900 Subject: [PATCH] =?UTF-8?q?[Feat]:=20=EA=B5=AC=ED=98=84=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #25 --- .../review/ChallengeReviewController.java | 11 +++++++ .../review/ChallengeReviewRes.java | 21 ++++++++++++ .../challenge/ChallengeCommand.java | 7 ++++ .../challenge/ChallengeService.java | 11 +++++++ .../review/ChallengeReviewModel.java | 32 +++++++++++++++++++ .../review/ChallengeReviewReader.java | 2 ++ .../ChallengeReviewReaderImpl.java | 9 ++++++ 7 files changed, 93 insertions(+) diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/challengegroup/review/ChallengeReviewController.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/challengegroup/review/ChallengeReviewController.java index c3fdd9e..e377654 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/challengegroup/review/ChallengeReviewController.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/challengegroup/review/ChallengeReviewController.java @@ -11,6 +11,7 @@ import org.haedal.zzansuni.controller.user.UserRes; import org.haedal.zzansuni.core.api.ApiResponse; import org.haedal.zzansuni.domain.challengegroup.challenge.ChallengeService; +import org.haedal.zzansuni.domain.challengegroup.review.ChallengeReviewModel; import org.haedal.zzansuni.domain.challengegroup.review.ChallengeReviewModel.ChallengeReviewWithChallenge; import org.haedal.zzansuni.domain.challengegroup.review.ChallengeReviewModel.ChallengeReviewWithUserInfo; import org.haedal.zzansuni.global.jwt.JwtUser; @@ -78,4 +79,14 @@ public ApiResponse challengeReviewCreate( return ApiResponse.success(response, "챌린지 리뷰 작성에 성공하였습니다."); } + @ResponseStatus(HttpStatus.OK) + @Operation(summary = "챌린지 그룹별 리뷰 평점 조회", description = "챌린지 그룹별 리뷰 평점 조회") + @GetMapping("/api/challengeGroups/{challengeGroupId}/reviews/score") + public ApiResponse getChallengeGroupReviewScore( + @PathVariable Long challengeGroupId + ) { + var response = ChallengeReviewRes.ChallengeReviewScoreResponse.from( + challengeService.getChallengeGroupReviewScore(challengeGroupId)); + return ApiResponse.success(response, "챌린지 그룹별 리뷰 평점 조회에 성공하였습니다."); + } } diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/challengegroup/review/ChallengeReviewRes.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/challengegroup/review/ChallengeReviewRes.java index 4708ad5..4a211f3 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/challengegroup/review/ChallengeReviewRes.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/challengegroup/review/ChallengeReviewRes.java @@ -1,7 +1,9 @@ package org.haedal.zzansuni.controller.challengegroup.review; +import java.util.Map; import lombok.Builder; import org.haedal.zzansuni.controller.user.UserRes; +import org.haedal.zzansuni.domain.challengegroup.review.ChallengeReviewModel; import org.haedal.zzansuni.domain.challengegroup.review.ChallengeReviewModel.ChallengeReviewWithChallenge; import org.haedal.zzansuni.domain.challengegroup.review.ChallengeReviewModel.ChallengeReviewWithUserInfo; @@ -54,4 +56,23 @@ public static ChallengeReviewWithChalengeDto from( .build(); } } + + @Builder + public record ChallengeReviewScoreResponse( + Float averageRating, + /** + * key: rating, value: count + */ + Map ratingCount + ) { + + public static ChallengeReviewScoreResponse from( + ChallengeReviewModel.ChallengeReviewScore challengeReviewScore) { + return ChallengeReviewScoreResponse.builder() + .averageRating(challengeReviewScore.averageRating()) + .ratingCount(challengeReviewScore.ratingCount()) + .build(); + } + } + } diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/challenge/ChallengeCommand.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/challenge/ChallengeCommand.java index b8b513d..f01641c 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/challenge/ChallengeCommand.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/challenge/ChallengeCommand.java @@ -1,5 +1,7 @@ package org.haedal.zzansuni.domain.challengegroup.challenge; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.Builder; @@ -36,6 +38,7 @@ public VerificationCreate afterUpload(String imageUrl) { @Getter @Builder public static class VerificationCreate extends SelfValidating { + @NotBlank(message = "내용은 필수입니다.") private final String content; private final String imageUrl; @@ -55,6 +58,8 @@ public static class ReviewCreate extends SelfValidating { private final String content; @NotNull(message = "평점은 필수입니다.") + @Min(1) + @Max(5) private final Integer rating; public ReviewCreate(String content, Integer rating) { @@ -62,6 +67,8 @@ public ReviewCreate(String content, Integer rating) { this.rating = rating; this.validateSelf(); } + + } } diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/challenge/ChallengeService.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/challenge/ChallengeService.java index 1c17b6f..ba0257f 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/challenge/ChallengeService.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/challenge/ChallengeService.java @@ -107,4 +107,15 @@ public Page getChallengeReviews(Pageable pageable) return challengeReviewPage.map(ChallengeReviewWithUserInfo::from); } + + /** + * 챌린지 그룹 리뷰 평점 가져오기 + */ + @Transactional(readOnly = true) + public ChallengeReviewModel.ChallengeReviewScore getChallengeGroupReviewScore( + Long challengeGroupId) { + List challengeReviews = challengeReviewReader.findByChallengeGroupId( + challengeGroupId); + return ChallengeReviewModel.ChallengeReviewScore.of(challengeReviews); + } } diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/review/ChallengeReviewModel.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/review/ChallengeReviewModel.java index fd34510..0c2f8c3 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/review/ChallengeReviewModel.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/review/ChallengeReviewModel.java @@ -1,5 +1,8 @@ package org.haedal.zzansuni.domain.challengegroup.review; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import lombok.Builder; import org.haedal.zzansuni.domain.user.UserModel; @@ -55,4 +58,33 @@ public static ChallengeReviewWithChallenge from(ChallengeReview challengeReview) } + @Builder + public record ChallengeReviewScore( + Float averageRating, + Map ratingCount + ) { + + public static ChallengeReviewScore of(List challengeReviews) { + // key: rating, value: count + // rating은 1,2,3,4,5 이며 value는 각각의 rating이 몇개인지 count + Map ratingCount = new HashMap<>(); + for (int i = 1; i <= 5; i++) { + ratingCount.put(i, 0); + } + challengeReviews.forEach(challengeReview -> { + var rating = challengeReview.getRating(); + ratingCount.put(rating, ratingCount.get(rating) + 1); + }); + + var averageRating = challengeReviews.stream() + .mapToInt(ChallengeReview::getRating) + .average() + .orElse(0); + return ChallengeReviewScore.builder() + .averageRating((float) averageRating) + .ratingCount(ratingCount) + .build(); + } + } + } diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/review/ChallengeReviewReader.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/review/ChallengeReviewReader.java index 554754e..84689a4 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/review/ChallengeReviewReader.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/challengegroup/review/ChallengeReviewReader.java @@ -19,4 +19,6 @@ Page getChallengeReviewPageByChallengeGroupId(Long challengeGro Page getChallengeReviewPage(Pageable pageable); + List findByChallengeGroupId(Long challengeGroupId); + } diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/infrastructure/challengegroup/challengereview/ChallengeReviewReaderImpl.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/infrastructure/challengegroup/challengereview/ChallengeReviewReaderImpl.java index 51ce56e..388c10b 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/infrastructure/challengegroup/challengereview/ChallengeReviewReaderImpl.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/infrastructure/challengegroup/challengereview/ChallengeReviewReaderImpl.java @@ -106,4 +106,13 @@ public Page getChallengeReviewPage(Pageable pageable) { return new PageImpl<>(challengeReviews, pageable, count == null ? 0 : count); } + + @Override + public List findByChallengeGroupId(Long challengeGroupId) { + return queryFactory + .select(QChallengeReview.challengeReview) + .from(QChallengeReview.challengeReview) + .where(QChallengeReview.challengeReview.challengeGroupId.eq(challengeGroupId)) + .fetch(); + } }