diff --git a/src/main/java/com/pbl/insaroad/domain/animalmission/controller/AnimalMissionController.java b/src/main/java/com/pbl/insaroad/domain/animalmission/controller/AnimalMissionController.java index abc9572..65c06e3 100644 --- a/src/main/java/com/pbl/insaroad/domain/animalmission/controller/AnimalMissionController.java +++ b/src/main/java/com/pbl/insaroad/domain/animalmission/controller/AnimalMissionController.java @@ -3,6 +3,7 @@ */ package com.pbl.insaroad.domain.animalmission.controller; +import com.pbl.insaroad.domain.game.dto.request.GameRequest.CompleteRequest; import jakarta.validation.Valid; import org.springframework.web.bind.annotation.PostMapping; @@ -33,8 +34,9 @@ public class AnimalMissionController { description = "사용자의 선택(문양 2개, 입구 1개, 그림 1개)을 받아 최종 동물을 반환합니다. 동점일 경우 마지막 문항(그림) 선택을 결과로 반환합니다.") public BaseResponse submitAnimalMission( - @Valid @RequestBody AnimalMissionSubmitRequest request) { - AnimalResultResponse result = animalMissionService.submitAnimalMission(request); + @Valid @RequestBody AnimalMissionSubmitRequest missionRequest, + @Valid @RequestBody CompleteRequest completeRequest) { + AnimalResultResponse result = animalMissionService.submitAnimalMission(missionRequest, completeRequest); return BaseResponse.success(result); } } diff --git a/src/main/java/com/pbl/insaroad/domain/animalmission/dto/request/AnimalMissionSubmitRequest.java b/src/main/java/com/pbl/insaroad/domain/animalmission/dto/request/AnimalMissionSubmitRequest.java index e1bd5ee..c5936a1 100644 --- a/src/main/java/com/pbl/insaroad/domain/animalmission/dto/request/AnimalMissionSubmitRequest.java +++ b/src/main/java/com/pbl/insaroad/domain/animalmission/dto/request/AnimalMissionSubmitRequest.java @@ -22,10 +22,6 @@ @Schema(description = "동물 미션 테스트 결과 제출 요청") public class AnimalMissionSubmitRequest { - @NotBlank(message = "사용자 코드는 필수입니다.") - @Schema(description = "사용자 코드 (3자리)", example = "123") - private String userCode; - @NotNull @Size(min = 2, max = 2, message = "문양은 2개를 선택해야 합니다.") @Schema(description = "문양 선택 (2개)", example = "[\"TIGER\", \"CRANE\"]") private List patternAnimals; diff --git a/src/main/java/com/pbl/insaroad/domain/animalmission/exception/AnimalMissionErrorCode.java b/src/main/java/com/pbl/insaroad/domain/animalmission/exception/AnimalMissionErrorCode.java index e61a0f5..3a7d997 100644 --- a/src/main/java/com/pbl/insaroad/domain/animalmission/exception/AnimalMissionErrorCode.java +++ b/src/main/java/com/pbl/insaroad/domain/animalmission/exception/AnimalMissionErrorCode.java @@ -15,7 +15,7 @@ public enum AnimalMissionErrorCode implements BaseErrorCode { DUPLICATE_PATTERN_ANIMALS("ANIMAL_4001", "patternAnimals에 중복된 동물이 있습니다.", HttpStatus.BAD_REQUEST), USER_NOT_FOUND("ANIMAL_4002", "사용자를 찾을 수 없습니다.", HttpStatus.NOT_FOUND), - USER_NOT_STAGE_3("ANIMAL_4003", "사용자의 스테이지가 3이 아닙니다.", HttpStatus.BAD_REQUEST), + USER_NOT_STAGE_2("ANIMAL_4003", "사용자의 스테이지가 2가 아닙니다.", HttpStatus.BAD_REQUEST), ; private final String code; diff --git a/src/main/java/com/pbl/insaroad/domain/animalmission/service/AnimalMissionService.java b/src/main/java/com/pbl/insaroad/domain/animalmission/service/AnimalMissionService.java index db5ab15..c4b07f5 100644 --- a/src/main/java/com/pbl/insaroad/domain/animalmission/service/AnimalMissionService.java +++ b/src/main/java/com/pbl/insaroad/domain/animalmission/service/AnimalMissionService.java @@ -3,6 +3,9 @@ */ package com.pbl.insaroad.domain.animalmission.service; +import com.pbl.insaroad.domain.game.dto.request.GameRequest.CompleteRequest; +import com.pbl.insaroad.domain.user.entity.User; +import com.pbl.insaroad.domain.user.service.UserService; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -34,6 +37,7 @@ public class AnimalMissionService { private static final Map ANIMAL_RESULTS = new HashMap<>(); private final UserRepository userRepository; + private final UserService userService; static { ANIMAL_RESULTS.put(AnimalType.TIGER, Tiger.CONTENT); @@ -45,12 +49,23 @@ public class AnimalMissionService { // 동물 미션 제출 처리 메서드 @Transactional - public AnimalResultResponse submitAnimalMission(AnimalMissionSubmitRequest request) { + public AnimalResultResponse submitAnimalMission(AnimalMissionSubmitRequest missionRequest, CompleteRequest completeRequest) { // 0. patternAnimals 중복 검증 - validateNoDuplicatePatternAnimals(request.getPatternAnimals()); + validateNoDuplicatePatternAnimals(missionRequest.getPatternAnimals()); + + // 사용자 조회 + User user = + userRepository + .findByCode(completeRequest.getUserCode()) + .orElseThrow(() -> new CustomException(AnimalMissionErrorCode.USER_NOT_FOUND)); + + // 사용자 스테이지 검증 + if (user.getStage() != 2) { + throw new CustomException(AnimalMissionErrorCode.USER_NOT_STAGE_2); + } // 1. 동물별 점수 집계 - Map scoreMap = calculateScores(request); + Map scoreMap = calculateScores(missionRequest); // 2. 최고 점수 계산 int maxScore = scoreMap.values().stream().mapToInt(Integer::intValue).max().orElse(0); @@ -61,7 +76,7 @@ public AnimalResultResponse submitAnimalMission(AnimalMissionSubmitRequest reque // 4. 동점 처리: 2개 이상이면 paintingAnimal 반환 AnimalType resultAnimal; if (countMaxScore >= 2) { - resultAnimal = request.getPaintingAnimal(); + resultAnimal = missionRequest.getPaintingAnimal(); } else { // 단일 최고 점수인 경우 해당 동물 반환 resultAnimal = @@ -69,9 +84,11 @@ public AnimalResultResponse submitAnimalMission(AnimalMissionSubmitRequest reque .filter(entry -> entry.getValue() == maxScore) .map(Map.Entry::getKey) .findFirst() - .orElse(request.getPaintingAnimal()); + .orElse(missionRequest.getPaintingAnimal()); } + userService.completeGame(completeRequest); + return ANIMAL_RESULTS.get(resultAnimal); } diff --git a/src/main/java/com/pbl/insaroad/domain/hangulsign/controller/HangulSignQuizController.java b/src/main/java/com/pbl/insaroad/domain/hangulsign/controller/HangulSignQuizController.java index 974362e..c116a0a 100644 --- a/src/main/java/com/pbl/insaroad/domain/hangulsign/controller/HangulSignQuizController.java +++ b/src/main/java/com/pbl/insaroad/domain/hangulsign/controller/HangulSignQuizController.java @@ -3,6 +3,7 @@ */ package com.pbl.insaroad.domain.hangulsign.controller; +import com.pbl.insaroad.domain.game.dto.request.GameRequest.CompleteRequest; import jakarta.validation.Valid; import org.springframework.http.ResponseEntity; @@ -41,8 +42,10 @@ public ResponseEntity> getRandomQuiz() { @Operation(summary = "퀴즈 정답 제출", description = "사용자가 선택한 답을 제출하고 정답 여부를 확인합니다.") @PostMapping("/{quizId}/answer") public ResponseEntity> submitAnswer( - @PathVariable Long quizId, @Valid @RequestBody AnswerRequest request) { - AnswerResponse response = quizService.submitAnswer(quizId, request); + @PathVariable Long quizId, + @Valid @RequestBody AnswerRequest answerRequest, + @Valid @RequestBody CompleteRequest completeRequest) { + AnswerResponse response = quizService.submitAnswer(quizId, answerRequest, completeRequest); return ResponseEntity.ok(BaseResponse.success("정답 제출 완료", response)); } } diff --git a/src/main/java/com/pbl/insaroad/domain/hangulsign/dto/response/QuizResponse.java b/src/main/java/com/pbl/insaroad/domain/hangulsign/dto/response/QuizResponse.java index 0fc6581..2baeaff 100644 --- a/src/main/java/com/pbl/insaroad/domain/hangulsign/dto/response/QuizResponse.java +++ b/src/main/java/com/pbl/insaroad/domain/hangulsign/dto/response/QuizResponse.java @@ -29,4 +29,7 @@ public class QuizResponse { @Schema(description = "선택지 3", example = "김밥왕국") private String choice3; + + @Schema(description = "정답 선택지 번호", example = "2") + private Integer correctChoice; } diff --git a/src/main/java/com/pbl/insaroad/domain/hangulsign/exception/HangulSignQuizErrorCode.java b/src/main/java/com/pbl/insaroad/domain/hangulsign/exception/HangulSignQuizErrorCode.java index 8811056..8abdfe5 100644 --- a/src/main/java/com/pbl/insaroad/domain/hangulsign/exception/HangulSignQuizErrorCode.java +++ b/src/main/java/com/pbl/insaroad/domain/hangulsign/exception/HangulSignQuizErrorCode.java @@ -15,7 +15,8 @@ public enum HangulSignQuizErrorCode implements BaseErrorCode { QUIZ_NOT_FOUND("QUIZ_4041", "퀴즈를 찾을 수 없습니다.", HttpStatus.NOT_FOUND), USER_NOT_FOUND("QUIZ_4042", "사용자를 찾을 수 없습니다.", HttpStatus.NOT_FOUND), - INVALID_CHOICE("QUIZ_4001", "유효하지 않은 선택지입니다. (1, 2, 3 중 선택)", HttpStatus.BAD_REQUEST); + INVALID_CHOICE("QUIZ_4001", "유효하지 않은 선택지입니다. (1, 2, 3 중 선택)", HttpStatus.BAD_REQUEST), + USER_NOT_STAGE_3("QUIZ_4003", "사용자의 스테이지가 3이 아닙니다.", HttpStatus.BAD_REQUEST); private final String code; private final String message; diff --git a/src/main/java/com/pbl/insaroad/domain/hangulsign/mapper/HangulSignQuizMapper.java b/src/main/java/com/pbl/insaroad/domain/hangulsign/mapper/HangulSignQuizMapper.java index 4ba51de..4b4ad58 100644 --- a/src/main/java/com/pbl/insaroad/domain/hangulsign/mapper/HangulSignQuizMapper.java +++ b/src/main/java/com/pbl/insaroad/domain/hangulsign/mapper/HangulSignQuizMapper.java @@ -21,6 +21,7 @@ public QuizResponse toQuizResponse(HangulSignQuiz quiz) { .choice1(quiz.getChoice1()) .choice2(quiz.getChoice2()) .choice3(quiz.getChoice3()) + .correctChoice(quiz.getCorrectChoice()) .build(); } diff --git a/src/main/java/com/pbl/insaroad/domain/hangulsign/service/HangulSignQuizService.java b/src/main/java/com/pbl/insaroad/domain/hangulsign/service/HangulSignQuizService.java index e20f871..49c023f 100644 --- a/src/main/java/com/pbl/insaroad/domain/hangulsign/service/HangulSignQuizService.java +++ b/src/main/java/com/pbl/insaroad/domain/hangulsign/service/HangulSignQuizService.java @@ -3,6 +3,8 @@ */ package com.pbl.insaroad.domain.hangulsign.service; +import com.pbl.insaroad.domain.game.dto.request.GameRequest.CompleteRequest; +import com.pbl.insaroad.domain.user.service.UserService; import java.util.List; import org.springframework.stereotype.Service; @@ -17,6 +19,8 @@ import com.pbl.insaroad.domain.hangulsign.exception.HangulSignQuizErrorCode; import com.pbl.insaroad.domain.hangulsign.mapper.HangulSignQuizMapper; import com.pbl.insaroad.domain.hangulsign.repository.HangulSignQuizRepository; +import com.pbl.insaroad.domain.user.entity.User; +import com.pbl.insaroad.domain.user.repository.UserRepository; import com.pbl.insaroad.global.exception.CustomException; import lombok.RequiredArgsConstructor; @@ -30,6 +34,8 @@ public class HangulSignQuizService { private final HangulSignQuizRepository quizRepository; private final HangulSignQuizMapper quizMapper; + private final UserRepository userRepository; + private final UserService userService; @Transactional(readOnly = true) public QuizResponse getRandomQuiz() { @@ -41,7 +47,18 @@ public QuizResponse getRandomQuiz() { return quizMapper.toQuizResponse(quiz); } - public AnswerResponse submitAnswer(Long quizId, AnswerRequest request) { + public AnswerResponse submitAnswer(Long quizId, AnswerRequest request, CompleteRequest completeRequest) { + // 사용자 조회 + User user = + userRepository + .findByCode(completeRequest.getUserCode()) + .orElseThrow(() -> new CustomException(HangulSignQuizErrorCode.USER_NOT_FOUND)); + + // 사용자 스테이지 검증 + if (user.getStage() != 3) { + throw new CustomException(HangulSignQuizErrorCode.USER_NOT_STAGE_3); + } + // 퀴즈 조회 HangulSignQuiz quiz = quizRepository @@ -57,6 +74,8 @@ public AnswerResponse submitAnswer(Long quizId, AnswerRequest request) { String answerImageUrl = isCorrect ? quiz.getAnswerImageUrl() : null; + userService.completeGame(completeRequest); + return quizMapper.toAnswerResponse(isCorrect, answerImageUrl); }