Skip to content

Commit 55d97ee

Browse files
authored
Merge pull request #212 from prgrms-web-devcourse-final-project/feature/EA3-156-review-implement
[EA3-156] Feature: 리뷰 대상 스터디 조회 수정
2 parents 21974e5 + 6d992f5 commit 55d97ee

File tree

10 files changed

+187
-60
lines changed

10 files changed

+187
-60
lines changed

src/main/java/grep/neogulcoder/domain/buddy/entity/BuddyEnergy.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,11 @@ public void updateEnergy(ReviewType reviewType) {
4848
this.level -= 1;
4949
}
5050
}
51+
52+
public BuddyEnergyReason findReasonFrom(ReviewType reviewType) {
53+
if(reviewType.isPositive()){
54+
return BuddyEnergyReason.POSITIVE_REVIEW;
55+
}
56+
return BuddyEnergyReason.NEGATIVE_REVIEW;
57+
}
5158
}

src/main/java/grep/neogulcoder/domain/review/ReviewType.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@ public boolean isSameType(ReviewType reviewType) {
2121
public boolean isNotSameType(ReviewType reviewType) {
2222
return !isSameType(reviewType);
2323
}
24+
25+
public boolean isPositive() {
26+
return this == GOOD || this == EXCELLENT;
27+
}
2428
}

src/main/java/grep/neogulcoder/domain/review/controller/ReviewController.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ public ApiResponse<ReviewTargetUsersInfo> getReviewTargetUsersInfo(@PathVariable
3232
}
3333

