-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: 커리큘럼 ID의 모든 키워드 가져오는 로직 JPQL 사용해서 리팩토링
- Loading branch information
Showing
8 changed files
with
235 additions
and
179 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 26 additions & 90 deletions
116
backend/src/main/java/wooteco/prolog/roadmap/application/RoadMapService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,122 +1,58 @@ | ||
package wooteco.prolog.roadmap.application; | ||
|
||
import java.util.Comparator; | ||
import java.util.HashSet; | ||
import java.util.stream.Collectors; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import wooteco.prolog.common.exception.BadRequestException; | ||
import wooteco.prolog.roadmap.application.dto.KeywordResponse; | ||
import wooteco.prolog.roadmap.application.dto.KeywordsResponse; | ||
import wooteco.prolog.roadmap.application.dto.RecommendedPostResponse; | ||
import wooteco.prolog.roadmap.domain.Curriculum; | ||
import wooteco.prolog.roadmap.domain.EssayAnswer; | ||
import wooteco.prolog.roadmap.domain.Keyword; | ||
import wooteco.prolog.roadmap.domain.Quiz; | ||
import wooteco.prolog.roadmap.domain.repository.CurriculumRepository; | ||
import wooteco.prolog.roadmap.domain.repository.EssayAnswerRepository; | ||
import wooteco.prolog.roadmap.domain.repository.KeywordRepository; | ||
import wooteco.prolog.roadmap.domain.repository.QuizRepository; | ||
import wooteco.prolog.session.domain.Session; | ||
import wooteco.prolog.session.domain.repository.SessionRepository; | ||
import wooteco.prolog.roadmap.domain.repository.dto.KeywordIdAndDoneQuizCount; | ||
import wooteco.prolog.roadmap.domain.repository.dto.KeywordIdAndTotalQuizCount; | ||
|
||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
import static java.util.stream.Collectors.groupingBy; | ||
import static java.util.stream.Collectors.toList; | ||
import static java.util.stream.Collectors.toSet; | ||
import static wooteco.prolog.common.exception.BadRequestCode.CURRICULUM_NOT_FOUND_EXCEPTION; | ||
import static java.util.Objects.isNull; | ||
|
||
@RequiredArgsConstructor | ||
@Transactional | ||
@Transactional(readOnly = true) | ||
@Service | ||
public class RoadMapService { | ||
|
||
private final CurriculumRepository curriculumRepository; | ||
private final SessionRepository sessionRepository; | ||
private final KeywordRepository keywordRepository; | ||
private final QuizRepository quizRepository; | ||
private final EssayAnswerRepository essayAnswerRepository; | ||
|
||
@Transactional(readOnly = true) | ||
public KeywordsResponse findAllKeywordsWithProgress(final Long curriculumId, final Long memberId) { | ||
final Curriculum curriculum = curriculumRepository.findById(curriculumId) | ||
.orElseThrow(() -> new BadRequestException(CURRICULUM_NOT_FOUND_EXCEPTION)); | ||
final List<Keyword> keywords = keywordRepository.findAllByCurriculumId(curriculumId); | ||
final Map<Long, Integer> totalQuizCounts = getTotalQuizCounts(); | ||
final Map<Long, Integer> doneQuizCounts = getDoneQuizCounts(memberId); | ||
|
||
final List<Keyword> keywordsInCurriculum = getKeywordsInCurriculum(curriculum); | ||
final KeywordsResponse keywordsResponse = KeywordsResponse.of(keywords); | ||
keywordsResponse.setProgress(totalQuizCounts, doneQuizCounts); | ||
|
||
final Map<Keyword, Set<Quiz>> quizzesInKeywords = quizRepository.findAll().stream() | ||
.collect(groupingBy(Quiz::getKeyword, toSet())); | ||
|
||
return createResponsesWithProgress(keywordsInCurriculum, quizzesInKeywords, getDoneQuizzes(memberId)); | ||
} | ||
|
||
private Set<Quiz> getDoneQuizzes(final Long memberId) { | ||
return essayAnswerRepository.findAllByMemberId(memberId).stream() | ||
.map(EssayAnswer::getQuiz) | ||
.collect(toSet()); | ||
return keywordsResponse; | ||
} | ||
|
||
private List<Keyword> getKeywordsInCurriculum(final Curriculum curriculum) { | ||
final Set<Long> sessionIds = sessionRepository.findAllByCurriculumId(curriculum.getId()) | ||
.stream() | ||
.map(Session::getId) | ||
.collect(toSet()); | ||
|
||
return keywordRepository.findBySessionIdIn(sessionIds); | ||
} | ||
private Map<Long, Integer> getTotalQuizCounts() { | ||
final Map<Long, Integer> totalQuizCounts = new HashMap<>(); | ||
|
||
private KeywordsResponse createResponsesWithProgress(final List<Keyword> keywords, | ||
final Map<Keyword, Set<Quiz>> quizzesPerKeyword, | ||
final Set<Quiz> doneQuizzes) { | ||
final List<KeywordResponse> keywordResponses = keywords.stream() | ||
.filter(Keyword::isRoot) | ||
.map(keyword -> createResponseWithProgress(keyword, quizzesPerKeyword, doneQuizzes)) | ||
.sorted(Comparator.comparing(KeywordResponse::getKeywordId)) | ||
.collect(toList()); | ||
for (KeywordIdAndTotalQuizCount totalQuizCount : keywordRepository.findTotalQuizCount()) { | ||
totalQuizCounts.put(totalQuizCount.getKeywordId(), totalQuizCount.getTotalQuizCount()); | ||
} | ||
|
||
return new KeywordsResponse(keywordResponses); | ||
return totalQuizCounts; | ||
} | ||
|
||
private KeywordResponse createResponseWithProgress(final Keyword keyword, | ||
final Map<Keyword, Set<Quiz>> quizzesPerKeyword, | ||
final Set<Quiz> doneQuizzes) { | ||
final int totalQuizCount = quizzesPerKeyword.getOrDefault(keyword, new HashSet<>()).size(); | ||
final int doneQuizCount = getDoneQuizCount( | ||
quizzesPerKeyword.getOrDefault(keyword, new HashSet<>()), doneQuizzes); | ||
private Map<Long, Integer> getDoneQuizCounts(final Long memberId) { | ||
final Map<Long, Integer> doneQuizCounts = new HashMap<>(); | ||
if (isNull(memberId)) { | ||
return doneQuizCounts; | ||
} | ||
|
||
final List<RecommendedPostResponse> recommendedPostResponses = keyword.getRecommendedPosts().stream() | ||
.map(RecommendedPostResponse::from) | ||
.collect(toList()); | ||
|
||
return new KeywordResponse( | ||
keyword.getId(), | ||
keyword.getName(), | ||
keyword.getDescription(), | ||
keyword.getSeq(), | ||
keyword.getImportance(), | ||
totalQuizCount, | ||
doneQuizCount, | ||
keyword.getParentIdOrNull(), | ||
recommendedPostResponses, | ||
createChildrenWithProgress(keyword.getChildren(), quizzesPerKeyword, doneQuizzes) | ||
); | ||
} | ||
|
||
private int getDoneQuizCount(final Set<Quiz> quizzes, final Set<Quiz> doneQuizzes) { | ||
quizzes.retainAll(doneQuizzes); | ||
return quizzes.size(); | ||
} | ||
for (KeywordIdAndDoneQuizCount doneQuizCount : keywordRepository.findDoneQuizCountByMemberId(memberId)) { | ||
doneQuizCounts.put(doneQuizCount.getKeywordId(), doneQuizCount.getDoneQuizCount()); | ||
} | ||
|
||
private List<KeywordResponse> createChildrenWithProgress(final Set<Keyword> children, | ||
final Map<Keyword, Set<Quiz>> quizzesPerKeyword, | ||
final Set<Quiz> userAnswers) { | ||
return children.stream() | ||
.map(child -> createResponseWithProgress(child, quizzesPerKeyword, userAnswers)) | ||
.sorted(Comparator.comparing(KeywordResponse::getKeywordId)) | ||
.collect(Collectors.toList()); | ||
return doneQuizCounts; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 2 additions & 1 deletion
3
backend/src/main/java/wooteco/prolog/roadmap/domain/repository/QuizRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.