Skip to content

Commit

Permalink
Merge pull request #68 from LIKELION-TEAM4-HACKATHON/feature/evaluate…
Browse files Browse the repository at this point in the history
…-member

멤버 평가하기 및 조회
  • Loading branch information
chaeyoungeee authored Jul 30, 2024
2 parents 83046b9 + df1a01e commit a2dda2e
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -20,7 +21,6 @@
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@Slf4j
Expand Down
22 changes: 18 additions & 4 deletions src/main/java/likelion/MZConnent/api/club/MyClubController.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
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.MemberRateResponse;
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<MyClubSimpleResponse> getMyClubs(@AuthenticationPrincipal UserPrinciple userPrinciple) {
Expand All @@ -32,4 +34,16 @@ public ResponseEntity<MyClubDetailResponse> getMyClubDetail(@AuthenticationPrinc
}


@PostMapping("/api/clubs/{clubId}/members/{evaluateeId}/rate")
public ResponseEntity<EvaluateMemberResponse> 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);
}

@GetMapping("/api/clubs/{clubId}/members/{evaluateeId}/rate/count")
public ResponseEntity<MemberRateResponse> getMemberRateAndCount(@AuthenticationPrincipal UserPrinciple userPrinciple, @PathVariable Long clubId, @PathVariable Long evaluateeId) {
MemberRateResponse response = rateService.getMemberRateCountAndCount(userPrinciple.getEmail(), clubId, evaluateeId);
return ResponseEntity.ok(response);
}

}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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<Manner, Long> {
long countByMemberAndClubMember(Member member, ClubMember clubMember);
List<Manner> findByMember(Member member);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
130 changes: 130 additions & 0 deletions src/main/java/likelion/MZConnent/service/club/RateService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
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.dto.club.response.MemberRateResponse;
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));
}

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("존재하지 않는 사용자입니다."));
}

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<Manner> allMannersForEvaluatee = mannerRepository.findByMember(evaluatee);
double averageScore = allMannersForEvaluatee.stream()
.mapToInt(Manner::getScore)
.average()
.getAsDouble();
evaluatee.setAverageMannersScore(BigDecimal.valueOf(averageScore));
memberRepository.save(evaluatee);
}

}

0 comments on commit a2dda2e

Please sign in to comment.