3434
@GetMapping("/studies/me")
35-
public ApiResponse<ReviewTargetStudiesInfo> getReviewTargetStudiesInfo(@AuthenticationPrincipal Principal userDetails,
36-
LocalDateTime currentDateTime) {
35+
public ApiResponse<ReviewTargetStudiesInfo> getReviewTargetStudiesInfo(@AuthenticationPrincipal Principal userDetails) {
3736
ReviewTargetStudiesInfo response = reviewService.getReviewTargetStudiesInfo(userDetails.getUserId(), LocalDateTime.now());
3837
return ApiResponse.success(response);
3938
}

src/main/java/grep/neogulcoder/domain/review/controller/ReviewSpecification.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public interface ReviewSpecification {
5454
- `studyInfo`: 리뷰 가능한 스터디의 이름과 이미지 정보 리스트입니다.
5555
"""
5656
)
57-
ApiResponse<ReviewTargetStudiesInfo> getReviewTargetStudiesInfo(Principal userDetails, LocalDateTime currentDateTime);
57+
ApiResponse<ReviewTargetStudiesInfo> getReviewTargetStudiesInfo(Principal userDetails);
5858

5959
@Operation(summary = "리뷰 생성", description = "스터디에 대한 리뷰를 작성 합니다.")
6060
ApiResponse<Long> save(ReviewSaveRequest request, Principal userDetails);

src/main/java/grep/neogulcoder/domain/review/service/ReviewService.java

Lines changed: 58 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package grep.neogulcoder.domain.review.service;
22

3-
import grep.neogulcoder.domain.buddy.service.BuddyEnergyService;
3+
import grep.neogulcoder.domain.buddy.entity.BuddyEnergy;
4+
import grep.neogulcoder.domain.buddy.entity.BuddyLog;
5+
import grep.neogulcoder.domain.buddy.exception.BuddyEnergyNotFoundException;
6+
import grep.neogulcoder.domain.buddy.repository.BuddyEnergyLogRepository;
7+
import grep.neogulcoder.domain.buddy.repository.BuddyEnergyRepository;
48
import grep.neogulcoder.domain.review.*;
59
import grep.neogulcoder.domain.review.controller.dto.response.MyReviewTagsInfo;
610
import grep.neogulcoder.domain.review.controller.dto.response.ReviewContentsPagingInfo;
@@ -14,8 +18,10 @@
1418
import grep.neogulcoder.domain.review.repository.ReviewRepository;
1519
import grep.neogulcoder.domain.review.repository.ReviewTagRepository;
1620
import grep.neogulcoder.domain.review.service.request.ReviewSaveServiceRequest;
21+
import grep.neogulcoder.domain.study.Studies;
1722
import grep.neogulcoder.domain.study.Study;
1823
import grep.neogulcoder.domain.study.StudyMember;
24+
import grep.neogulcoder.domain.study.StudyMembers;
1925
import grep.neogulcoder.domain.study.repository.StudyMemberQueryRepository;
2026
import grep.neogulcoder.domain.study.repository.StudyMemberRepository;
2127
import grep.neogulcoder.domain.study.repository.StudyRepository;
@@ -30,11 +36,13 @@
3036
import org.springframework.transaction.annotation.Transactional;
3137

3238
import java.time.LocalDateTime;
39+
import java.util.Collections;
3340
import java.util.List;
3441
import java.util.Map;
3542
import java.util.function.Function;
3643
import java.util.stream.Collectors;
3744

45+
import static grep.neogulcoder.domain.buddy.exception.code.BuddyEnergyErrorCode.BUDDY_ENERGY_NOT_FOUND;
3846
import static grep.neogulcoder.domain.review.ReviewErrorCode.ALREADY_REVIEW_WRITE_USER;
3947
import static grep.neogulcoder.domain.review.ReviewErrorCode.STUDY_NOT_FOUND;
4048

@@ -54,7 +62,8 @@ public class ReviewService {
5462
private final MyReviewTagRepository myReviewTagRepository;
5563
private final ReviewTagRepository reviewTagRepository;
5664

57-
private final BuddyEnergyService buddyEnergyService;
65+
private final BuddyEnergyRepository buddyEnergyRepository;
66+
private final BuddyEnergyLogRepository buddyEnergyLogRepository;
5867

5968
public ReviewTargetUsersInfo getReviewTargetUsersInfo(long studyId, long userId) {
6069
List<StudyMember> studyMembers = studyMemberRepository.findFetchStudyByStudyId(studyId);
@@ -67,39 +76,22 @@ public ReviewTargetUsersInfo getReviewTargetUsersInfo(long studyId, long userId)
6776
}
6877

6978
public ReviewTargetStudiesInfo getReviewTargetStudiesInfo(long userId, LocalDateTime currentDateTime) {
70-
List<StudyMember> studyMembers = studyMemberQueryRepository.findMembersByUserId(userId);
71-
List<Study> studies = extractConnectedStudies(studyMembers);
72-
List<Study> reviewableStudies = filteredReviewableStudies(currentDateTime, studies);
79+
List<Study> studies = findReviewableStudies(userId, currentDateTime);
80+
List<StudyMember> studyMembers = findJoinedStudyMemberBy(studies);
81+
List<StudyMember> otherMembers = StudyMembers.of(studyMembers).excludeByUser(userId);
7382

74-
List<Long> studyIds = reviewableStudies.stream()
75-
.map(Study::getId)
76-
.toList();
77-
78-
List<StudyMember> studyMemberList = studyMemberQueryRepository.findByIdIn(studyIds);
79-
80-
81-
Map<Long, Long> groupedStudyIdCountMap = studyMemberList.stream()
82-
.map(StudyMember::getStudy)
83-
.collect(
84-
Collectors.groupingBy(
85-
Study::getId,
86-
Collectors.counting()
87-
)
88-
);
83+
List<ReviewEntity> myReviews = reviewQueryRepository.findReviewsByReviewerInStudies(
84+
Studies.of(studies).extractId(), userId
85+
);
8986

90-
List<ReviewEntity> myReviews = reviewQueryRepository.findReviewsByReviewerInStudies(studyIds, userId);
91-
Map<Long, List<ReviewEntity>> groupedStudyIdMap = myReviews.stream()
92-
.collect(
93-
Collectors.groupingBy(
94-
ReviewEntity::getStudyId
95-
)
96-
);
87+
Map<Long, Long> groupedStudyIdCountMap = StudyMembers.of(otherMembers).getGroupedStudyIdCountMap();
88+
Map<Long, List<ReviewEntity>> groupedStudyIdMap = getGroupedStudyIdMap(myReviews);
9789

98-
List<Study> studies1 = studies.stream()
99-
.filter(study -> groupedStudyIdCountMap.get(study.getId()) - 1 != groupedStudyIdMap.get(study.getId()).size())
90+
List<Study> reviewTargetStudies = studies.stream()
91+
.filter(study -> isCompletedReview(study, groupedStudyIdCountMap, groupedStudyIdMap))
10092
.toList();
10193

102-
return ReviewTargetStudiesInfo.of(studies1);
94+
return ReviewTargetStudiesInfo.of(reviewTargetStudies);
10395
}
10496

10597
@Transactional
@@ -108,15 +100,16 @@ public long save(ReviewSaveServiceRequest request, long writeUserId) {
108100
throw new BusinessException(ALREADY_REVIEW_WRITE_USER);
109101
}
110102

111-
Study study = findValidStudy(request.getStudyId());
103+
Study study = studyRepository.findById(request.getStudyId())
104+
.orElseThrow(() -> new NotFoundException(STUDY_NOT_FOUND));
105+
112106
ReviewTags reviewTags = ReviewTags.from(convertStringToReviewTag(request.getReviewTag()));
113107
ReviewType reviewType = reviewTags.ensureSingleReviewType();
114108

115109
Review review = request.toReview(reviewTags.getReviewTags(), reviewType, writeUserId);
116110
List<ReviewTagEntity> reviewTagEntities = mapToReviewTagEntities(reviewTags);
117111

118-
buddyEnergyService.updateEnergyByReview(request.getTargetUserId(), reviewType);
119-
112+
updatedBuddyEnergy(writeUserId, reviewType);
120113
return reviewRepository.save(ReviewEntity.from(review, reviewTagEntities, study.getId())).getId();
121114
}
122115

@@ -160,23 +153,39 @@ private List<User> excludeMe(List<User> users, long userId) {
160153
.toList();
161154
}
162155

163-
private List<Study> filteredReviewableStudies(LocalDateTime currentDateTime, List<Study> studies) {
164-
return studies.stream()
156+
private List<Study> findReviewableStudies(long userId, LocalDateTime currentDateTime) {
157+
List<StudyMember> myStudyMembers = studyMemberQueryRepository.findMembersByUserId(userId);
158+
List<Study> myStudies = extractConnectedStudies(myStudyMembers);
159+
160+
return myStudies.stream()
165161
.filter(study -> study.isReviewableAt(currentDateTime))
166162
.toList();
167163
}
168164

165+
private boolean isCompletedReview(Study study, Map<Long, Long> groupedStudyIdCountMap, Map<Long, List<ReviewEntity>> groupedStudyIdMap) {
166+
return groupedStudyIdCountMap.getOrDefault(study.getId(), 0L) != groupedStudyIdMap.getOrDefault(study.getId(), Collections.emptyList()).size();
167+
}
168+
169+
private List<StudyMember> findJoinedStudyMemberBy(List<Study> studies) {
170+
List<Long> studyIds = Studies.of(studies).extractId();
171+
return studyMemberQueryRepository.findByIdIn(studyIds);
172+
}
173+
174+
private Map<Long, List<ReviewEntity>> getGroupedStudyIdMap(List<ReviewEntity> myReviews) {
175+
return myReviews.stream()
176+
.collect(
177+
Collectors.groupingBy(
178+
ReviewEntity::getStudyId
179+
)
180+
);
181+
}
182+
169183
private List<Study> extractConnectedStudies(List<StudyMember> studyMembers) {
170184
return studyMembers.stream()
171185
.map(StudyMember::getStudy)
172186
.toList();
173187
}
174188

175-
private Study findValidStudy(long studyId) {
176-
return studyRepository.findById(studyId)
177-
.orElseThrow(() -> new NotFoundException(STUDY_NOT_FOUND));
178-
}
179-
180189
private boolean isAlreadyWrittenReviewBy(long studyId, long targetUserId, long writeUserId) {
181190
return reviewQueryRepository.findBy(studyId, targetUserId, writeUserId) != null;
182191
}
@@ -192,6 +201,15 @@ private List<ReviewTagEntity> mapToReviewTagEntities(ReviewTags reviewTags) {
192201
return reviewTagRepository.findByReviewTagIn(reviewTagDescriptions);
193202
}
194203

204+
private BuddyEnergy updatedBuddyEnergy(long writeUserId, ReviewType reviewType) {
205+
BuddyEnergy energy = buddyEnergyRepository.findByUserId(writeUserId)
206+
.orElseThrow(() -> new BuddyEnergyNotFoundException(BUDDY_ENERGY_NOT_FOUND));
207+
208+
energy.updateEnergy(reviewType);
209+
buddyEnergyLogRepository.save(BuddyLog.of(energy, energy.findReasonFrom(reviewType)));
210+
return energy;
211+
}
212+
195213
private List<ReviewTag> extractReviewTags(List<ReviewEntity> myReviews) {
196214
List<ReviewTagEntity> reviewTagEntities = getReviewTagEntities(myReviews);
197215
return reviewTagEntities.stream()
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package grep.neogulcoder.domain.study;
2+
3+
import java.util.List;
4+
5+
public class Studies {
6+
7+
private final List<Study> studies;
8+
9+
private Studies(List<Study> studies) {
10+
this.studies = studies;
11+
}
12+
13+
public static Studies of(List<Study> studies){
14+
return new Studies(studies);
15+
}
16+
17+
public List<Long> extractId(){
18+
return this.studies.stream()
19+
.map(Study::getId)
20+
.toList();
21+
}
22+
}

src/main/java/grep/neogulcoder/domain/study/StudyMember.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ public static StudyMember createLeader(Study study, Long userId) {
4646

4747
public static StudyMember createMember(Study study, Long userId) {
4848
return StudyMember.builder()
49-
.study(study)
50-
.userId(userId)
51-
.role(StudyMemberRole.MEMBER)
52-
.build();
49+
.study(study)
50+
.userId(userId)
51+
.role(StudyMemberRole.MEMBER)
52+
.build();
5353
}
5454

5555
public void delete() {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package grep.neogulcoder.domain.study;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
import java.util.stream.Collectors;
6+
7+
public class StudyMembers {
8+
9+
private List<StudyMember> studyMembers;
10+
11+
private StudyMembers(List<StudyMember> studyMembers) {
12+
this.studyMembers = studyMembers;
13+
}
14+
15+
public static StudyMembers of(List<StudyMember> studyMembers){
16+
return new StudyMembers(studyMembers);
17+
}
18+
19+
public List<StudyMember> excludeByUser(long userId){
20+
return this.studyMembers.stream()
21+
.filter(studyMember -> studyMember.getUserId() != userId)
22+
.toList();
23+
}
24+
25+
public Map<Long, Long> getGroupedStudyIdCountMap() {
26+
return this.studyMembers.stream()
27+
.map(StudyMember::getStudy)
28+
.collect(
29+
Collectors.groupingBy(
30+
Study::getId,
31+
Collectors.counting()
32+
)
33+
);
34+
}
35+
}

src/main/java/grep/neogulcoder/domain/study/repository/StudyMemberQueryRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public List<ExtendParticipationResponse> findExtendParticipation(Long studyId) {
7575
public List<StudyMember> findByIdIn(List<Long> studyIds) {
7676
return queryFactory.selectFrom(studyMember)
7777
.where(
78-
studyMember.id.in(studyIds),
78+
studyMember.study.id.in(studyIds),
7979
studyMember.activated.isTrue()
8080
)
8181
.join(studyMember.study, study).fetchJoin()

0 commit comments

Comments
 (0)