From 49285c789ac97f4382ba21d6e438f883da1e6eb2 Mon Sep 17 00:00:00 2001 From: oosedus Date: Mon, 29 Jul 2024 21:53:53 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=ED=9B=84=EA=B8=B0=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/review/ReviewController.java | 43 ++++++++++- .../dto/review/request/SaveReviewRequest.java | 24 ++++++ .../review/response/SaveReviewResponse.java | 68 +++++++++++++++++ .../service/review/ReviewService.java | 75 ++++++++++++++++++- 4 files changed, 205 insertions(+), 5 deletions(-) create mode 100644 src/main/java/likelion/MZConnent/dto/review/request/SaveReviewRequest.java create mode 100644 src/main/java/likelion/MZConnent/dto/review/response/SaveReviewResponse.java diff --git a/src/main/java/likelion/MZConnent/api/review/ReviewController.java b/src/main/java/likelion/MZConnent/api/review/ReviewController.java index 19b3930..7832ef3 100644 --- a/src/main/java/likelion/MZConnent/api/review/ReviewController.java +++ b/src/main/java/likelion/MZConnent/api/review/ReviewController.java @@ -1,16 +1,25 @@ package likelion.MZConnent.api.review; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import likelion.MZConnent.dto.paging.response.PageContentResponse; +import likelion.MZConnent.dto.review.request.SaveReviewRequest; import likelion.MZConnent.dto.review.response.ReviewsSimpleResponse; +import likelion.MZConnent.dto.review.response.SaveReviewResponse; +import likelion.MZConnent.jwt.principle.UserPrinciple; import likelion.MZConnent.service.review.ReviewService; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.PageRequest; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; @RestController @RequiredArgsConstructor @@ -23,4 +32,32 @@ ResponseEntity getReviewSimpleList(@RequestParam(required = PageContentResponse response = reviewService.getReviewsSimpleList(keyword, page); return ResponseEntity.ok(response); } + + @PostMapping(value="/api/reviews/culture/{cultureId}", consumes = {"multipart/form-data"}) + public ResponseEntity saveReview( + @AuthenticationPrincipal UserPrinciple userPrinciple, + @RequestPart("info") String info, + @RequestPart(value = "reviewImage1", required = true) MultipartFile reviewImage1, + @RequestPart(value = "reviewImage2", required = false) MultipartFile reviewImage2, + @RequestPart(value = "reviewImage3", required = false) MultipartFile reviewImage3, + @RequestPart(value = "reviewImage4", required = false) MultipartFile reviewImage4, + @PathVariable Long cultureId) throws JsonProcessingException { + + try { + ObjectMapper objectMapper = new ObjectMapper(); + SaveReviewRequest request = objectMapper.readValue(info, SaveReviewRequest.class); + + List images = new ArrayList<>(); + if (reviewImage1 != null) images.add(reviewImage1); + if (reviewImage2 != null) images.add(reviewImage2); + if (reviewImage3 != null) images.add(reviewImage3); + if (reviewImage4 != null) images.add(reviewImage4); + + SaveReviewResponse response = reviewService.createReview(userPrinciple.getEmail(), request, images, cultureId); + return ResponseEntity.ok(response); + } catch (IOException e) { + log.error("리뷰 저장 실패", e); + return ResponseEntity.status(500).body(null); + } + } } diff --git a/src/main/java/likelion/MZConnent/dto/review/request/SaveReviewRequest.java b/src/main/java/likelion/MZConnent/dto/review/request/SaveReviewRequest.java new file mode 100644 index 0000000..57a9a32 --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/review/request/SaveReviewRequest.java @@ -0,0 +1,24 @@ +package likelion.MZConnent.dto.review.request; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@Slf4j +@Getter +@NoArgsConstructor +public class SaveReviewRequest { + private String title; + private String content; + + @Builder + public SaveReviewRequest(String title, String content, List reviewImageUrls) { + this.title = title; + this.content = content; + } +} diff --git a/src/main/java/likelion/MZConnent/dto/review/response/SaveReviewResponse.java b/src/main/java/likelion/MZConnent/dto/review/response/SaveReviewResponse.java new file mode 100644 index 0000000..b857d79 --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/review/response/SaveReviewResponse.java @@ -0,0 +1,68 @@ +package likelion.MZConnent.dto.review.response; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.time.LocalDateTime; +import java.util.List; + +@Slf4j +@Getter +@NoArgsConstructor +public class SaveReviewResponse { + private Long reviewId; + private ReviewerDto reviewer; + private CultureDto culture; + private String title; + private String reviewImageUrl1; + private String reviewImageUrl2; + private String reviewImageUrl3; + private String reviewImageUrl4; + private LocalDateTime createdDate; + private int likeCount; + + @Builder + public SaveReviewResponse(Long reviewId, ReviewerDto reviewer, CultureDto culture, String title, String reviewImageUrl1, String reviewImageUrl2, String reviewImageUrl3, String reviewImageUrl4, LocalDateTime createdDate, int likeCount) { + this.reviewId = reviewId; + this.reviewer = reviewer; + this.culture = culture; + this.title = title; + this.reviewImageUrl1 = reviewImageUrl1; + this.reviewImageUrl2 = reviewImageUrl2; + this.reviewImageUrl3 = reviewImageUrl3; + this.reviewImageUrl4 = reviewImageUrl4; + this.createdDate = createdDate; + this.likeCount = likeCount; + } + + @Getter + @NoArgsConstructor + public static class ReviewerDto { + private Long userId; + private String username; + private String profileImage; + + @Builder + public ReviewerDto(Long userId, String username, String profileImage) { + this.userId = userId; + this.username = username; + this.profileImage = profileImage; + } + } + + @Getter + @NoArgsConstructor + public static class CultureDto { + private Long cultureId; + private String cultureName; + + @Builder + public CultureDto(Long cultureId, String cultureName) { + this.cultureId = cultureId; + this.cultureName = cultureName; + } + } + +} diff --git a/src/main/java/likelion/MZConnent/service/review/ReviewService.java b/src/main/java/likelion/MZConnent/service/review/ReviewService.java index 1aafd07..a9b597b 100644 --- a/src/main/java/likelion/MZConnent/service/review/ReviewService.java +++ b/src/main/java/likelion/MZConnent/service/review/ReviewService.java @@ -1,9 +1,16 @@ package likelion.MZConnent.service.review; +import likelion.MZConnent.domain.culture.Culture; +import likelion.MZConnent.domain.member.Member; import likelion.MZConnent.domain.review.Review; import likelion.MZConnent.dto.paging.response.PageContentResponse; +import likelion.MZConnent.dto.review.request.SaveReviewRequest; import likelion.MZConnent.dto.review.response.ReviewsSimpleResponse; +import likelion.MZConnent.dto.review.response.SaveReviewResponse; +import likelion.MZConnent.repository.culture.CultureRepository; +import likelion.MZConnent.repository.member.MemberRepository; import likelion.MZConnent.repository.review.ReviewRepository; +import likelion.MZConnent.service.image.S3ImageService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -11,17 +18,22 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; -import java.util.Collections; +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import java.util.stream.Stream; @Service @Slf4j @RequiredArgsConstructor public class ReviewService { private final ReviewRepository reviewRepository; + private final S3ImageService s3ImageService; + private final MemberRepository memberRepository; + private final CultureRepository cultureRepository; private final int PAGE_SIZE = 6; public PageContentResponse getReviewsSimpleList(String keyword, int page) { @@ -43,4 +55,63 @@ public PageContentResponse getReviewsSimpleList(String ke .build(); } + + public SaveReviewResponse createReview(String email, SaveReviewRequest request, List images, Long cultureId) throws IOException { + List imageUrls = uploadImages(images); + + Member member = memberRepository.findByEmail(email).orElseThrow(() -> new IllegalArgumentException("회원 정보를 찾을 수 없습니다.")); + Culture culture = cultureRepository.findById(cultureId).orElseThrow(() -> new IllegalArgumentException("문화 정보를 찾을 수 없습니다.")); + + Review review = buildReview(request, imageUrls, member, culture); + review = reviewRepository.save(review); + + return buildSaveReviewResponse(review, member, culture); + } + + private List uploadImages(List images) throws IOException { + List imageUrls = new ArrayList<>(); + for (MultipartFile image : images) { + String imageUrl = s3ImageService.upload(image, "reviews"); + imageUrls.add(imageUrl); + } + return imageUrls; + } + + private Review buildReview(SaveReviewRequest request, List imageUrls, Member member, Culture culture) { + return Review.builder() + .title(request.getTitle()) + .content(request.getContent()) + .reviewImageUrl1(imageUrls.size() > 0 ? imageUrls.get(0) : null) + .reviewImageUrl2(imageUrls.size() > 1 ? imageUrls.get(1) : null) + .reviewImageUrl3(imageUrls.size() > 2 ? imageUrls.get(2) : null) + .reviewImageUrl4(imageUrls.size() > 3 ? imageUrls.get(3) : null) + .createdDate(LocalDateTime.now()) + .likeCount(0) + .commentCount(0) + .culture(culture) + .member(member) + .build(); + } + + private SaveReviewResponse buildSaveReviewResponse(Review review, Member member, Culture culture) { + return SaveReviewResponse.builder() + .reviewId(review.getReviewId()) + .reviewer(SaveReviewResponse.ReviewerDto.builder() + .userId(member.getId()) + .username(member.getUsername()) + .profileImage(member.getProfileImageUrl()) + .build()) + .culture(SaveReviewResponse.CultureDto.builder() + .cultureId(culture.getCultureId()) + .cultureName(culture.getName()) + .build()) + .title(review.getTitle()) + .reviewImageUrl1(review.getReviewImageUrl1()) + .reviewImageUrl2(review.getReviewImageUrl2()) + .reviewImageUrl3(review.getReviewImageUrl3()) + .reviewImageUrl4(review.getReviewImageUrl4()) + .createdDate(review.getCreatedDate()) + .likeCount(review.getLikeCount()) + .build(); + } } From 0d493a6efcc2417790d8d5070fea915084db3ba9 Mon Sep 17 00:00:00 2001 From: oosedus Date: Mon, 29 Jul 2024 21:56:30 +0900 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20=EB=AA=A8=EC=9E=84=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=8B=9C=20=EB=AC=B8=ED=99=94=EC=97=90=20clubCount=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/likelion/MZConnent/domain/culture/Culture.java | 2 ++ src/main/java/likelion/MZConnent/service/club/ClubService.java | 1 + 2 files changed, 3 insertions(+) diff --git a/src/main/java/likelion/MZConnent/domain/culture/Culture.java b/src/main/java/likelion/MZConnent/domain/culture/Culture.java index 464cce3..622eca1 100644 --- a/src/main/java/likelion/MZConnent/domain/culture/Culture.java +++ b/src/main/java/likelion/MZConnent/domain/culture/Culture.java @@ -8,11 +8,13 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import java.util.List; @Entity @Getter +@Setter @NoArgsConstructor public class Culture { @Id diff --git a/src/main/java/likelion/MZConnent/service/club/ClubService.java b/src/main/java/likelion/MZConnent/service/club/ClubService.java index 77d5e34..131f899 100644 --- a/src/main/java/likelion/MZConnent/service/club/ClubService.java +++ b/src/main/java/likelion/MZConnent/service/club/ClubService.java @@ -32,6 +32,7 @@ public class ClubService { public CreateClubResponse createClub(CreateClubRequest request, Member member) { Culture culture = cultureRepository.findById(request.getCultureId()).orElseThrow(() -> new IllegalArgumentException("존재하지 않는 문화입니다.")); + culture.setClubCount(culture.getClubCount() + 1); RegionCategory region = regionCategoryRepository.findById(request.getRegionId()).orElseThrow(() -> new IllegalArgumentException("존재하지 않는 지역입니다.")); Club club = Club.builder() From 44e8aca7081c6a598be20634086021326d55df23 Mon Sep 17 00:00:00 2001 From: oosedus Date: Mon, 29 Jul 2024 23:29:23 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20=EB=82=98=EC=9D=98=20=EB=AA=A8?= =?UTF-8?q?=EC=9E=84=20=EA=B0=84=EB=8B=A8=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MZConnent/api/club/ClubController.java | 3 -- .../MZConnent/api/club/MyClubController.java | 25 +++++++++ .../api/review/ReviewController.java | 2 - .../club/response/MyClubSimpleResponse.java | 43 ++++++++++++++++ .../MZConnent/service/club/MyClubService.java | 51 +++++++++++++++++++ 5 files changed, 119 insertions(+), 5 deletions(-) create mode 100644 src/main/java/likelion/MZConnent/api/club/MyClubController.java create mode 100644 src/main/java/likelion/MZConnent/dto/club/response/MyClubSimpleResponse.java create mode 100644 src/main/java/likelion/MZConnent/service/club/MyClubService.java diff --git a/src/main/java/likelion/MZConnent/api/club/ClubController.java b/src/main/java/likelion/MZConnent/api/club/ClubController.java index 6157065..4900a97 100644 --- a/src/main/java/likelion/MZConnent/api/club/ClubController.java +++ b/src/main/java/likelion/MZConnent/api/club/ClubController.java @@ -12,14 +12,11 @@ import likelion.MZConnent.service.club.RegionCategoryService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -import org.springframework.data.web.PageableDefault; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; diff --git a/src/main/java/likelion/MZConnent/api/club/MyClubController.java b/src/main/java/likelion/MZConnent/api/club/MyClubController.java new file mode 100644 index 0000000..194b866 --- /dev/null +++ b/src/main/java/likelion/MZConnent/api/club/MyClubController.java @@ -0,0 +1,25 @@ +package likelion.MZConnent.api.club; + +import likelion.MZConnent.dto.club.response.MyClubSimpleResponse; +import likelion.MZConnent.jwt.principle.UserPrinciple; +import likelion.MZConnent.service.club.MyClubService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RequiredArgsConstructor +@RestController +public class MyClubController { + private final MyClubService myClubService; + + @GetMapping("/api/users/clubs") + public ResponseEntity getMyClubs(@AuthenticationPrincipal UserPrinciple userPrinciple) { + MyClubSimpleResponse response = myClubService.getMyClubs(userPrinciple.getEmail()); + return ResponseEntity.ok(response); + } + +} diff --git a/src/main/java/likelion/MZConnent/api/review/ReviewController.java b/src/main/java/likelion/MZConnent/api/review/ReviewController.java index 7832ef3..d1d488d 100644 --- a/src/main/java/likelion/MZConnent/api/review/ReviewController.java +++ b/src/main/java/likelion/MZConnent/api/review/ReviewController.java @@ -8,10 +8,8 @@ import likelion.MZConnent.dto.review.response.SaveReviewResponse; import likelion.MZConnent.jwt.principle.UserPrinciple; import likelion.MZConnent.service.review.ReviewService; -import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.PageRequest; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; diff --git a/src/main/java/likelion/MZConnent/dto/club/response/MyClubSimpleResponse.java b/src/main/java/likelion/MZConnent/dto/club/response/MyClubSimpleResponse.java new file mode 100644 index 0000000..fd7f8ce --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/club/response/MyClubSimpleResponse.java @@ -0,0 +1,43 @@ +package likelion.MZConnent.dto.club.response; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.time.LocalDate; +import java.util.List; + +@Slf4j +@Getter +@NoArgsConstructor +public class MyClubSimpleResponse { + private List myClubs; + + @Builder + public MyClubSimpleResponse(List myClubs) { + this.myClubs = myClubs; + } + + @Getter + @NoArgsConstructor + public static class MyClubSimpleDto { + private Long clubId; + private String title; + private String cultureName; + private LocalDate meetingDate; + private int currentParticipant; + private int maxParticipant; + + @Builder + public MyClubSimpleDto(Long clubId, String title, String cultureName, LocalDate meetingDate, int currentParticipant, int maxParticipant) { + this.clubId = clubId; + this.title = title; + this.cultureName = cultureName; + this.meetingDate = meetingDate; + this.currentParticipant = currentParticipant; + this.maxParticipant = maxParticipant; + } + + } +} diff --git a/src/main/java/likelion/MZConnent/service/club/MyClubService.java b/src/main/java/likelion/MZConnent/service/club/MyClubService.java new file mode 100644 index 0000000..5189f5e --- /dev/null +++ b/src/main/java/likelion/MZConnent/service/club/MyClubService.java @@ -0,0 +1,51 @@ +package likelion.MZConnent.service.club; + +import likelion.MZConnent.domain.club.Club; +import likelion.MZConnent.domain.member.Member; +import likelion.MZConnent.dto.club.response.ClubSimpleResponse; +import likelion.MZConnent.dto.club.response.MyClubSimpleResponse; +import likelion.MZConnent.repository.member.MemberRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +@Slf4j +public class MyClubService { + private final MemberRepository memberRepository; + + public MyClubSimpleResponse getMyClubs(String email) { + Member member = memberRepository.findByEmail(email) + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 사용자입니다.")); + List clubList = getClubsByMember(member); + + List myClubs = clubList.stream() + .map(this::convertToDto) + .collect(Collectors.toList()); + + return MyClubSimpleResponse.builder() + .myClubs(myClubs) + .build(); + } + + private List getClubsByMember(Member member) { + return member.getClubMembers().stream() + .map(cm -> cm.getClub()) + .collect(Collectors.toList()); + } + + private MyClubSimpleResponse.MyClubSimpleDto convertToDto(Club club) { + return MyClubSimpleResponse.MyClubSimpleDto.builder() + .clubId(club.getClubId()) + .title(club.getTitle()) + .cultureName(club.getCulture().getName()) + .meetingDate(club.getMeetingDate()) + .currentParticipant(club.getClubMembers().size()) + .maxParticipant(club.getMaxParticipant()) + .build(); + } +} From be6f81e758e472a10a140708962a612c051d5622 Mon Sep 17 00:00:00 2001 From: oosedus Date: Tue, 30 Jul 2024 00:25:03 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20=EB=82=98=EC=9D=98=20=EB=AA=A8?= =?UTF-8?q?=EC=9E=84=20=EC=83=81=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MZConnent/api/club/MyClubController.java | 10 +++ .../club/response/MyClubDetailResponse.java | 71 +++++++++++++++++++ .../review/response/SaveReviewResponse.java | 8 +-- .../MZConnent/service/club/MyClubService.java | 67 +++++++++++++++-- .../service/review/ReviewService.java | 2 +- 5 files changed, 148 insertions(+), 10 deletions(-) create mode 100644 src/main/java/likelion/MZConnent/dto/club/response/MyClubDetailResponse.java diff --git a/src/main/java/likelion/MZConnent/api/club/MyClubController.java b/src/main/java/likelion/MZConnent/api/club/MyClubController.java index 194b866..d93d926 100644 --- a/src/main/java/likelion/MZConnent/api/club/MyClubController.java +++ b/src/main/java/likelion/MZConnent/api/club/MyClubController.java @@ -1,5 +1,6 @@ package likelion.MZConnent.api.club; +import likelion.MZConnent.dto.club.response.MyClubDetailResponse; import likelion.MZConnent.dto.club.response.MyClubSimpleResponse; import likelion.MZConnent.jwt.principle.UserPrinciple; import likelion.MZConnent.service.club.MyClubService; @@ -8,6 +9,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @Slf4j @@ -22,4 +25,11 @@ public ResponseEntity getMyClubs(@AuthenticationPrincipal return ResponseEntity.ok(response); } + @GetMapping("/api/users/clubs/{clubId}") + public ResponseEntity getMyClubDetail(@AuthenticationPrincipal UserPrinciple userPrinciple, @PathVariable Long clubId) { + MyClubDetailResponse response = myClubService.getMyClubDetail(userPrinciple.getEmail(), clubId); + return ResponseEntity.ok(response); + } + + } diff --git a/src/main/java/likelion/MZConnent/dto/club/response/MyClubDetailResponse.java b/src/main/java/likelion/MZConnent/dto/club/response/MyClubDetailResponse.java new file mode 100644 index 0000000..e421164 --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/club/response/MyClubDetailResponse.java @@ -0,0 +1,71 @@ +package likelion.MZConnent.dto.club.response; + +import likelion.MZConnent.domain.club.ClubRole; +import likelion.MZConnent.domain.member.Age; +import likelion.MZConnent.domain.member.Gender; +import likelion.MZConnent.dto.club.SelfIntroductionDto; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.util.List; + +@Getter +@NoArgsConstructor +public class MyClubDetailResponse { + private Long clubId; + private String title; + private LocalDate meetingDate; + private String content; + private int currentParticipant; + private MyClubCultureDto culture; + private List members; + + @Builder + public MyClubDetailResponse(Long clubId, String title, LocalDate meetingDate, String content, int currentParticipant, MyClubCultureDto culture, List members) { + this.clubId = clubId; + this.title = title; + this.meetingDate = meetingDate; + this.content = content; + this.currentParticipant = currentParticipant; + this.culture = culture; + this.members = members; + } + + @Getter + @NoArgsConstructor + public static class MyClubCultureDto { + private Long cultureId; + private String name; + + @Builder + public MyClubCultureDto(Long cultureId, String name) { + this.cultureId = cultureId; + this.name = name; + } + } + + @Getter + @NoArgsConstructor + public static class MyClubMemberDto { + private Long userId; + private String username; + private String profileImageUrl; + private Age age; + private Gender gender; + private ClubRole role; + private List selfIntroductions; + + @Builder + public MyClubMemberDto(Long userId, String username, String profileImageUrl, Age age, Gender gender, ClubRole role, List selfIntroductions) { + this.userId = userId; + this.username = username; + this.profileImageUrl = profileImageUrl; + this.age = age; + this.gender = gender; + this.role = role; + this.selfIntroductions = selfIntroductions; + } + } +} diff --git a/src/main/java/likelion/MZConnent/dto/review/response/SaveReviewResponse.java b/src/main/java/likelion/MZConnent/dto/review/response/SaveReviewResponse.java index b857d79..f181259 100644 --- a/src/main/java/likelion/MZConnent/dto/review/response/SaveReviewResponse.java +++ b/src/main/java/likelion/MZConnent/dto/review/response/SaveReviewResponse.java @@ -14,7 +14,7 @@ public class SaveReviewResponse { private Long reviewId; private ReviewerDto reviewer; - private CultureDto culture; + private ReviewCultureDto culture; private String title; private String reviewImageUrl1; private String reviewImageUrl2; @@ -24,7 +24,7 @@ public class SaveReviewResponse { private int likeCount; @Builder - public SaveReviewResponse(Long reviewId, ReviewerDto reviewer, CultureDto culture, String title, String reviewImageUrl1, String reviewImageUrl2, String reviewImageUrl3, String reviewImageUrl4, LocalDateTime createdDate, int likeCount) { + public SaveReviewResponse(Long reviewId, ReviewerDto reviewer, ReviewCultureDto culture, String title, String reviewImageUrl1, String reviewImageUrl2, String reviewImageUrl3, String reviewImageUrl4, LocalDateTime createdDate, int likeCount) { this.reviewId = reviewId; this.reviewer = reviewer; this.culture = culture; @@ -54,12 +54,12 @@ public ReviewerDto(Long userId, String username, String profileImage) { @Getter @NoArgsConstructor - public static class CultureDto { + public static class ReviewCultureDto { private Long cultureId; private String cultureName; @Builder - public CultureDto(Long cultureId, String cultureName) { + public ReviewCultureDto(Long cultureId, String cultureName) { this.cultureId = cultureId; this.cultureName = cultureName; } diff --git a/src/main/java/likelion/MZConnent/service/club/MyClubService.java b/src/main/java/likelion/MZConnent/service/club/MyClubService.java index 5189f5e..6299c06 100644 --- a/src/main/java/likelion/MZConnent/service/club/MyClubService.java +++ b/src/main/java/likelion/MZConnent/service/club/MyClubService.java @@ -2,7 +2,8 @@ import likelion.MZConnent.domain.club.Club; import likelion.MZConnent.domain.member.Member; -import likelion.MZConnent.dto.club.response.ClubSimpleResponse; +import likelion.MZConnent.dto.club.SelfIntroductionDto; +import likelion.MZConnent.dto.club.response.MyClubDetailResponse; import likelion.MZConnent.dto.club.response.MyClubSimpleResponse; import likelion.MZConnent.repository.member.MemberRepository; import lombok.RequiredArgsConstructor; @@ -19,12 +20,11 @@ public class MyClubService { private final MemberRepository memberRepository; public MyClubSimpleResponse getMyClubs(String email) { - Member member = memberRepository.findByEmail(email) - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 사용자입니다.")); + Member member = getMemberByEmail(email); List clubList = getClubsByMember(member); List myClubs = clubList.stream() - .map(this::convertToDto) + .map(this::convertToSimpleDto) .collect(Collectors.toList()); return MyClubSimpleResponse.builder() @@ -38,7 +38,7 @@ private List getClubsByMember(Member member) { .collect(Collectors.toList()); } - private MyClubSimpleResponse.MyClubSimpleDto convertToDto(Club club) { + private MyClubSimpleResponse.MyClubSimpleDto convertToSimpleDto(Club club) { return MyClubSimpleResponse.MyClubSimpleDto.builder() .clubId(club.getClubId()) .title(club.getTitle()) @@ -48,4 +48,61 @@ private MyClubSimpleResponse.MyClubSimpleDto convertToDto(Club club) { .maxParticipant(club.getMaxParticipant()) .build(); } + + public MyClubDetailResponse getMyClubDetail(String email, Long clubId) { + Member member = getMemberByEmail(email); + Club club = getClubByMemberAndId(member, clubId); + + MyClubDetailResponse.MyClubCultureDto cultureDto = convertToCultureDto(club); + List memberDtos = convertToMemberDtos(club); + + return MyClubDetailResponse.builder() + .clubId(club.getClubId()) + .title(club.getTitle()) + .meetingDate(club.getMeetingDate()) + .content(club.getContent()) + .currentParticipant(club.getClubMembers().size()) + .culture(cultureDto) + .members(memberDtos) + .build(); + } + + private Member getMemberByEmail(String email) { + return memberRepository.findByEmail(email) + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 사용자입니다.")); + } + + private Club getClubByMemberAndId(Member member, Long clubId) { + return member.getClubMembers().stream() + .map(cm -> cm.getClub()) + .filter(c -> c.getClubId().equals(clubId)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("해당 클럽을 찾을 수 없습니다.")); + } + + private MyClubDetailResponse.MyClubCultureDto convertToCultureDto(Club club) { + return MyClubDetailResponse.MyClubCultureDto.builder() + .cultureId(club.getCulture().getCultureId()) + .name(club.getCulture().getName()) + .build(); + } + + private List convertToMemberDtos(Club club) { + return club.getClubMembers().stream() + .map(cm -> MyClubDetailResponse.MyClubMemberDto.builder() + .userId(cm.getMember().getId()) + .username(cm.getMember().getUsername()) + .profileImageUrl(cm.getMember().getProfileImageUrl()) + .age(cm.getMember().getAge()) + .gender(cm.getMember().getGender()) + .role(cm.getClubRole()) + .selfIntroductions(cm.getMember().getSelfIntroductions().stream() + .map(si -> SelfIntroductionDto.builder() + .cultureCategoryId(si.getCultureCategory().getId()) + .name(si.getCultureCategory().getName()) + .build()) + .collect(Collectors.toList())) + .build()) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/likelion/MZConnent/service/review/ReviewService.java b/src/main/java/likelion/MZConnent/service/review/ReviewService.java index a9b597b..072fecc 100644 --- a/src/main/java/likelion/MZConnent/service/review/ReviewService.java +++ b/src/main/java/likelion/MZConnent/service/review/ReviewService.java @@ -101,7 +101,7 @@ private SaveReviewResponse buildSaveReviewResponse(Review review, Member member, .username(member.getUsername()) .profileImage(member.getProfileImageUrl()) .build()) - .culture(SaveReviewResponse.CultureDto.builder() + .culture(SaveReviewResponse.ReviewCultureDto.builder() .cultureId(culture.getCultureId()) .cultureName(culture.getName()) .build()) From 3467542dc079188da44539b537794c9b19b7e08e Mon Sep 17 00:00:00 2001 From: oosedus Date: Tue, 30 Jul 2024 20:54:59 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=EB=A9=A4=EB=B2=84=20=ED=8F=89?= =?UTF-8?q?=EA=B0=80=ED=95=98=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20/=20fix:=20=EB=AA=A8=EC=9E=84=20=EA=B0=80=EC=9E=85?= =?UTF-8?q?=20=EC=8B=9C=20=EB=82=98=EC=9D=B4,=EC=84=B1=EB=B3=84=20?= =?UTF-8?q?=EC=A0=9C=ED=95=9C=20=EC=95=88=EB=90=98=EB=8D=98=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MZConnent/api/club/ClubController.java | 2 +- .../MZConnent/api/club/MyClubController.java | 15 ++- .../club/request/EvaluateMemberRequest.java | 14 +++ .../club/response/EvaluateMemberResponse.java | 14 +++ .../repository/manner/MannerRepository.java | 6 + .../MZConnent/service/club/ClubService.java | 8 +- .../MZConnent/service/club/RateService.java | 106 ++++++++++++++++++ 7 files changed, 158 insertions(+), 7 deletions(-) create mode 100644 src/main/java/likelion/MZConnent/dto/club/request/EvaluateMemberRequest.java create mode 100644 src/main/java/likelion/MZConnent/dto/club/response/EvaluateMemberResponse.java create mode 100644 src/main/java/likelion/MZConnent/service/club/RateService.java diff --git a/src/main/java/likelion/MZConnent/api/club/ClubController.java b/src/main/java/likelion/MZConnent/api/club/ClubController.java index 4900a97..5920c2a 100644 --- a/src/main/java/likelion/MZConnent/api/club/ClubController.java +++ b/src/main/java/likelion/MZConnent/api/club/ClubController.java @@ -1,5 +1,6 @@ package likelion.MZConnent.api.club; +import jakarta.transaction.Transactional; import jakarta.validation.Valid; import likelion.MZConnent.domain.member.Member; import likelion.MZConnent.dto.club.request.ClubSimpleRequest; @@ -20,7 +21,6 @@ import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; -import java.util.List; import java.util.Map; @Slf4j diff --git a/src/main/java/likelion/MZConnent/api/club/MyClubController.java b/src/main/java/likelion/MZConnent/api/club/MyClubController.java index d93d926..9bb0232 100644 --- a/src/main/java/likelion/MZConnent/api/club/MyClubController.java +++ b/src/main/java/likelion/MZConnent/api/club/MyClubController.java @@ -1,23 +1,24 @@ package likelion.MZConnent.api.club; +import likelion.MZConnent.dto.club.request.EvaluateMemberRequest; +import likelion.MZConnent.dto.club.response.EvaluateMemberResponse; import likelion.MZConnent.dto.club.response.MyClubDetailResponse; import likelion.MZConnent.dto.club.response.MyClubSimpleResponse; import likelion.MZConnent.jwt.principle.UserPrinciple; import likelion.MZConnent.service.club.MyClubService; +import likelion.MZConnent.service.club.RateService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @Slf4j @RequiredArgsConstructor @RestController public class MyClubController { private final MyClubService myClubService; + private final RateService rateService; @GetMapping("/api/users/clubs") public ResponseEntity getMyClubs(@AuthenticationPrincipal UserPrinciple userPrinciple) { @@ -32,4 +33,10 @@ public ResponseEntity getMyClubDetail(@AuthenticationPrinc } + @PostMapping("/api/clubs/{clubId}/members/{evaluateeId}/rate") + public ResponseEntity evaluateMember(@AuthenticationPrincipal UserPrinciple userPrinciple, @PathVariable Long clubId, @PathVariable Long evaluateeId, @RequestBody EvaluateMemberRequest request) { + EvaluateMemberResponse response = rateService.evaluateMember(userPrinciple.getEmail(), clubId, evaluateeId, request); + return ResponseEntity.ok(response); + } + } diff --git a/src/main/java/likelion/MZConnent/dto/club/request/EvaluateMemberRequest.java b/src/main/java/likelion/MZConnent/dto/club/request/EvaluateMemberRequest.java new file mode 100644 index 0000000..00bdc0a --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/club/request/EvaluateMemberRequest.java @@ -0,0 +1,14 @@ +package likelion.MZConnent.dto.club.request; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class EvaluateMemberRequest { + private int score; + + public EvaluateMemberRequest(int score) { + this.score = score; + } +} diff --git a/src/main/java/likelion/MZConnent/dto/club/response/EvaluateMemberResponse.java b/src/main/java/likelion/MZConnent/dto/club/response/EvaluateMemberResponse.java new file mode 100644 index 0000000..1b94f1d --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/club/response/EvaluateMemberResponse.java @@ -0,0 +1,14 @@ +package likelion.MZConnent.dto.club.response; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class EvaluateMemberResponse { + private int rateCount; + + public EvaluateMemberResponse(int rateCount) { + this.rateCount = rateCount; + } +} diff --git a/src/main/java/likelion/MZConnent/repository/manner/MannerRepository.java b/src/main/java/likelion/MZConnent/repository/manner/MannerRepository.java index 6afb9bd..29a4a3e 100644 --- a/src/main/java/likelion/MZConnent/repository/manner/MannerRepository.java +++ b/src/main/java/likelion/MZConnent/repository/manner/MannerRepository.java @@ -1,9 +1,15 @@ package likelion.MZConnent.repository.manner; +import likelion.MZConnent.domain.club.ClubMember; import likelion.MZConnent.domain.manner.Manner; +import likelion.MZConnent.domain.member.Member; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface MannerRepository extends JpaRepository { + long countByMemberAndClubMember(Member member, ClubMember clubMember); + List findByMember(Member member); } diff --git a/src/main/java/likelion/MZConnent/service/club/ClubService.java b/src/main/java/likelion/MZConnent/service/club/ClubService.java index 131f899..12a1ebe 100644 --- a/src/main/java/likelion/MZConnent/service/club/ClubService.java +++ b/src/main/java/likelion/MZConnent/service/club/ClubService.java @@ -111,13 +111,17 @@ private void validateJoinClub(Club club, Member member) { throw new IllegalArgumentException("정원이 초과되어 가입할 수 없습니다."); } - if (club.getAgeRestriction() != AgeRestriction.ALL && !(club.getAgeRestriction().equals(member.getAge()))) { + if (!club.getAgeRestriction().equals(AgeRestriction.ALL) && !club.getAgeRestriction().getAgeRestriction().equals(member.getAge().getName())) { throw new IllegalArgumentException("나이 제한으로 가입할 수 없습니다."); } - if (club.getGenderRestriction() != GenderRestriction.ALL && !(club.getGenderRestriction().equals(member.getGender()))) { + if (!club.getGenderRestriction().equals(GenderRestriction.ALL) && !club.getGenderRestriction().equals(member.getGender())) { throw new IllegalArgumentException("성별 제한으로 가입할 수 없습니다."); } + + if (club.getStatus().equals("CLOSE")) { + throw new IllegalArgumentException("모임이 마감되어 가입할 수 없습니다."); + } } @Scheduled(cron = "0 0 0 * * *", zone = "Asia/Seoul") diff --git a/src/main/java/likelion/MZConnent/service/club/RateService.java b/src/main/java/likelion/MZConnent/service/club/RateService.java new file mode 100644 index 0000000..1033844 --- /dev/null +++ b/src/main/java/likelion/MZConnent/service/club/RateService.java @@ -0,0 +1,106 @@ +package likelion.MZConnent.service.club; + +import jakarta.transaction.Transactional; +import likelion.MZConnent.domain.club.Club; +import likelion.MZConnent.domain.club.ClubMember; +import likelion.MZConnent.domain.manner.Manner; +import likelion.MZConnent.domain.member.Member; +import likelion.MZConnent.dto.club.request.EvaluateMemberRequest; +import likelion.MZConnent.dto.club.response.EvaluateMemberResponse; +import likelion.MZConnent.repository.club.ClubRepository; +import likelion.MZConnent.repository.manner.MannerRepository; +import likelion.MZConnent.repository.member.MemberRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.List; + +@Service +@Slf4j +@RequiredArgsConstructor +@Transactional +public class RateService { + private final MemberRepository memberRepository; + private final ClubRepository clubRepository; + private final MannerRepository mannerRepository; + + public EvaluateMemberResponse evaluateMember(String email, Long clubId, Long evaluateeId, EvaluateMemberRequest request) { + Member member = getMemberByEmail(email); + Member evaluatee = getMemberById(evaluateeId); + Club club = getClubById(clubId); + + // 해당 유저들이 해당 모임에 가입되어 있는지 확인 + validateClubMember(club, member, evaluatee); + ClubMember memberClubMember = getClubMember(club, member); + + // 평가자가 해당 멤버에게 평가한 횟수 조회 + // 평가자가 해당 멤버의 평가를 2번 이상한 경우 예외 처리 + long evaluationCount = mannerRepository.countByMemberAndClubMember(evaluatee, memberClubMember); + if (evaluationCount >= 2) { + throw new IllegalArgumentException("해당 멤버에게 2번 이상 평가할 수 없습니다."); + } + + // 평가 점수 저장 + saveEvaluation(request.getScore(), evaluatee, memberClubMember); + + // 평가 점수 평균 계산 및 업데이트 + updateAverageMannersScore(evaluatee); + + // 평가자가 해당 멤버에게 평가한 횟수 반환 + return new EvaluateMemberResponse((int) (evaluationCount + 1)); + } + + private Member getMemberByEmail(String email) { + return memberRepository.findByEmail(email) + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 사용자입니다.")); + } + + private Member getMemberById(Long evaluateeId) { + return memberRepository.findById(evaluateeId) + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 사용자입니다.")); + } + + private Club getClubById(Long clubId) { + return clubRepository.findById(clubId) + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 모임입니다.")); + } + + private void validateClubMember(Club club, Member evaluator, Member evaluatee) { + boolean isMemberJoined = club.getClubMembers().stream() + .anyMatch(cm -> cm.getMember().getId().equals(evaluator.getId())); + boolean isEvaluateeJoined = club.getClubMembers().stream() + .anyMatch(cm -> cm.getMember().getId().equals(evaluatee.getId())); + if (!isMemberJoined || !isEvaluateeJoined) { + throw new IllegalArgumentException("해당 사용자는 해당 모임에 가입되어 있지 않습니다."); + } + } + + private ClubMember getClubMember(Club club, Member member) { + return club.getClubMembers().stream() + .filter(cm -> cm.getMember().equals(member)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("해당 멤버를 클럽 멤버에서 찾을 수 없습니다.")); + } + + private void saveEvaluation(int score, Member evaluatee, ClubMember memberClubMember) { + Manner manner = Manner.builder() + .score(score) + .member(evaluatee) + .clubMember(memberClubMember) + .build(); + mannerRepository.save(manner); + } + + private void updateAverageMannersScore(Member evaluatee) { + List allMannersForEvaluatee = mannerRepository.findByMember(evaluatee); + double averageScore = allMannersForEvaluatee.stream() + .mapToInt(Manner::getScore) + .average() + .getAsDouble(); + evaluatee.setAverageMannersScore(BigDecimal.valueOf(averageScore)); + memberRepository.save(evaluatee); + } + +} From df1a01e441755c49c7d295e7998f319a24b46eb8 Mon Sep 17 00:00:00 2001 From: oosedus Date: Tue, 30 Jul 2024 21:08:05 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feat:=20=EB=A9=A4=EB=B2=84=20=ED=8F=89?= =?UTF-8?q?=EA=B0=80=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MZConnent/api/club/MyClubController.java | 7 ++++++ .../dto/club/response/MemberRateResponse.java | 24 +++++++++++++++++++ .../MZConnent/service/club/RateService.java | 24 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 src/main/java/likelion/MZConnent/dto/club/response/MemberRateResponse.java diff --git a/src/main/java/likelion/MZConnent/api/club/MyClubController.java b/src/main/java/likelion/MZConnent/api/club/MyClubController.java index 9bb0232..5d05380 100644 --- a/src/main/java/likelion/MZConnent/api/club/MyClubController.java +++ b/src/main/java/likelion/MZConnent/api/club/MyClubController.java @@ -2,6 +2,7 @@ import likelion.MZConnent.dto.club.request.EvaluateMemberRequest; import likelion.MZConnent.dto.club.response.EvaluateMemberResponse; +import likelion.MZConnent.dto.club.response.MemberRateResponse; import likelion.MZConnent.dto.club.response.MyClubDetailResponse; import likelion.MZConnent.dto.club.response.MyClubSimpleResponse; import likelion.MZConnent.jwt.principle.UserPrinciple; @@ -39,4 +40,10 @@ public ResponseEntity evaluateMember(@AuthenticationPrin return ResponseEntity.ok(response); } + @GetMapping("/api/clubs/{clubId}/members/{evaluateeId}/rate/count") + public ResponseEntity getMemberRateAndCount(@AuthenticationPrincipal UserPrinciple userPrinciple, @PathVariable Long clubId, @PathVariable Long evaluateeId) { + MemberRateResponse response = rateService.getMemberRateCountAndCount(userPrinciple.getEmail(), clubId, evaluateeId); + return ResponseEntity.ok(response); + } + } diff --git a/src/main/java/likelion/MZConnent/dto/club/response/MemberRateResponse.java b/src/main/java/likelion/MZConnent/dto/club/response/MemberRateResponse.java new file mode 100644 index 0000000..a400181 --- /dev/null +++ b/src/main/java/likelion/MZConnent/dto/club/response/MemberRateResponse.java @@ -0,0 +1,24 @@ +package likelion.MZConnent.dto.club.response; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +@Getter +@NoArgsConstructor +public class MemberRateResponse { + private int rateCount; + private String userName; + private BigDecimal averageMannersScore; + private String profileImageUrl; + + @Builder + public MemberRateResponse(int rateCount, String userName, BigDecimal averageMannersScore, String profileImageUrl) { + this.rateCount = rateCount; + this.userName = userName; + this.averageMannersScore = averageMannersScore; + this.profileImageUrl = profileImageUrl; + } +} diff --git a/src/main/java/likelion/MZConnent/service/club/RateService.java b/src/main/java/likelion/MZConnent/service/club/RateService.java index 1033844..8df3e88 100644 --- a/src/main/java/likelion/MZConnent/service/club/RateService.java +++ b/src/main/java/likelion/MZConnent/service/club/RateService.java @@ -7,6 +7,7 @@ import likelion.MZConnent.domain.member.Member; import likelion.MZConnent.dto.club.request.EvaluateMemberRequest; import likelion.MZConnent.dto.club.response.EvaluateMemberResponse; +import likelion.MZConnent.dto.club.response.MemberRateResponse; import likelion.MZConnent.repository.club.ClubRepository; import likelion.MZConnent.repository.manner.MannerRepository; import likelion.MZConnent.repository.member.MemberRepository; @@ -52,6 +53,29 @@ public EvaluateMemberResponse evaluateMember(String email, Long clubId, Long eva return new EvaluateMemberResponse((int) (evaluationCount + 1)); } + public MemberRateResponse getMemberRateCountAndCount(String email, Long clubId, Long evaluateeId) { + Member member = getMemberByEmail(email); + Member evaluatee = getMemberById(evaluateeId); + Club club = getClubById(clubId); + + // 해당 멤버가 해당 모임에 가입되어 있는지 확인 + ClubMember memberClubMember = getClubMember(club, member); + validateClubMember(club, member, evaluatee); + + // 해당 멤버의 평가 점수 평균 조회 + double averageScore = evaluatee.getAverageMannersScore().doubleValue(); + + // 해당 멤버에게 평가한 횟수 조회 + long evaluationCount = mannerRepository.countByMemberAndClubMember(evaluatee, memberClubMember); + + return MemberRateResponse.builder() + .rateCount((int) evaluationCount) + .userName(evaluatee.getUsername()) + .averageMannersScore(BigDecimal.valueOf(averageScore)) + .profileImageUrl(evaluatee.getProfileImageUrl()) + .build(); + } + private Member getMemberByEmail(String email) { return memberRepository.findByEmail(email) .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 사용자입니다."));