diff --git a/src/main/java/com/dnd/spaced/domain/skill/application/SkillService.java b/src/main/java/com/dnd/spaced/domain/skill/application/SkillService.java index b58373d..cb223fe 100644 --- a/src/main/java/com/dnd/spaced/domain/skill/application/SkillService.java +++ b/src/main/java/com/dnd/spaced/domain/skill/application/SkillService.java @@ -21,64 +21,41 @@ public class SkillService { private final SkillRepository skillRepository; /** - * 스킬 저장 로직. - * 기존에 스킬 정보가 있으면 업데이트하고, 없으면 새로 저장. + * 스킬 저장 로직 * * @param info 유저 정보 * @param skillRequest 카테고리와 맞춘 문제 개수 */ public void addSkill(AuthAccountInfo info, SkillRequest skillRequest) { - Skill skill = skillRepository.findByCategoryAndEmail(skillRequest.category(), info.email()); - if (skill != null) { - skill.updateSkill(skillRequest.correctCount()); - } else { - skill = Skill.builder() - .email(info.email()) - .correctCount(skillRequest.correctCount()) - .category(skillRequest.category()) - .totalCount(5L) - .build(); - } + Skill skill = findOrCreateSkill(info, skillRequest); skillRepository.save(skill); } /** - * 유저의 카테고리별 스킬 점수를 계산하고 반환. + * 유저의 카테고리별 스킬 점수를 계산 및 반환 * * @param info 유저 정보 * @return 카테고리별 스킬 점수 응답 */ public SkillTotalResponse getSkillTotalScore(AuthAccountInfo info) { - List skills = skillRepository.findByEmail(info.email()); - Map response = new HashMap<>(); - - int sum = 0; + Map response = initializeCategoryScores(); + int totalSum = calculateCategoryScores(info, response); + int totalAvgResponse = calculateAverageScore(response, totalSum); - for (Skill skill : skills) { - Long totalCount = calculateTotalScore(skill); - sum += totalCount; - response.put(skill.getCategory(), createSkillTotalScoreResponse(skill, totalCount)); - } - - sum /= 3; - - SkillTotalResponse totalResponse = SkillTotalResponse.builder() - .totalAvgResponse(sum) + return SkillTotalResponse.builder() + .totalAvgResponse(totalAvgResponse) .skillTotalScoreResponse(response) .build(); - - return totalResponse; } /** - * 유저의 총점에 따라 상위 몇 퍼센트인지 계산. + * 유저의 총점에 따라 상위 몇 퍼센트인지 계산 * * @param info 유저 정보 * @return 유저의 상위 퍼센트 */ public Long getTotalMyScore(AuthAccountInfo info) { List skills = skillRepository.findByEmail(info.email()); - Long userTotalScore = skills.stream() .mapToLong(this::calculateTotalScore) .sum(); @@ -89,40 +66,88 @@ public Long getTotalMyScore(AuthAccountInfo info) { } /** - * 개별 스킬의 정답 비율을 계산하는 메서드. - * - * @param skill 스킬 정보 - * @return 정답 비율 (총점) + * 스킬 저장 관련 메서드 */ - private Long calculateTotalScore(Skill skill) { - return (skill.getCorrectCount() == 0) ? 0 : (skill.getTotalCount() * 100) / skill.getCorrectCount(); + private Skill findOrCreateSkill(AuthAccountInfo info, SkillRequest skillRequest) { + Skill skill = skillRepository.findByCategoryAndEmail(skillRequest.category(), info.email()); + if (skill != null) { + skill.updateSkill(skillRequest.correctCount()); + return skill; + } + return Skill.builder() + .email(info.email()) + .correctCount(skillRequest.correctCount()) + .category(skillRequest.category()) + .totalCount(5L) + .build(); } /** - * 스킬 응답을 생성하는 메서드. - * - * @param skill 스킬 정보 - * @param totalCount 계산된 총점 - * @return 카테고리별 스킬 응답 DTO + * 카테고리 초기화 메서드 */ - private SkillTotalScoreResponse createSkillTotalScoreResponse(Skill skill, Long totalCount) { - return SkillTotalScoreResponse.builder() - .totalScore(totalCount) - .currentCount(skill.getCorrectCount()) - .totalCount(skill.getTotalCount()) - .build(); + private Map initializeCategoryScores() { + Map categoryScores = new HashMap<>(); + for (Category category : Category.values()) { + if (category != Category.ALL) { + categoryScores.put(category, SkillTotalScoreResponse.builder() + .totalScore(0L) + .currentCount(0L) + .totalCount(5L) + .build()); + } + } + return categoryScores; } /** - * 전체 유저의 평균 스킬 점수를 계산하는 메서드. - * - * @return 평균 스킬 점수 + * 카테고리별 점수 계산 + */ + private int calculateCategoryScores(AuthAccountInfo info, Map response) { + List skills = skillRepository.findByEmail(info.email()); + int totalSum = 0; + + for (Skill skill : skills) { + Long totalScore = calculateTotalScore(skill); + totalSum += totalScore; + response.put(skill.getCategory(), createSkillTotalScoreResponse(skill, totalScore)); + } + return totalSum; + } + + /** + * 총 평균 점수 계산 + */ + private int calculateAverageScore(Map response, int totalSum) { + long validCategories = response.keySet().stream().filter(category -> category != Category.ALL).count(); + return validCategories == 0 ? 0 : totalSum / (int) validCategories; + } + + /** + * 개별 스킬의 정답 비율 계산 + */ + private Long calculateTotalScore(Skill skill) { + return (skill.getCorrectCount() == 0) ? 0 : (skill.getCorrectCount() * 100) / skill.getTotalCount(); + } + + /** + * 전체 유저 평균 점수 계산 */ private Long calculateAveragePeopleScore() { List allSkills = skillRepository.findAll(); Long totalPeopleScore = allSkills.stream() .mapToLong(Skill::getCorrectCount) .sum(); - return (allSkills.isEmpty()) ? 0 : totalPeopleScore / allSkills.size(); + return allSkills.isEmpty() ? 0 : totalPeopleScore / allSkills.size(); + } + + /** + * 카테고리별 스킬 점수 생성 + */ + private SkillTotalScoreResponse createSkillTotalScoreResponse(Skill skill, Long totalScore) { + return SkillTotalScoreResponse.builder() + .totalScore(totalScore) + .currentCount(skill.getCorrectCount()) + .totalCount(skill.getTotalCount()) + .build(); } }