From 2d598e076c14f05ee85b73346f77153b2c6da54a Mon Sep 17 00:00:00 2001 From: HongGit Date: Tue, 18 Mar 2025 17:37:50 +0900 Subject: [PATCH 01/14] =?UTF-8?q?[feat/#94]=20=EC=A0=84=EC=B2=B4=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=A1=B0=ED=9A=8C=20api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/submit/controller/.gitkeep | 0 .../controller/ClientGetController.java | 31 ++++++++ .../moplus_server/client/submit/dto/.gitkeep | 0 .../dto/response/AllProblemGetResponse.java | 26 +++++++ .../submit/dto/response/DayProgress.java | 21 ++++++ .../client/submit/repository/.gitkeep | 0 .../repository/ProblemSubmitRepository.java | 9 +++ .../client/submit/service/.gitkeep | 0 .../submit/service/ClientGetService.java | 74 +++++++++++++++++++ 9 files changed, 161 insertions(+) delete mode 100644 src/main/java/com/moplus/moplus_server/client/submit/controller/.gitkeep create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java delete mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/.gitkeep create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/response/AllProblemGetResponse.java create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/response/DayProgress.java delete mode 100644 src/main/java/com/moplus/moplus_server/client/submit/repository/.gitkeep create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/repository/ProblemSubmitRepository.java delete mode 100644 src/main/java/com/moplus/moplus_server/client/submit/service/.gitkeep create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java diff --git a/src/main/java/com/moplus/moplus_server/client/submit/controller/.gitkeep b/src/main/java/com/moplus/moplus_server/client/submit/controller/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java new file mode 100644 index 0000000..d7ace94 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java @@ -0,0 +1,31 @@ +package com.moplus.moplus_server.client.submit.controller; + +import com.moplus.moplus_server.client.submit.dto.response.AllProblemGetResponse; +import com.moplus.moplus_server.client.submit.service.ClientGetService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "클라이언트 조회", description = "클라이언트 조회 관련 API") +@RestController +@RequestMapping("/api/v1/client") +@RequiredArgsConstructor +public class ClientGetController { + + private final ClientGetService clientGetService; + + @GetMapping("allProblem/{year}/{month}") + @Operation(summary = "전체 문제 조회", description = "월별 문제들에 대한 진행도와 정보들을 조회합니다.") + public ResponseEntity> getAllProblem( + @PathVariable int year, + @PathVariable int month + ) { + return ResponseEntity.ok(clientGetService.getAllProblem(year, month)); + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/.gitkeep b/src/main/java/com/moplus/moplus_server/client/submit/dto/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/AllProblemGetResponse.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/AllProblemGetResponse.java new file mode 100644 index 0000000..91c3c6f --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/AllProblemGetResponse.java @@ -0,0 +1,26 @@ +package com.moplus.moplus_server.client.submit.dto.response; + +import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; +import java.time.LocalDate; +import java.util.List; +import lombok.Builder; + +@Builder +public record AllProblemGetResponse( + Long publishId, + LocalDate date, + DayProgress progress, + List problemStatuses, + String mainProblemImageUrl +) { + public static AllProblemGetResponse of(Long publishId, LocalDate date, DayProgress progress, + List problemStatuses, String mainProblemImageUrl) { + return AllProblemGetResponse.builder() + .publishId(publishId) + .date(date) + .progress(progress) + .problemStatuses(problemStatuses) + .mainProblemImageUrl(mainProblemImageUrl) + .build(); + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/DayProgress.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/DayProgress.java new file mode 100644 index 0000000..5e9251d --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/DayProgress.java @@ -0,0 +1,21 @@ +package com.moplus.moplus_server.client.submit.dto.response; + +import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; +import java.util.List; + +public enum DayProgress { + COMPLETE, + INCOMPLETE, + IN_PROGRESS; + public static DayProgress determineDayProgress(List problemStatuses) { + if (problemStatuses.isEmpty()) { + return INCOMPLETE; + } + else if (problemStatuses.contains(ProblemSubmitStatus.IN_PROGRESS)) { + return IN_PROGRESS; + } + else{ + return COMPLETE; + } + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/repository/.gitkeep b/src/main/java/com/moplus/moplus_server/client/submit/repository/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/com/moplus/moplus_server/client/submit/repository/ProblemSubmitRepository.java b/src/main/java/com/moplus/moplus_server/client/submit/repository/ProblemSubmitRepository.java new file mode 100644 index 0000000..5edb089 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/repository/ProblemSubmitRepository.java @@ -0,0 +1,9 @@ +package com.moplus.moplus_server.client.submit.repository; + +import com.moplus.moplus_server.client.submit.domain.ProblemSubmit; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ProblemSubmitRepository extends JpaRepository { + List findByMemberIdAndPublishId(Long memberId, Long publishId); +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/.gitkeep b/src/main/java/com/moplus/moplus_server/client/submit/service/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java new file mode 100644 index 0000000..0f0b20c --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java @@ -0,0 +1,74 @@ +package com.moplus.moplus_server.client.submit.service; + + +import com.moplus.moplus_server.admin.publish.domain.Publish; +import com.moplus.moplus_server.client.submit.domain.ProblemSubmit; +import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; +import com.moplus.moplus_server.client.submit.dto.response.AllProblemGetResponse; +import com.moplus.moplus_server.client.submit.dto.response.DayProgress; +import com.moplus.moplus_server.client.submit.repository.ProblemSubmitRepository; +import com.moplus.moplus_server.domain.problem.domain.problem.Problem; +import com.moplus.moplus_server.domain.problem.repository.ProblemRepository; +import com.moplus.moplus_server.domain.problemset.repository.ProblemSetRepository; +import com.moplus.moplus_server.domain.publish.repository.PublishRepository; +import com.moplus.moplus_server.global.error.exception.ErrorCode; +import com.moplus.moplus_server.global.error.exception.InvalidValueException; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ClientGetService { + + private final PublishRepository publishRepository; + private final ProblemSubmitRepository problemSubmitRepository; + private final ProblemRepository problemRepository; + private final ProblemSetRepository problemSetRepository; + + @Transactional(readOnly = true) + public List getAllProblem(int year, int month) { + + Long memberId = 1L; + + if (month < 1 || month > 12) { + throw new InvalidValueException(ErrorCode.INVALID_MONTH_ERROR); + } + LocalDate startDate = LocalDate.of(year, month, 1); + LocalDate endDate = startDate.withDayOfMonth(startDate.lengthOfMonth()); + + // 해당 월 모든 Publish 조회 + List publishes = publishRepository.findByPublishedDateBetween(startDate, endDate); + + List result = new ArrayList<>(); + + for (Publish publish : publishes) { + Long publishId = publish.getId(); + LocalDate date = publish.getPublishedDate(); + + // 날짜별 사용자 제출 정보 조회 + List submissions = problemSubmitRepository.findByMemberIdAndPublishId(memberId, publishId); + List problemStatuses = submissions.stream() + .map(ProblemSubmit::getStatus) + .toList(); + + // 사용자 제출 정보 바탕으로 진행도 결정 + DayProgress progress = DayProgress.determineDayProgress(problemStatuses); + String mainProblemImageUrl = getMainProblemImageUrl(publish.getProblemSetId()); + + result.add(AllProblemGetResponse.of(publishId, date, progress, problemStatuses, mainProblemImageUrl)); + } + return result; + } + + private String getMainProblemImageUrl(Long problemSetId) { + return problemSetRepository.findById(problemSetId) + .flatMap(problemSet -> problemSet.getProblemIds().stream().findFirst()) + .flatMap(problemRepository::findById) + .map(Problem::getMainProblemImageUrl) + .orElse(null); + } +} From 59057899f0dcec8f6da14902764ce7a214b999c7 Mon Sep 17 00:00:00 2001 From: HongGit Date: Tue, 18 Mar 2025 19:43:30 +0900 Subject: [PATCH 02/14] =?UTF-8?q?[feat/#94]=20=ED=95=B4=EC=84=A4=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ClientGetController.java | 11 +++++ .../response/ChildProblemDetailResponse.java | 20 ++++++++ .../dto/response/CommentaryGetResponse.java | 28 +++++++++++ .../dto/response/PrescriptionResponse.java | 18 +++++++ .../dto/response/ProblemDetailResponse.java | 20 ++++++++ .../ChildProblemSubmitRepository.java | 16 +++++++ .../repository/ProblemSubmitRepository.java | 10 ++++ .../submit/service/ClientGetService.java | 47 +++++++++++++++++++ .../global/error/exception/ErrorCode.java | 6 +++ 9 files changed, 176 insertions(+) create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/response/ChildProblemDetailResponse.java create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/response/CommentaryGetResponse.java create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/response/PrescriptionResponse.java create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemDetailResponse.java create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/repository/ChildProblemSubmitRepository.java diff --git a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java index d7ace94..d959000 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java @@ -1,6 +1,7 @@ package com.moplus.moplus_server.client.submit.controller; import com.moplus.moplus_server.client.submit.dto.response.AllProblemGetResponse; +import com.moplus.moplus_server.client.submit.dto.response.CommentaryGetResponse; import com.moplus.moplus_server.client.submit.service.ClientGetService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -10,6 +11,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @Tag(name = "클라이언트 조회", description = "클라이언트 조회 관련 API") @@ -20,6 +22,15 @@ public class ClientGetController { private final ClientGetService clientGetService; + @GetMapping("commentary") + @Operation(summary = "해설 조회", description = "문항 별 해설/처방을 조회합니다.") + public ResponseEntity getCommentary( + @RequestParam(value = "publishId", required = false) Long publishId, + @RequestParam(value = "problemId", required = false) Long problemId + ) { + return ResponseEntity.ok(clientGetService.getCommentary(publishId, problemId)); + } + @GetMapping("allProblem/{year}/{month}") @Operation(summary = "전체 문제 조회", description = "월별 문제들에 대한 진행도와 정보들을 조회합니다.") public ResponseEntity> getAllProblem( diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ChildProblemDetailResponse.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ChildProblemDetailResponse.java new file mode 100644 index 0000000..8250034 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ChildProblemDetailResponse.java @@ -0,0 +1,20 @@ +package com.moplus.moplus_server.client.submit.dto.response; + +import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmitStatus; +import java.util.List; +import lombok.Builder; + +@Builder +public record ChildProblemDetailResponse( + String imageUrl, + List prescriptionImageUrls, + ChildProblemSubmitStatus submitStatus +) { + public static ChildProblemDetailResponse of(String imageUrl, List prescriptionImageUrls, ChildProblemSubmitStatus submitStatus) { + return ChildProblemDetailResponse.builder() + .imageUrl(imageUrl) + .prescriptionImageUrls(prescriptionImageUrls) + .submitStatus(submitStatus) + .build(); + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/CommentaryGetResponse.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/CommentaryGetResponse.java new file mode 100644 index 0000000..5c0ba7c --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/CommentaryGetResponse.java @@ -0,0 +1,28 @@ +package com.moplus.moplus_server.client.submit.dto.response; + +import lombok.Builder; + +@Builder +public record CommentaryGetResponse( + int problemNumber, + String answer, + String mainAnalysisImageUrl, + String mainHandwritingExplanationImageUrl, + String readingTipImageUrl, + String seniorTipImageUrl, + PrescriptionResponse prescription +) { + public static CommentaryGetResponse of(int problemNumber, String answer, String mainAnalysisImageUrl, + String mainHandwritingExplanationImageUrl, String readingTipImageUrl, + String seniorTipImageUrl, PrescriptionResponse prescription) { + return CommentaryGetResponse.builder() + .problemNumber(problemNumber) + .answer(answer) + .mainAnalysisImageUrl(mainAnalysisImageUrl) + .mainHandwritingExplanationImageUrl(mainHandwritingExplanationImageUrl) + .readingTipImageUrl(readingTipImageUrl) + .seniorTipImageUrl(seniorTipImageUrl) + .prescription(prescription) + .build(); + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/PrescriptionResponse.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/PrescriptionResponse.java new file mode 100644 index 0000000..31e5a01 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/PrescriptionResponse.java @@ -0,0 +1,18 @@ +package com.moplus.moplus_server.client.submit.dto.response; + +import java.util.List; +import lombok.Builder; + +@Builder +public record PrescriptionResponse( + List childProblem, + ProblemDetailResponse mainProblem +) { + public static PrescriptionResponse of(List childProblem, + ProblemDetailResponse mainProblem) { + return PrescriptionResponse.builder() + .childProblem(childProblem) + .mainProblem(mainProblem) + .build(); + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemDetailResponse.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemDetailResponse.java new file mode 100644 index 0000000..aa31cf0 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemDetailResponse.java @@ -0,0 +1,20 @@ +package com.moplus.moplus_server.client.submit.dto.response; + +import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; +import java.util.List; +import lombok.Builder; + +@Builder +public record ProblemDetailResponse( + String imageUrl, + List prescriptionImageUrls, + ProblemSubmitStatus submitStatus +) { + public static ProblemDetailResponse of(String imageUrl, List prescriptionImageUrls, ProblemSubmitStatus submitStatus) { + return ProblemDetailResponse.builder() + .imageUrl(imageUrl) + .prescriptionImageUrls(prescriptionImageUrls) + .submitStatus(submitStatus) + .build(); + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/repository/ChildProblemSubmitRepository.java b/src/main/java/com/moplus/moplus_server/client/submit/repository/ChildProblemSubmitRepository.java new file mode 100644 index 0000000..6d33c1d --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/repository/ChildProblemSubmitRepository.java @@ -0,0 +1,16 @@ +package com.moplus.moplus_server.client.submit.repository; + +import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmit; +import com.moplus.moplus_server.global.error.exception.ErrorCode; +import com.moplus.moplus_server.global.error.exception.NotFoundException; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ChildProblemSubmitRepository extends JpaRepository { + Optional findByMemberIdAndPublishIdAndChildProblemId(Long memberId, Long publishId, Long problemId); + + default ChildProblemSubmit findByMemberIdAndPublishIdAndChildProblemIdElseThrow(Long memberId, Long publishId, Long problemId) { + return findByMemberIdAndPublishIdAndChildProblemId(memberId, publishId, problemId).orElseThrow( + () -> new NotFoundException(ErrorCode.CHILD_PROBLEM_SUBMIT_NOT_CONFIRMED)); + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/repository/ProblemSubmitRepository.java b/src/main/java/com/moplus/moplus_server/client/submit/repository/ProblemSubmitRepository.java index 5edb089..d9ff255 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/repository/ProblemSubmitRepository.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/repository/ProblemSubmitRepository.java @@ -1,9 +1,19 @@ package com.moplus.moplus_server.client.submit.repository; import com.moplus.moplus_server.client.submit.domain.ProblemSubmit; +import com.moplus.moplus_server.global.error.exception.ErrorCode; +import com.moplus.moplus_server.global.error.exception.NotFoundException; import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface ProblemSubmitRepository extends JpaRepository { List findByMemberIdAndPublishId(Long memberId, Long publishId); + + Optional findByMemberIdAndPublishIdAndProblemId(Long memberId, Long publishId, Long problemId); + + default ProblemSubmit findByMemberIdAndPublishIdAndProblemIdElseThrow(Long memberId, Long publishId, Long problemId) { + return findByMemberIdAndPublishIdAndProblemId(memberId, publishId, problemId).orElseThrow( + () -> new NotFoundException(ErrorCode.PROBLEM_SUBMIT_NOT_CONFIRMED)); + } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java index 0f0b20c..f545c02 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java @@ -5,7 +5,12 @@ import com.moplus.moplus_server.client.submit.domain.ProblemSubmit; import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; import com.moplus.moplus_server.client.submit.dto.response.AllProblemGetResponse; +import com.moplus.moplus_server.client.submit.dto.response.ChildProblemDetailResponse; +import com.moplus.moplus_server.client.submit.dto.response.CommentaryGetResponse; import com.moplus.moplus_server.client.submit.dto.response.DayProgress; +import com.moplus.moplus_server.client.submit.dto.response.PrescriptionResponse; +import com.moplus.moplus_server.client.submit.dto.response.ProblemDetailResponse; +import com.moplus.moplus_server.client.submit.repository.ChildProblemSubmitRepository; import com.moplus.moplus_server.client.submit.repository.ProblemSubmitRepository; import com.moplus.moplus_server.domain.problem.domain.problem.Problem; import com.moplus.moplus_server.domain.problem.repository.ProblemRepository; @@ -28,6 +33,48 @@ public class ClientGetService { private final ProblemSubmitRepository problemSubmitRepository; private final ProblemRepository problemRepository; private final ProblemSetRepository problemSetRepository; + private final ChildProblemSubmitRepository childProblemSubmitRepository; + + + @Transactional(readOnly = true) + public CommentaryGetResponse getCommentary(Long publishId, Long problemId) { + + Long memberId = 1L; + + // 문항 제출 조회 + ProblemSubmit problemSubmit = problemSubmitRepository.findByMemberIdAndPublishIdAndProblemIdElseThrow(memberId, + publishId, problemId); + + // 문항 해설 생성 + Problem problem = problemRepository.findByIdElseThrow(problemId); + ProblemDetailResponse mainProblem = ProblemDetailResponse.of( + problem.getMainProblemImageUrl(), + problem.getPrescriptionImageUrls(), + problemSubmit.getStatus() + ); + + // 새끼문항 해설 생성 + List childProblem = problem.getChildProblems().stream() + .map(cp -> ChildProblemDetailResponse.of( + cp.getImageUrl(), + cp.getPrescriptionImageUrls(), + childProblemSubmitRepository.findByMemberIdAndPublishIdAndChildProblemIdElseThrow(memberId, publishId, + cp.getId()).getStatus() + )).toList(); + + // 처방 정보 생성 + PrescriptionResponse prescription = PrescriptionResponse.of(childProblem, mainProblem); + + return CommentaryGetResponse.of( + problem.getNumber(), + problem.getAnswer(), + problem.getMainAnalysisImageUrl(), + problem.getMainHandwritingExplanationImageUrl(), + problem.getReadingTipImageUrl(), + problem.getSeniorTipImageUrl(), + prescription + ); + } @Transactional(readOnly = true) public List getAllProblem(int year, int month) { diff --git a/src/main/java/com/moplus/moplus_server/global/error/exception/ErrorCode.java b/src/main/java/com/moplus/moplus_server/global/error/exception/ErrorCode.java index 52a7fa0..193b4f6 100644 --- a/src/main/java/com/moplus/moplus_server/global/error/exception/ErrorCode.java +++ b/src/main/java/com/moplus/moplus_server/global/error/exception/ErrorCode.java @@ -76,6 +76,12 @@ public enum ErrorCode { ALREADY_PUBLISHED_ERROR(HttpStatus.BAD_REQUEST, "이미 발행된 문항세트는 컨펌해제할 수 없습니다."), PROBLEM_SET_DELETED(HttpStatus.BAD_REQUEST, "삭제된 문항세트는 발행할 수 없습니다"), PROBLEM_SET_NOT_CONFIRMED(HttpStatus.BAD_REQUEST, "컨펌되지 않은 문항세트는 발행할 수 없습니다"), + + // 문항 제출 + PROBLEM_SUBMIT_NOT_CONFIRMED(HttpStatus.NOT_FOUND, "문항 제출 정보를 찾을 수 없습니다."), + + // 새끼문항 제출 + CHILD_PROBLEM_SUBMIT_NOT_CONFIRMED(HttpStatus.NOT_FOUND, "새끼문항 제출 정보를 찾을 수 없습니다."), ; From 25a7adabcc72a692d40bd543fb1dfc443a5bcb13 Mon Sep 17 00:00:00 2001 From: HongGit Date: Tue, 18 Mar 2025 20:08:51 +0900 Subject: [PATCH 03/14] =?UTF-8?q?[feat/#94]=20=EC=A7=84=ED=96=89=EC=A4=91?= =?UTF-8?q?=EC=9D=B8=20=EB=AC=B8=ED=95=AD=EC=A0=9C=EC=B6=9C=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ClientSubmitController.java | 30 +++++++++++++++++++ .../request/ProblemSubmitCreateRequest.java | 21 +++++++++++++ .../submit/service/ClientSubmitService.java | 30 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/request/ProblemSubmitCreateRequest.java create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java diff --git a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java new file mode 100644 index 0000000..3ae0046 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java @@ -0,0 +1,30 @@ +package com.moplus.moplus_server.client.submit.controller; + +import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitCreateRequest; +import com.moplus.moplus_server.client.submit.service.ClientSubmitService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "클라이언트 제출", description = "클라이언트 제출 관련 API") +@RestController +@RequestMapping("/api/v1/client") +@RequiredArgsConstructor +public class ClientSubmitController { + + private final ClientSubmitService clientSubmitService; + + @PostMapping("problemSubmit") + @Operation(summary = "문항 제출 데이터 생성", description = "문항 제출을 '진행중'으로 생성합니다.") + public ResponseEntity createProblemSubmit( + @RequestBody ProblemSubmitCreateRequest request + ) { + clientSubmitService.createProblemSubmit(request); + return ResponseEntity.ok(null); + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ProblemSubmitCreateRequest.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ProblemSubmitCreateRequest.java new file mode 100644 index 0000000..7aec4f0 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ProblemSubmitCreateRequest.java @@ -0,0 +1,21 @@ +package com.moplus.moplus_server.client.submit.dto.request; + +import com.moplus.moplus_server.client.submit.domain.ProblemSubmit; +import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; +import jakarta.validation.constraints.NotNull; + +public record ProblemSubmitCreateRequest ( + @NotNull(message = "발행 ID는 필수입니다.") + Long publishId, + @NotNull(message = "문항 ID는 필수입니다.") + Long problemId +){ + public ProblemSubmit toEntity(Long memberId) { + return ProblemSubmit.builder() + .memberId(memberId) + .publishId(this.publishId) + .problemId(this.problemId) + .status(ProblemSubmitStatus.IN_PROGRESS) + .build(); + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java new file mode 100644 index 0000000..6ff89a7 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java @@ -0,0 +1,30 @@ +package com.moplus.moplus_server.client.submit.service; + + +import com.moplus.moplus_server.client.submit.domain.ProblemSubmit; +import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitCreateRequest; +import com.moplus.moplus_server.client.submit.repository.ProblemSubmitRepository; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ClientSubmitService { + + private final ProblemSubmitRepository problemSubmitRepository; + + @Transactional + public void createProblemSubmit(ProblemSubmitCreateRequest request) { + + Long memberId = 1L; + // 제출이력이 없을때만 생성 + Optional existingProblemSubmit = problemSubmitRepository.findByMemberIdAndPublishIdAndProblemId(memberId, + request.publishId(), request.problemId()); + if (existingProblemSubmit.isEmpty()) { + ProblemSubmit problemSubmit = request.toEntity(memberId); + problemSubmitRepository.save(problemSubmit); + } + } +} From d3e83b4dce250c569f778d0acbb7bb3a615143a9 Mon Sep 17 00:00:00 2001 From: HongGit Date: Tue, 18 Mar 2025 20:44:16 +0900 Subject: [PATCH 04/14] =?UTF-8?q?[feat/#94]=20=EC=8B=9C=EC=9E=91=EC=A0=84?= =?UTF-8?q?=20=EC=83=88=EB=81=BC=EB=AC=B8=ED=95=AD=EC=A0=9C=EC=B6=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ClientSubmitController.java | 12 +++- .../domain/ChildProblemSubmitStatus.java | 3 +- .../ChildProblemSubmitCreateRequest.java | 7 ++ .../submit/service/ClientSubmitService.java | 65 +++++++++++++++++++ .../problem/repository/ProblemRepository.java | 1 + .../publish/repository/PublishRepository.java | 6 ++ 6 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitCreateRequest.java diff --git a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java index 3ae0046..d9d4426 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java @@ -1,5 +1,6 @@ package com.moplus.moplus_server.client.submit.controller; +import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitCreateRequest; import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitCreateRequest; import com.moplus.moplus_server.client.submit.service.ClientSubmitService; import io.swagger.v3.oas.annotations.Operation; @@ -20,11 +21,20 @@ public class ClientSubmitController { private final ClientSubmitService clientSubmitService; @PostMapping("problemSubmit") - @Operation(summary = "문항 제출 데이터 생성", description = "문항 제출을 '진행중'으로 생성합니다.") + @Operation(summary = "문항 제출 생성", description = "문항 제출을 '진행중'으로 생성합니다.") public ResponseEntity createProblemSubmit( @RequestBody ProblemSubmitCreateRequest request ) { clientSubmitService.createProblemSubmit(request); return ResponseEntity.ok(null); } + + @PostMapping("childProblemSubmit") + @Operation(summary = "새끼문항 제출 생성", description = "문항에 속한 새끼문항들을 '시작전'으로 생성합니다.") + public ResponseEntity createProblemSubmit( + @RequestBody ChildProblemSubmitCreateRequest request + ) { + clientSubmitService.createChildProblemSubmit(request); + return ResponseEntity.ok(null); + } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmitStatus.java b/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmitStatus.java index 541c308..18e1ee0 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmitStatus.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmitStatus.java @@ -3,5 +3,6 @@ public enum ChildProblemSubmitStatus { CORRECT, INCORRECT, - RETRY_CORRECT + RETRY_CORRECT, + NOT_STARTED } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitCreateRequest.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitCreateRequest.java new file mode 100644 index 0000000..daeb567 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitCreateRequest.java @@ -0,0 +1,7 @@ +package com.moplus.moplus_server.client.submit.dto.request; + +public record ChildProblemSubmitCreateRequest( + Long publishId, + Long problemId +) { +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java index 6ff89a7..57e959a 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java @@ -1,9 +1,19 @@ package com.moplus.moplus_server.client.submit.service; +import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmit; +import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmitStatus; import com.moplus.moplus_server.client.submit.domain.ProblemSubmit; +import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; +import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitCreateRequest; import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitCreateRequest; +import com.moplus.moplus_server.client.submit.repository.ChildProblemSubmitRepository; import com.moplus.moplus_server.client.submit.repository.ProblemSubmitRepository; +import com.moplus.moplus_server.domain.problem.domain.childProblem.ChildProblem; +import com.moplus.moplus_server.domain.problem.domain.problem.Problem; +import com.moplus.moplus_server.domain.problem.repository.ProblemRepository; +import com.moplus.moplus_server.domain.publish.repository.PublishRepository; +import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -14,11 +24,21 @@ public class ClientSubmitService { private final ProblemSubmitRepository problemSubmitRepository; + private final ProblemRepository problemRepository; + private final ChildProblemSubmitRepository childProblemSubmitRepository; + private final PublishRepository publishRepository; @Transactional public void createProblemSubmit(ProblemSubmitCreateRequest request) { Long memberId = 1L; + + // 존재하는 발행인지 검증 + publishRepository.existsByIdElseThrow(request.publishId()); + + // 존재하는 문항인지 검증 + problemRepository.existsByIdElseThrow(request.problemId()); + // 제출이력이 없을때만 생성 Optional existingProblemSubmit = problemSubmitRepository.findByMemberIdAndPublishIdAndProblemId(memberId, request.publishId(), request.problemId()); @@ -27,4 +47,49 @@ public void createProblemSubmit(ProblemSubmitCreateRequest request) { problemSubmitRepository.save(problemSubmit); } } + + @Transactional + public void createChildProblemSubmit(ChildProblemSubmitCreateRequest request) { + + Long memberId = 1L; + + // 존재하는 발행인지 검증 + publishRepository.existsByIdElseThrow(request.publishId()); + + // 존재하는 문항인지 검증 + problemRepository.existsByIdElseThrow(request.problemId()); + + // 문항제출 이력이 없으면 문항제출 생성 + Optional existingProblemSubmit = problemSubmitRepository.findByMemberIdAndPublishIdAndProblemId(memberId, + request.publishId(), request.problemId()); + if (existingProblemSubmit.isEmpty()) { + ProblemSubmit problemSubmit = ProblemSubmit.builder() + .memberId(memberId) + .publishId(request.publishId()) + .problemId(request.problemId()) + .status(ProblemSubmitStatus.IN_PROGRESS) + .build(); + problemSubmitRepository.save(problemSubmit); + } + + // 문항의 새끼문항 조회 + Problem problem = problemRepository.findByIdElseThrow(request.problemId()); + List childProblems = problem.getChildProblems(); + + // 제출이력이 없을떄만 생성 + for (ChildProblem childProblem : childProblems) { + Long childProblemId = childProblem.getId(); + + Optional existingChildProblemSubmit = childProblemSubmitRepository.findByMemberIdAndPublishIdAndChildProblemId(memberId, + request.publishId(), childProblemId); + ChildProblemSubmit childProblemSubmit = ChildProblemSubmit.builder() + .memberId(memberId) + .publishId(request.publishId()) + .childProblemId(childProblemId) + .status(ChildProblemSubmitStatus.NOT_STARTED) + .build(); + childProblemSubmitRepository.save(childProblemSubmit); + } + } + } diff --git a/src/main/java/com/moplus/moplus_server/domain/problem/repository/ProblemRepository.java b/src/main/java/com/moplus/moplus_server/domain/problem/repository/ProblemRepository.java index 4529f68..3779f0f 100644 --- a/src/main/java/com/moplus/moplus_server/domain/problem/repository/ProblemRepository.java +++ b/src/main/java/com/moplus/moplus_server/domain/problem/repository/ProblemRepository.java @@ -25,4 +25,5 @@ default void existsByProblemAdminIdElseThrow(ProblemCustomId problemCustomId) { default Problem findByIdElseThrow(Long id) { return findById(id).orElseThrow(() -> new NotFoundException(ErrorCode.PROBLEM_NOT_FOUND)); } + } diff --git a/src/main/java/com/moplus/moplus_server/domain/publish/repository/PublishRepository.java b/src/main/java/com/moplus/moplus_server/domain/publish/repository/PublishRepository.java index d7422a1..37dcce3 100644 --- a/src/main/java/com/moplus/moplus_server/domain/publish/repository/PublishRepository.java +++ b/src/main/java/com/moplus/moplus_server/domain/publish/repository/PublishRepository.java @@ -15,4 +15,10 @@ default Publish findByIdElseThrow(Long publishId) { } List findByProblemSetId(Long problemSetId); + + default void existsByIdElseThrow(Long id) { + if (!existsById(id)) { + throw new NotFoundException(ErrorCode.PUBLISH_NOT_FOUND); + } + } } From 879985ff0e99b9b46e76537440000f185312e39c Mon Sep 17 00:00:00 2001 From: HongGit Date: Tue, 18 Mar 2025 22:03:31 +0900 Subject: [PATCH 05/14] =?UTF-8?q?[feat/#94]=20=EB=AC=B8=ED=95=AD=20?= =?UTF-8?q?=EC=A0=9C=EC=B6=9C=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20api?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ClientSubmitController.java | 11 ++++++++ .../client/submit/domain/ProblemSubmit.java | 4 +++ .../submit/domain/ProblemSubmitStatus.java | 15 ++++++++++- .../ChildProblemSubmitCreateRequest.java | 4 +++ .../request/ProblemSubmitUpdateRequest.java | 12 +++++++++ .../submit/service/ClientGetService.java | 2 -- .../submit/service/ClientSubmitService.java | 26 ++++++++++++++++--- 7 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/request/ProblemSubmitUpdateRequest.java diff --git a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java index d9d4426..012e0d9 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java @@ -1,13 +1,16 @@ package com.moplus.moplus_server.client.submit.controller; +import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitCreateRequest; import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitCreateRequest; +import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitUpdateRequest; import com.moplus.moplus_server.client.submit.service.ClientSubmitService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -29,6 +32,14 @@ public ResponseEntity createProblemSubmit( return ResponseEntity.ok(null); } + @PutMapping("problemSubmit") + @Operation(summary = "문항 제출 업데이트", description = "제출한 답안을 바탕으로 문항 제출의 상태를 업데이트합니다.") + public ResponseEntity updateProblemSubmit( + @RequestBody ProblemSubmitUpdateRequest request + ) { + return ResponseEntity.ok(clientSubmitService.updateProblemSubmit(request)); + } + @PostMapping("childProblemSubmit") @Operation(summary = "새끼문항 제출 생성", description = "문항에 속한 새끼문항들을 '시작전'으로 생성합니다.") public ResponseEntity createProblemSubmit( diff --git a/src/main/java/com/moplus/moplus_server/client/submit/domain/ProblemSubmit.java b/src/main/java/com/moplus/moplus_server/client/submit/domain/ProblemSubmit.java index 63ae280..02a6be9 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/domain/ProblemSubmit.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/domain/ProblemSubmit.java @@ -37,4 +37,8 @@ public ProblemSubmit(Long memberId, Long publishId, Long problemId, ProblemSubmi this.problemId = problemId; this.status = status; } + + public void updateStatus(ProblemSubmitStatus status) { + this.status = status; + } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/domain/ProblemSubmitStatus.java b/src/main/java/com/moplus/moplus_server/client/submit/domain/ProblemSubmitStatus.java index e42b77d..be01991 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/domain/ProblemSubmitStatus.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/domain/ProblemSubmitStatus.java @@ -4,5 +4,18 @@ public enum ProblemSubmitStatus { CORRECT, INCORRECT, IN_PROGRESS, - RETRY_CORRECT + RETRY_CORRECT; + public static ProblemSubmitStatus determineStatus(ProblemSubmitStatus currentStatus, String memberAnswer, String problemAnswer) { + boolean isCorrect = problemAnswer.trim().equals(memberAnswer.trim()); + + if (currentStatus == CORRECT) { + return isCorrect ? CORRECT : INCORRECT; + } else if (currentStatus == INCORRECT) { + return isCorrect ? RETRY_CORRECT : INCORRECT; + } else if (currentStatus == IN_PROGRESS) { + return isCorrect ? CORRECT : INCORRECT; + } else { + return isCorrect ? RETRY_CORRECT : INCORRECT; + } + } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitCreateRequest.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitCreateRequest.java index daeb567..9f42241 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitCreateRequest.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitCreateRequest.java @@ -1,7 +1,11 @@ package com.moplus.moplus_server.client.submit.dto.request; +import jakarta.validation.constraints.NotNull; + public record ChildProblemSubmitCreateRequest( + @NotNull(message = "발행 ID는 필수입니다.") Long publishId, + @NotNull(message = "문항 ID는 필수입니다.") Long problemId ) { } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ProblemSubmitUpdateRequest.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ProblemSubmitUpdateRequest.java new file mode 100644 index 0000000..1b52175 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ProblemSubmitUpdateRequest.java @@ -0,0 +1,12 @@ +package com.moplus.moplus_server.client.submit.dto.request; + +import jakarta.validation.constraints.NotNull; + +public record ProblemSubmitUpdateRequest( + @NotNull(message = "발행 ID는 필수입니다.") + Long publishId, + @NotNull(message = "문항 ID는 필수입니다.") + Long problemId, + String answer +) { +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java index f545c02..3079134 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java @@ -38,7 +38,6 @@ public class ClientGetService { @Transactional(readOnly = true) public CommentaryGetResponse getCommentary(Long publishId, Long problemId) { - Long memberId = 1L; // 문항 제출 조회 @@ -78,7 +77,6 @@ public CommentaryGetResponse getCommentary(Long publishId, Long problemId) { @Transactional(readOnly = true) public List getAllProblem(int year, int month) { - Long memberId = 1L; if (month < 1 || month > 12) { diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java index 57e959a..3de942e 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java @@ -7,6 +7,7 @@ import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitCreateRequest; import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitCreateRequest; +import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitUpdateRequest; import com.moplus.moplus_server.client.submit.repository.ChildProblemSubmitRepository; import com.moplus.moplus_server.client.submit.repository.ProblemSubmitRepository; import com.moplus.moplus_server.domain.problem.domain.childProblem.ChildProblem; @@ -30,12 +31,10 @@ public class ClientSubmitService { @Transactional public void createProblemSubmit(ProblemSubmitCreateRequest request) { - Long memberId = 1L; // 존재하는 발행인지 검증 publishRepository.existsByIdElseThrow(request.publishId()); - // 존재하는 문항인지 검증 problemRepository.existsByIdElseThrow(request.problemId()); @@ -49,13 +48,32 @@ public void createProblemSubmit(ProblemSubmitCreateRequest request) { } @Transactional - public void createChildProblemSubmit(ChildProblemSubmitCreateRequest request) { - + public ProblemSubmitStatus updateProblemSubmit(ProblemSubmitUpdateRequest request) { Long memberId = 1L; // 존재하는 발행인지 검증 publishRepository.existsByIdElseThrow(request.publishId()); + // 문항 조회 + Problem problem = problemRepository.findByIdElseThrow(request.problemId()); + + //문항 제출 데이터 조회 + ProblemSubmit problemSubmit = problemSubmitRepository.findByMemberIdAndPublishIdAndProblemIdElseThrow(memberId, + request.publishId(), request.problemId()); + // 제출한 답안에 대한 상태 결정 + ProblemSubmitStatus status = ProblemSubmitStatus.determineStatus(problemSubmit.getStatus(), request.answer(), + problem.getAnswer()); + + problemSubmit.updateStatus(status); + return status; + } + + @Transactional + public void createChildProblemSubmit(ChildProblemSubmitCreateRequest request) { + Long memberId = 1L; + + // 존재하는 발행인지 검증 + publishRepository.existsByIdElseThrow(request.publishId()); // 존재하는 문항인지 검증 problemRepository.existsByIdElseThrow(request.problemId()); From 2479aa57078885cf4d1cf77edb83b4f8bfe98962 Mon Sep 17 00:00:00 2001 From: HongGit Date: Tue, 18 Mar 2025 22:13:11 +0900 Subject: [PATCH 06/14] =?UTF-8?q?[feat/#94]=20=EC=83=88=EB=81=BC=EB=AC=B8?= =?UTF-8?q?=ED=95=AD=20=EC=A0=9C=EC=B6=9C=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ClientSubmitController.java | 10 ++++++++ .../submit/domain/ChildProblemSubmit.java | 4 ++++ .../domain/ChildProblemSubmitStatus.java | 15 +++++++++++- .../ChildProblemSubmitUpdateRequest.java | 12 ++++++++++ .../ChildProblemSubmitRepository.java | 6 ++--- .../submit/service/ClientSubmitService.java | 24 +++++++++++++++++++ 6 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitUpdateRequest.java diff --git a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java index 012e0d9..d515e53 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java @@ -1,7 +1,9 @@ package com.moplus.moplus_server.client.submit.controller; +import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmitStatus; import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitCreateRequest; +import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitUpdateRequest; import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitCreateRequest; import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitUpdateRequest; import com.moplus.moplus_server.client.submit.service.ClientSubmitService; @@ -48,4 +50,12 @@ public ResponseEntity createProblemSubmit( clientSubmitService.createChildProblemSubmit(request); return ResponseEntity.ok(null); } + + @PutMapping("childProblemSubmit") + @Operation(summary = "새끼문항 제출 업데이트", description = "제출한 답안을 바탕으로 문항 제출의 상태를 업데이트합니다.") + public ResponseEntity updateChildProblemSubmit( + @RequestBody ChildProblemSubmitUpdateRequest request + ) { + return ResponseEntity.ok(clientSubmitService.updateChildProblemSubmit(request)); + } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmit.java b/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmit.java index c7bb92c..95d9bce 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmit.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmit.java @@ -37,4 +37,8 @@ public ChildProblemSubmit(Long memberId, Long publishId, Long childProblemId, Ch this.childProblemId = childProblemId; this.status = status; } + + public void updateStatus(ChildProblemSubmitStatus status) { + this.status = status; + } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmitStatus.java b/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmitStatus.java index 18e1ee0..fb15456 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmitStatus.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmitStatus.java @@ -4,5 +4,18 @@ public enum ChildProblemSubmitStatus { CORRECT, INCORRECT, RETRY_CORRECT, - NOT_STARTED + NOT_STARTED; + public static ChildProblemSubmitStatus determineStatus(ChildProblemSubmitStatus currentStatus, String memberAnswer, String childProblemAnswer) { + boolean isCorrect = childProblemAnswer.trim().equals(memberAnswer.trim()); + + if (currentStatus == CORRECT) { + return isCorrect ? CORRECT : INCORRECT; + } else if (currentStatus == INCORRECT) { + return isCorrect ? RETRY_CORRECT : INCORRECT; + } else if (currentStatus == RETRY_CORRECT) { + return isCorrect ? RETRY_CORRECT : INCORRECT; + } else { + return isCorrect ? CORRECT : INCORRECT; + } + } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitUpdateRequest.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitUpdateRequest.java new file mode 100644 index 0000000..23a452d --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitUpdateRequest.java @@ -0,0 +1,12 @@ +package com.moplus.moplus_server.client.submit.dto.request; + +import jakarta.validation.constraints.NotNull; + +public record ChildProblemSubmitUpdateRequest( + @NotNull(message = "발행 ID는 필수입니다.") + Long publishId, + @NotNull(message = "새끼문항 ID는 필수입니다.") + Long childProblemId, + String answer +) { +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/repository/ChildProblemSubmitRepository.java b/src/main/java/com/moplus/moplus_server/client/submit/repository/ChildProblemSubmitRepository.java index 6d33c1d..40acf5d 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/repository/ChildProblemSubmitRepository.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/repository/ChildProblemSubmitRepository.java @@ -7,10 +7,10 @@ import org.springframework.data.jpa.repository.JpaRepository; public interface ChildProblemSubmitRepository extends JpaRepository { - Optional findByMemberIdAndPublishIdAndChildProblemId(Long memberId, Long publishId, Long problemId); + Optional findByMemberIdAndPublishIdAndChildProblemId(Long memberId, Long publishId, Long childProblemId); - default ChildProblemSubmit findByMemberIdAndPublishIdAndChildProblemIdElseThrow(Long memberId, Long publishId, Long problemId) { - return findByMemberIdAndPublishIdAndChildProblemId(memberId, publishId, problemId).orElseThrow( + default ChildProblemSubmit findByMemberIdAndPublishIdAndChildProblemIdElseThrow(Long memberId, Long publishId, Long childProblemId) { + return findByMemberIdAndPublishIdAndChildProblemId(memberId, publishId, childProblemId).orElseThrow( () -> new NotFoundException(ErrorCode.CHILD_PROBLEM_SUBMIT_NOT_CONFIRMED)); } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java index 3de942e..654a549 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java @@ -6,12 +6,14 @@ import com.moplus.moplus_server.client.submit.domain.ProblemSubmit; import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitCreateRequest; +import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitUpdateRequest; import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitCreateRequest; import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitUpdateRequest; import com.moplus.moplus_server.client.submit.repository.ChildProblemSubmitRepository; import com.moplus.moplus_server.client.submit.repository.ProblemSubmitRepository; import com.moplus.moplus_server.domain.problem.domain.childProblem.ChildProblem; import com.moplus.moplus_server.domain.problem.domain.problem.Problem; +import com.moplus.moplus_server.domain.problem.repository.ChildProblemRepository; import com.moplus.moplus_server.domain.problem.repository.ProblemRepository; import com.moplus.moplus_server.domain.publish.repository.PublishRepository; import java.util.List; @@ -28,6 +30,7 @@ public class ClientSubmitService { private final ProblemRepository problemRepository; private final ChildProblemSubmitRepository childProblemSubmitRepository; private final PublishRepository publishRepository; + private final ChildProblemRepository childProblemRepository; @Transactional public void createProblemSubmit(ProblemSubmitCreateRequest request) { @@ -110,4 +113,25 @@ public void createChildProblemSubmit(ChildProblemSubmitCreateRequest request) { } } + @Transactional + public ChildProblemSubmitStatus updateChildProblemSubmit(ChildProblemSubmitUpdateRequest request) { + Long memberId = 1L; + + // 존재하는 발행인지 검증 + publishRepository.existsByIdElseThrow(request.publishId()); + + // 새끼문항 조회 + ChildProblem childProblem = childProblemRepository.findByIdElseThrow(request.childProblemId()); + + //새끼문항 제출 데이터 조회 + ChildProblemSubmit childProblemSubmit = childProblemSubmitRepository.findByMemberIdAndPublishIdAndChildProblemIdElseThrow(memberId, + request.publishId(), request.childProblemId()); + // 제출한 답안에 대한 상태 결정 + ChildProblemSubmitStatus status = ChildProblemSubmitStatus.determineStatus(childProblemSubmit.getStatus(), request.answer(), + childProblem.getAnswer()); + + childProblemSubmit.updateStatus(status); + return status; + } + } From 1ae78de25c1915e19adb79be15063b779b243fe1 Mon Sep 17 00:00:00 2001 From: HongGit Date: Tue, 18 Mar 2025 22:19:50 +0900 Subject: [PATCH 07/14] =?UTF-8?q?[feat/#94]=20=EC=83=88=EB=81=BC=EB=AC=B8?= =?UTF-8?q?=ED=95=AD=20=EC=A0=9C=EC=B6=9C=20=ED=8B=80=EB=A6=BC=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8=20api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ClientSubmitController.java | 10 ++++++++++ .../submit/domain/ChildProblemSubmit.java | 5 +++++ ...hildProblemSubmitUpdateIncorrectRequest.java | 11 +++++++++++ .../submit/service/ClientSubmitService.java | 17 +++++++++++++++++ 4 files changed, 43 insertions(+) create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitUpdateIncorrectRequest.java diff --git a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java index d515e53..25c495c 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientSubmitController.java @@ -3,6 +3,7 @@ import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmitStatus; import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitCreateRequest; +import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitUpdateIncorrectRequest; import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitUpdateRequest; import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitCreateRequest; import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitUpdateRequest; @@ -58,4 +59,13 @@ public ResponseEntity updateChildProblemSubmit( ) { return ResponseEntity.ok(clientSubmitService.updateChildProblemSubmit(request)); } + + @PutMapping("childProblemSubmit/incorrect") + @Operation(summary = "새끼문항 제출 틀림 업데이트", description = "새끼문항 제출의 상태를 틀림으로 업데이트합니다.") + public ResponseEntity updateChildProblemSubmitIncorrect( + @RequestBody ChildProblemSubmitUpdateIncorrectRequest request + ) { + clientSubmitService.updateChildProblemSubmitIncorrect(request); + return ResponseEntity.ok(null); + } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmit.java b/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmit.java index 95d9bce..25a869e 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmit.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmit.java @@ -41,4 +41,9 @@ public ChildProblemSubmit(Long memberId, Long publishId, Long childProblemId, Ch public void updateStatus(ChildProblemSubmitStatus status) { this.status = status; } + + public void updateStatusIncorrect() { + this.status = ChildProblemSubmitStatus.INCORRECT; + + } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitUpdateIncorrectRequest.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitUpdateIncorrectRequest.java new file mode 100644 index 0000000..7ad9628 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/request/ChildProblemSubmitUpdateIncorrectRequest.java @@ -0,0 +1,11 @@ +package com.moplus.moplus_server.client.submit.dto.request; + +import jakarta.validation.constraints.NotNull; + +public record ChildProblemSubmitUpdateIncorrectRequest( + @NotNull(message = "발행 ID는 필수입니다.") + Long publishId, + @NotNull(message = "새끼문항 ID는 필수입니다.") + Long childProblemId +) { +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java index 654a549..f6ebd58 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientSubmitService.java @@ -6,6 +6,7 @@ import com.moplus.moplus_server.client.submit.domain.ProblemSubmit; import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitCreateRequest; +import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitUpdateIncorrectRequest; import com.moplus.moplus_server.client.submit.dto.request.ChildProblemSubmitUpdateRequest; import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitCreateRequest; import com.moplus.moplus_server.client.submit.dto.request.ProblemSubmitUpdateRequest; @@ -134,4 +135,20 @@ public ChildProblemSubmitStatus updateChildProblemSubmit(ChildProblemSubmitUpdat return status; } + @Transactional + public void updateChildProblemSubmitIncorrect(ChildProblemSubmitUpdateIncorrectRequest request) { + Long memberId = 1L; + + // 존재하는 발행인지 검증 + publishRepository.existsByIdElseThrow(request.publishId()); + + // 새끼문항 조회 + ChildProblem childProblem = childProblemRepository.findByIdElseThrow(request.childProblemId()); + + //새끼문항 제출 데이터 조회 + ChildProblemSubmit childProblemSubmit = childProblemSubmitRepository.findByMemberIdAndPublishIdAndChildProblemIdElseThrow(memberId, + request.publishId(), request.childProblemId()); + // 틀림 처리 + childProblemSubmit.updateStatusIncorrect(); + } } From f11997345a2d4f50c2e3be76916b5b8bde30b5a8 Mon Sep 17 00:00:00 2001 From: HongGit Date: Tue, 18 Mar 2025 23:02:17 +0900 Subject: [PATCH 08/14] =?UTF-8?q?[feat/#94]=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=EB=AC=B8=ED=95=AD=20=EC=A1=B0=ED=9A=8C=20api=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ClientGetController.java | 10 +++++++ .../response/ProblemClientGetResponse.java | 28 +++++++++++++++++++ .../ChildProblemSubmitRepository.java | 4 +++ .../submit/service/ClientGetService.java | 27 ++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemClientGetResponse.java diff --git a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java index d959000..ca579ba 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java @@ -2,6 +2,7 @@ import com.moplus.moplus_server.client.submit.dto.response.AllProblemGetResponse; import com.moplus.moplus_server.client.submit.dto.response.CommentaryGetResponse; +import com.moplus.moplus_server.client.submit.dto.response.ProblemClientGetResponse; import com.moplus.moplus_server.client.submit.service.ClientGetService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -39,4 +40,13 @@ public ResponseEntity> getAllProblem( ) { return ResponseEntity.ok(clientGetService.getAllProblem(year, month)); } + + @GetMapping("problem/{publishId}/{problemId}") + @Operation(summary = "문항 조회", description = "사용자에게 보여지는 문항을 조회합니다.") + public ResponseEntity getProblem( + @PathVariable Long publishId, + @PathVariable Long problemId + ) { + return ResponseEntity.ok(clientGetService.getProblem(publishId, problemId)); + } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemClientGetResponse.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemClientGetResponse.java new file mode 100644 index 0000000..40d73e5 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemClientGetResponse.java @@ -0,0 +1,28 @@ +package com.moplus.moplus_server.client.submit.dto.response; + +import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmitStatus; +import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; +import com.moplus.moplus_server.domain.problem.domain.problem.Problem; +import java.util.List; +import lombok.Builder; + +@Builder +public record ProblemClientGetResponse( + int number, + String imageUrl, + Integer recommendedMinute, + Integer recommendedSecond, + ProblemSubmitStatus status, + List childProblemStatuses +) { + public static ProblemClientGetResponse of(Problem problem, ProblemSubmitStatus status, List childProblemStatuses) { + return ProblemClientGetResponse.builder() + .number(problem.getNumber()) + .imageUrl(problem.getMainProblemImageUrl()) + .status(status) + .childProblemStatuses(childProblemStatuses) + .recommendedMinute(problem.getRecommendedTime().getMinute()) + .recommendedSecond(problem.getRecommendedTime().getSecond()) + .build(); + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/repository/ChildProblemSubmitRepository.java b/src/main/java/com/moplus/moplus_server/client/submit/repository/ChildProblemSubmitRepository.java index 40acf5d..33a5be8 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/repository/ChildProblemSubmitRepository.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/repository/ChildProblemSubmitRepository.java @@ -3,6 +3,7 @@ import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmit; import com.moplus.moplus_server.global.error.exception.ErrorCode; import com.moplus.moplus_server.global.error.exception.NotFoundException; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; @@ -13,4 +14,7 @@ default ChildProblemSubmit findByMemberIdAndPublishIdAndChildProblemIdElseThrow( return findByMemberIdAndPublishIdAndChildProblemId(memberId, publishId, childProblemId).orElseThrow( () -> new NotFoundException(ErrorCode.CHILD_PROBLEM_SUBMIT_NOT_CONFIRMED)); } + + List findAllByMemberIdAndPublishIdAndChildProblemIdIn(Long memberId, Long publishId, + List childProblemIds); } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java index 3079134..d22c3f6 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java @@ -2,6 +2,8 @@ import com.moplus.moplus_server.admin.publish.domain.Publish; +import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmit; +import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmitStatus; import com.moplus.moplus_server.client.submit.domain.ProblemSubmit; import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; import com.moplus.moplus_server.client.submit.dto.response.AllProblemGetResponse; @@ -9,9 +11,11 @@ import com.moplus.moplus_server.client.submit.dto.response.CommentaryGetResponse; import com.moplus.moplus_server.client.submit.dto.response.DayProgress; import com.moplus.moplus_server.client.submit.dto.response.PrescriptionResponse; +import com.moplus.moplus_server.client.submit.dto.response.ProblemClientGetResponse; import com.moplus.moplus_server.client.submit.dto.response.ProblemDetailResponse; import com.moplus.moplus_server.client.submit.repository.ChildProblemSubmitRepository; import com.moplus.moplus_server.client.submit.repository.ProblemSubmitRepository; +import com.moplus.moplus_server.domain.problem.domain.childProblem.ChildProblem; import com.moplus.moplus_server.domain.problem.domain.problem.Problem; import com.moplus.moplus_server.domain.problem.repository.ProblemRepository; import com.moplus.moplus_server.domain.problemset.repository.ProblemSetRepository; @@ -116,4 +120,27 @@ private String getMainProblemImageUrl(Long problemSetId) { .map(Problem::getMainProblemImageUrl) .orElse(null); } + + @Transactional(readOnly = true) + public ProblemClientGetResponse getProblem(Long publishId, Long problemId) { + Long memberId = 1L; + + Problem problem = problemRepository.findByIdElseThrow(problemId); + + // 문항 제출 조회 + ProblemSubmit problemSubmit = problemSubmitRepository.findByMemberIdAndPublishIdAndProblemIdElseThrow(memberId, + publishId, problemId); + + // 새끼 문항 제출 상태 조회 + List childProblemIds = problem.getChildProblems().stream() + .map(ChildProblem::getId) + .toList(); + + List childProblemStatuses = childProblemSubmitRepository.findAllByMemberIdAndPublishIdAndChildProblemIdIn( + memberId, publishId, childProblemIds).stream() + .map(ChildProblemSubmit::getStatus) + .toList(); + + return ProblemClientGetResponse.of(problem, problemSubmit.getStatus(), childProblemStatuses); + } } From f39d543ae2276296622b26f107ba44032a5f0abb Mon Sep 17 00:00:00 2001 From: HongGit Date: Tue, 18 Mar 2025 23:22:22 +0900 Subject: [PATCH 09/14] =?UTF-8?q?[feat/#94]=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=EC=83=88=EB=81=BC=EB=AC=B8=ED=95=AD=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ClientGetController.java | 11 ++++++++ .../ChildProblemClientGetResponse.java | 23 ++++++++++++++++ .../submit/service/ClientGetService.java | 27 +++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/dto/response/ChildProblemClientGetResponse.java diff --git a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java index ca579ba..d741a79 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java @@ -1,6 +1,7 @@ package com.moplus.moplus_server.client.submit.controller; import com.moplus.moplus_server.client.submit.dto.response.AllProblemGetResponse; +import com.moplus.moplus_server.client.submit.dto.response.ChildProblemClientGetResponse; import com.moplus.moplus_server.client.submit.dto.response.CommentaryGetResponse; import com.moplus.moplus_server.client.submit.dto.response.ProblemClientGetResponse; import com.moplus.moplus_server.client.submit.service.ClientGetService; @@ -49,4 +50,14 @@ public ResponseEntity getProblem( ) { return ResponseEntity.ok(clientGetService.getProblem(publishId, problemId)); } + + @GetMapping("problem/{publishId}/{problemId}/{childProblemId}") + @Operation(summary = "새끼문항 조회", description = "사용자에게 보여지는 새끼문항을 조회합니다.") + public ResponseEntity getChildProblem( + @PathVariable Long publishId, + @PathVariable Long problemId, + @PathVariable Long childProblemId + ) { + return ResponseEntity.ok(clientGetService.getChildProblem(publishId, problemId, childProblemId)); + } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ChildProblemClientGetResponse.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ChildProblemClientGetResponse.java new file mode 100644 index 0000000..f299d37 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ChildProblemClientGetResponse.java @@ -0,0 +1,23 @@ +package com.moplus.moplus_server.client.submit.dto.response; + +import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmitStatus; +import lombok.Builder; + +@Builder +public record ChildProblemClientGetResponse( + int problemNumber, + int childProblemNumber, + String imageUrl, + ChildProblemSubmitStatus status +) { + public static ChildProblemClientGetResponse of(int problemNumber, int childProblemNumber, String imageUrl, + ChildProblemSubmitStatus status + ) { + return ChildProblemClientGetResponse.builder() + .problemNumber(problemNumber) + .childProblemNumber(childProblemNumber) + .imageUrl(imageUrl) + .status(status) + .build(); + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java index d22c3f6..3b34e83 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java @@ -7,6 +7,7 @@ import com.moplus.moplus_server.client.submit.domain.ProblemSubmit; import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; import com.moplus.moplus_server.client.submit.dto.response.AllProblemGetResponse; +import com.moplus.moplus_server.client.submit.dto.response.ChildProblemClientGetResponse; import com.moplus.moplus_server.client.submit.dto.response.ChildProblemDetailResponse; import com.moplus.moplus_server.client.submit.dto.response.CommentaryGetResponse; import com.moplus.moplus_server.client.submit.dto.response.DayProgress; @@ -17,6 +18,7 @@ import com.moplus.moplus_server.client.submit.repository.ProblemSubmitRepository; import com.moplus.moplus_server.domain.problem.domain.childProblem.ChildProblem; import com.moplus.moplus_server.domain.problem.domain.problem.Problem; +import com.moplus.moplus_server.domain.problem.repository.ChildProblemRepository; import com.moplus.moplus_server.domain.problem.repository.ProblemRepository; import com.moplus.moplus_server.domain.problemset.repository.ProblemSetRepository; import com.moplus.moplus_server.domain.publish.repository.PublishRepository; @@ -38,6 +40,7 @@ public class ClientGetService { private final ProblemRepository problemRepository; private final ProblemSetRepository problemSetRepository; private final ChildProblemSubmitRepository childProblemSubmitRepository; + private final ChildProblemRepository childProblemRepository; @Transactional(readOnly = true) @@ -125,6 +128,7 @@ private String getMainProblemImageUrl(Long problemSetId) { public ProblemClientGetResponse getProblem(Long publishId, Long problemId) { Long memberId = 1L; + // 문항조회 Problem problem = problemRepository.findByIdElseThrow(problemId); // 문항 제출 조회 @@ -143,4 +147,27 @@ public ProblemClientGetResponse getProblem(Long publishId, Long problemId) { return ProblemClientGetResponse.of(problem, problemSubmit.getStatus(), childProblemStatuses); } + + @Transactional(readOnly = true) + public ChildProblemClientGetResponse getChildProblem(Long publishId, Long problemId, Long childProblemId) { + Long memberId = 1L; + + // 문항/새끼문항 조회 + Problem problem = problemRepository.findByIdElseThrow(problemId); + ChildProblem childProblem = childProblemRepository.findByIdElseThrow(childProblemId); + + // 새끼문항 제출 조회 + ChildProblemSubmit childProblemSubmit = childProblemSubmitRepository.findByMemberIdAndPublishIdAndChildProblemIdElseThrow( + memberId, publishId, childProblemId); + + int sequence = 0; + for (int i = 0; i < problem.getChildProblems().size(); i++) { + if (problem.getChildProblems().get(i).getId().equals(childProblemId)) { + sequence = i + 1; + break; + } + } + + return ChildProblemClientGetResponse.of(problem.getNumber(), sequence, childProblem.getImageUrl(), childProblemSubmit.getStatus()); + } } From a81ec80debb66d4f1cd3a7c050597eb6addc0b89 Mon Sep 17 00:00:00 2001 From: HongGit Date: Sat, 22 Mar 2025 17:34:42 +0900 Subject: [PATCH 10/14] =?UTF-8?q?[fix/#94]=20=EC=98=A4=EB=8A=98=20?= =?UTF-8?q?=EC=9D=B4=ED=9B=84=20=EB=B0=9C=ED=96=89=EC=9D=80=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=95=88=EB=90=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../submit/service/ClientGetService.java | 26 ++++++++++++++++--- .../global/error/exception/ErrorCode.java | 1 + 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java index 3b34e83..446bdbe 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java @@ -42,11 +42,14 @@ public class ClientGetService { private final ChildProblemSubmitRepository childProblemSubmitRepository; private final ChildProblemRepository childProblemRepository; - @Transactional(readOnly = true) public CommentaryGetResponse getCommentary(Long publishId, Long problemId) { Long memberId = 1L; + // 발행 조회 + Publish publish = publishRepository.findByIdElseThrow(publishId); + denyAccessToFuturePublish(publish); + // 문항 제출 조회 ProblemSubmit problemSubmit = problemSubmitRepository.findByMemberIdAndPublishIdAndProblemIdElseThrow(memberId, publishId, problemId); @@ -93,7 +96,10 @@ public List getAllProblem(int year, int month) { LocalDate endDate = startDate.withDayOfMonth(startDate.lengthOfMonth()); // 해당 월 모든 Publish 조회 - List publishes = publishRepository.findByPublishedDateBetween(startDate, endDate); + // 오늘 이후 발행이 있다면 필터링 + List publishes = publishRepository.findByPublishedDateBetween(startDate, endDate).stream() + .filter(publish -> !publish.getPublishedDate().isAfter(LocalDate.now())) + .toList(); List result = new ArrayList<>(); @@ -104,7 +110,7 @@ public List getAllProblem(int year, int month) { // 날짜별 사용자 제출 정보 조회 List submissions = problemSubmitRepository.findByMemberIdAndPublishId(memberId, publishId); List problemStatuses = submissions.stream() - .map(ProblemSubmit::getStatus) + .map(ProblemSubmit::getStatus ) .toList(); // 사용자 제출 정보 바탕으로 진행도 결정 @@ -128,6 +134,10 @@ private String getMainProblemImageUrl(Long problemSetId) { public ProblemClientGetResponse getProblem(Long publishId, Long problemId) { Long memberId = 1L; + // 발행 조회 + Publish publish = publishRepository.findByIdElseThrow(publishId); + denyAccessToFuturePublish(publish); + // 문항조회 Problem problem = problemRepository.findByIdElseThrow(problemId); @@ -152,6 +162,10 @@ public ProblemClientGetResponse getProblem(Long publishId, Long problemId) { public ChildProblemClientGetResponse getChildProblem(Long publishId, Long problemId, Long childProblemId) { Long memberId = 1L; + // 발행 조회 + Publish publish = publishRepository.findByIdElseThrow(publishId); + denyAccessToFuturePublish(publish); + // 문항/새끼문항 조회 Problem problem = problemRepository.findByIdElseThrow(problemId); ChildProblem childProblem = childProblemRepository.findByIdElseThrow(childProblemId); @@ -170,4 +184,10 @@ public ChildProblemClientGetResponse getChildProblem(Long publishId, Long proble return ChildProblemClientGetResponse.of(problem.getNumber(), sequence, childProblem.getImageUrl(), childProblemSubmit.getStatus()); } + + private void denyAccessToFuturePublish(Publish publish){ + if (publish.getPublishedDate().isAfter(LocalDate.now())) { + throw new InvalidValueException(ErrorCode.FUTURE_PUBLISH_NOT_ACCESSIBLE); + } + } } diff --git a/src/main/java/com/moplus/moplus_server/global/error/exception/ErrorCode.java b/src/main/java/com/moplus/moplus_server/global/error/exception/ErrorCode.java index 193b4f6..eadf888 100644 --- a/src/main/java/com/moplus/moplus_server/global/error/exception/ErrorCode.java +++ b/src/main/java/com/moplus/moplus_server/global/error/exception/ErrorCode.java @@ -76,6 +76,7 @@ public enum ErrorCode { ALREADY_PUBLISHED_ERROR(HttpStatus.BAD_REQUEST, "이미 발행된 문항세트는 컨펌해제할 수 없습니다."), PROBLEM_SET_DELETED(HttpStatus.BAD_REQUEST, "삭제된 문항세트는 발행할 수 없습니다"), PROBLEM_SET_NOT_CONFIRMED(HttpStatus.BAD_REQUEST, "컨펌되지 않은 문항세트는 발행할 수 없습니다"), + FUTURE_PUBLISH_NOT_ACCESSIBLE(HttpStatus.BAD_REQUEST, "오늘 이후의 발행을 조회할 수 없습니다."), // 문항 제출 PROBLEM_SUBMIT_NOT_CONFIRMED(HttpStatus.NOT_FOUND, "문항 제출 정보를 찾을 수 없습니다."), From 67a9f0ad8fecbe8cb0ef84f4e40f2b74fab03257 Mon Sep 17 00:00:00 2001 From: HongGit Date: Sat, 22 Mar 2025 17:48:11 +0900 Subject: [PATCH 11/14] =?UTF-8?q?[fix/#94]=20=EB=AC=B8=ED=95=AD=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20sequence=20=EA=B8=B0=EC=A4=80=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/ProblemClientGetResponse.java | 4 ++-- .../submit/service/ClientGetService.java | 23 +++++++++++++++++-- .../global/error/exception/ErrorCode.java | 1 + 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemClientGetResponse.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemClientGetResponse.java index 40d73e5..5ab0f5b 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemClientGetResponse.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemClientGetResponse.java @@ -15,9 +15,9 @@ public record ProblemClientGetResponse( ProblemSubmitStatus status, List childProblemStatuses ) { - public static ProblemClientGetResponse of(Problem problem, ProblemSubmitStatus status, List childProblemStatuses) { + public static ProblemClientGetResponse of(Problem problem, ProblemSubmitStatus status, List childProblemStatuses, int number) { return ProblemClientGetResponse.builder() - .number(problem.getNumber()) + .number(number) .imageUrl(problem.getMainProblemImageUrl()) .status(status) .childProblemStatuses(childProblemStatuses) diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java index 446bdbe..472455d 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java @@ -20,13 +20,16 @@ import com.moplus.moplus_server.domain.problem.domain.problem.Problem; import com.moplus.moplus_server.domain.problem.repository.ChildProblemRepository; import com.moplus.moplus_server.domain.problem.repository.ProblemRepository; +import com.moplus.moplus_server.domain.problemset.domain.ProblemSet; import com.moplus.moplus_server.domain.problemset.repository.ProblemSetRepository; import com.moplus.moplus_server.domain.publish.repository.PublishRepository; import com.moplus.moplus_server.global.error.exception.ErrorCode; import com.moplus.moplus_server.global.error.exception.InvalidValueException; +import com.moplus.moplus_server.global.error.exception.NotFoundException; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import javax.swing.undo.CannotUndoException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -74,8 +77,16 @@ public CommentaryGetResponse getCommentary(Long publishId, Long problemId) { // 처방 정보 생성 PrescriptionResponse prescription = PrescriptionResponse.of(childProblem, mainProblem); + // 문항 번호 추출 + ProblemSet problemSet = problemSetRepository.findByIdElseThrow(publish.getProblemSetId()); + List problemIds = problemSet.getProblemIds(); + int number = problemIds.indexOf(problemId); + if (number == -1) { + throw new NotFoundException(ErrorCode.PROBLEM_NOT_FOUND_IN_PROBLEM_SET); + } + return CommentaryGetResponse.of( - problem.getNumber(), + number + 1, problem.getAnswer(), problem.getMainAnalysisImageUrl(), problem.getMainHandwritingExplanationImageUrl(), @@ -138,6 +149,14 @@ public ProblemClientGetResponse getProblem(Long publishId, Long problemId) { Publish publish = publishRepository.findByIdElseThrow(publishId); denyAccessToFuturePublish(publish); + // 문항 번호 추출 + ProblemSet problemSet = problemSetRepository.findByIdElseThrow(publish.getProblemSetId()); + List problemIds = problemSet.getProblemIds(); + int number = problemIds.indexOf(problemId); + if (number == -1) { + throw new NotFoundException(ErrorCode.PROBLEM_NOT_FOUND_IN_PROBLEM_SET); + } + // 문항조회 Problem problem = problemRepository.findByIdElseThrow(problemId); @@ -155,7 +174,7 @@ public ProblemClientGetResponse getProblem(Long publishId, Long problemId) { .map(ChildProblemSubmit::getStatus) .toList(); - return ProblemClientGetResponse.of(problem, problemSubmit.getStatus(), childProblemStatuses); + return ProblemClientGetResponse.of(problem, problemSubmit.getStatus(), childProblemStatuses, number + 1); } @Transactional(readOnly = true) diff --git a/src/main/java/com/moplus/moplus_server/global/error/exception/ErrorCode.java b/src/main/java/com/moplus/moplus_server/global/error/exception/ErrorCode.java index eadf888..9f7f67a 100644 --- a/src/main/java/com/moplus/moplus_server/global/error/exception/ErrorCode.java +++ b/src/main/java/com/moplus/moplus_server/global/error/exception/ErrorCode.java @@ -34,6 +34,7 @@ public enum ErrorCode { INVALID_SHORT_NUMBER_ANSWER(HttpStatus.BAD_REQUEST, "주관식 문항의 정답은 0~999 사이의 숫자여야 합니다"), INVALID_CONFIRM_PROBLEM(HttpStatus.BAD_REQUEST, "유효하지 않은 문항들 : "), INVALID_DIFFICULTY(HttpStatus.BAD_REQUEST, "난이도는 1~10 사이의 숫자여야 합니다"), + PROBLEM_NOT_FOUND_IN_PROBLEM_SET(HttpStatus.NOT_FOUND, "해당 날짜에 발행된 문항세트에 존재하는 문항이 아닙니다."), //새끼 문항 CHILD_PROBLEM_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 새끼 문제를 찾을 수 없습니다"), From 68aac4dfaf2ef47999036a6e639ea7fb1c08bb65 Mon Sep 17 00:00:00 2001 From: HongGit Date: Sat, 22 Mar 2025 18:35:34 +0900 Subject: [PATCH 12/14] =?UTF-8?q?[fix/#94]=20=ED=81=B4=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EC=96=B8=ED=8A=B8=20=ED=8C=A8=ED=82=A4=EC=A7=95=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CommentaryGetController.java | 30 ++++++ ...troller.java => ProblemGetController.java} | 27 ++---- .../domain/ChildProblemSubmitStatus.java | 15 ++- .../submit/domain/ProblemSubmitStatus.java | 15 ++- .../submit/service/CommentaryGetService.java | 91 +++++++++++++++++++ ...etService.java => ProblemsGetService.java} | 58 +----------- 6 files changed, 142 insertions(+), 94 deletions(-) create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/controller/CommentaryGetController.java rename src/main/java/com/moplus/moplus_server/client/submit/controller/{ClientGetController.java => ProblemGetController.java} (61%) create mode 100644 src/main/java/com/moplus/moplus_server/client/submit/service/CommentaryGetService.java rename src/main/java/com/moplus/moplus_server/client/submit/service/{ClientGetService.java => ProblemsGetService.java} (73%) diff --git a/src/main/java/com/moplus/moplus_server/client/submit/controller/CommentaryGetController.java b/src/main/java/com/moplus/moplus_server/client/submit/controller/CommentaryGetController.java new file mode 100644 index 0000000..b46ad78 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/controller/CommentaryGetController.java @@ -0,0 +1,30 @@ +package com.moplus.moplus_server.client.submit.controller; + +import com.moplus.moplus_server.client.submit.dto.response.CommentaryGetResponse; +import com.moplus.moplus_server.client.submit.service.CommentaryGetService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "클라이언트 해설 조회", description = "클라이언트 해설 조회 관련 API") +@RestController +@RequestMapping("/api/v1/client") +@RequiredArgsConstructor +public class CommentaryGetController { + + private final CommentaryGetService commentaryGetService; + + @GetMapping("commentary") + @Operation(summary = "해설 조회", description = "문항 별 해설/처방을 조회합니다.") + public ResponseEntity getCommentary( + @RequestParam(value = "publishId", required = false) Long publishId, + @RequestParam(value = "problemId", required = false) Long problemId + ) { + return ResponseEntity.ok(commentaryGetService.getCommentary(publishId, problemId)); + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java b/src/main/java/com/moplus/moplus_server/client/submit/controller/ProblemGetController.java similarity index 61% rename from src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java rename to src/main/java/com/moplus/moplus_server/client/submit/controller/ProblemGetController.java index d741a79..0f2ee30 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/controller/ClientGetController.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/controller/ProblemGetController.java @@ -2,9 +2,8 @@ import com.moplus.moplus_server.client.submit.dto.response.AllProblemGetResponse; import com.moplus.moplus_server.client.submit.dto.response.ChildProblemClientGetResponse; -import com.moplus.moplus_server.client.submit.dto.response.CommentaryGetResponse; import com.moplus.moplus_server.client.submit.dto.response.ProblemClientGetResponse; -import com.moplus.moplus_server.client.submit.service.ClientGetService; +import com.moplus.moplus_server.client.submit.service.ProblemsGetService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import java.util.List; @@ -13,33 +12,23 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -@Tag(name = "클라이언트 조회", description = "클라이언트 조회 관련 API") +@Tag(name = "클라이언트 문제 조회", description = "클라이언트 문제 조회 관련 API") @RestController @RequestMapping("/api/v1/client") @RequiredArgsConstructor -public class ClientGetController { +public class ProblemGetController { - private final ClientGetService clientGetService; + private final ProblemsGetService problemsGetService; - @GetMapping("commentary") - @Operation(summary = "해설 조회", description = "문항 별 해설/처방을 조회합니다.") - public ResponseEntity getCommentary( - @RequestParam(value = "publishId", required = false) Long publishId, - @RequestParam(value = "problemId", required = false) Long problemId - ) { - return ResponseEntity.ok(clientGetService.getCommentary(publishId, problemId)); - } - - @GetMapping("allProblem/{year}/{month}") + @GetMapping("problem/all/{year}/{month}") @Operation(summary = "전체 문제 조회", description = "월별 문제들에 대한 진행도와 정보들을 조회합니다.") public ResponseEntity> getAllProblem( @PathVariable int year, @PathVariable int month ) { - return ResponseEntity.ok(clientGetService.getAllProblem(year, month)); + return ResponseEntity.ok(problemsGetService.getAllProblem(year, month)); } @GetMapping("problem/{publishId}/{problemId}") @@ -48,7 +37,7 @@ public ResponseEntity getProblem( @PathVariable Long publishId, @PathVariable Long problemId ) { - return ResponseEntity.ok(clientGetService.getProblem(publishId, problemId)); + return ResponseEntity.ok(problemsGetService.getProblem(publishId, problemId)); } @GetMapping("problem/{publishId}/{problemId}/{childProblemId}") @@ -58,6 +47,6 @@ public ResponseEntity getChildProblem( @PathVariable Long problemId, @PathVariable Long childProblemId ) { - return ResponseEntity.ok(clientGetService.getChildProblem(publishId, problemId, childProblemId)); + return ResponseEntity.ok(problemsGetService.getChildProblem(publishId, problemId, childProblemId)); } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmitStatus.java b/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmitStatus.java index fb15456..c869d59 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmitStatus.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/domain/ChildProblemSubmitStatus.java @@ -8,14 +8,11 @@ public enum ChildProblemSubmitStatus { public static ChildProblemSubmitStatus determineStatus(ChildProblemSubmitStatus currentStatus, String memberAnswer, String childProblemAnswer) { boolean isCorrect = childProblemAnswer.trim().equals(memberAnswer.trim()); - if (currentStatus == CORRECT) { - return isCorrect ? CORRECT : INCORRECT; - } else if (currentStatus == INCORRECT) { - return isCorrect ? RETRY_CORRECT : INCORRECT; - } else if (currentStatus == RETRY_CORRECT) { - return isCorrect ? RETRY_CORRECT : INCORRECT; - } else { - return isCorrect ? CORRECT : INCORRECT; - } + return switch (currentStatus) { + case CORRECT -> isCorrect ? CORRECT : INCORRECT; + case INCORRECT -> isCorrect ? RETRY_CORRECT : INCORRECT; + case RETRY_CORRECT -> isCorrect ? RETRY_CORRECT : INCORRECT; + default -> isCorrect ? CORRECT : INCORRECT; + }; } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/domain/ProblemSubmitStatus.java b/src/main/java/com/moplus/moplus_server/client/submit/domain/ProblemSubmitStatus.java index be01991..34bb4d4 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/domain/ProblemSubmitStatus.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/domain/ProblemSubmitStatus.java @@ -8,14 +8,11 @@ public enum ProblemSubmitStatus { public static ProblemSubmitStatus determineStatus(ProblemSubmitStatus currentStatus, String memberAnswer, String problemAnswer) { boolean isCorrect = problemAnswer.trim().equals(memberAnswer.trim()); - if (currentStatus == CORRECT) { - return isCorrect ? CORRECT : INCORRECT; - } else if (currentStatus == INCORRECT) { - return isCorrect ? RETRY_CORRECT : INCORRECT; - } else if (currentStatus == IN_PROGRESS) { - return isCorrect ? CORRECT : INCORRECT; - } else { - return isCorrect ? RETRY_CORRECT : INCORRECT; - } + return switch (currentStatus) { + case CORRECT -> isCorrect ? CORRECT : INCORRECT; + case INCORRECT -> isCorrect ? RETRY_CORRECT : INCORRECT; + case IN_PROGRESS -> isCorrect ? CORRECT : INCORRECT; + default -> isCorrect ? RETRY_CORRECT : INCORRECT; + }; } } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/CommentaryGetService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/CommentaryGetService.java new file mode 100644 index 0000000..11cdd25 --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/CommentaryGetService.java @@ -0,0 +1,91 @@ +package com.moplus.moplus_server.client.submit.service; + +import com.moplus.moplus_server.admin.publish.domain.Publish; +import com.moplus.moplus_server.client.submit.domain.ProblemSubmit; +import com.moplus.moplus_server.client.submit.dto.response.ChildProblemDetailResponse; +import com.moplus.moplus_server.client.submit.dto.response.CommentaryGetResponse; +import com.moplus.moplus_server.client.submit.dto.response.PrescriptionResponse; +import com.moplus.moplus_server.client.submit.dto.response.ProblemDetailResponse; +import com.moplus.moplus_server.client.submit.repository.ChildProblemSubmitRepository; +import com.moplus.moplus_server.client.submit.repository.ProblemSubmitRepository; +import com.moplus.moplus_server.domain.problem.domain.problem.Problem; +import com.moplus.moplus_server.domain.problem.repository.ProblemRepository; +import com.moplus.moplus_server.domain.problemset.domain.ProblemSet; +import com.moplus.moplus_server.domain.problemset.repository.ProblemSetRepository; +import com.moplus.moplus_server.domain.publish.repository.PublishRepository; +import com.moplus.moplus_server.global.error.exception.ErrorCode; +import com.moplus.moplus_server.global.error.exception.InvalidValueException; +import com.moplus.moplus_server.global.error.exception.NotFoundException; +import java.time.LocalDate; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class CommentaryGetService { + + private final PublishRepository publishRepository; + private final ProblemSubmitRepository problemSubmitRepository; + private final ProblemRepository problemRepository; + private final ProblemSetRepository problemSetRepository; + private final ChildProblemSubmitRepository childProblemSubmitRepository; + + @Transactional(readOnly = true) + public CommentaryGetResponse getCommentary(Long publishId, Long problemId) { + Long memberId = 1L; + + // 발행 조회 + Publish publish = publishRepository.findByIdElseThrow(publishId); + denyAccessToFuturePublish(publish); + + // 문항 제출 조회 + ProblemSubmit problemSubmit = problemSubmitRepository.findByMemberIdAndPublishIdAndProblemIdElseThrow(memberId, + publishId, problemId); + + // 문항 해설 생성 + Problem problem = problemRepository.findByIdElseThrow(problemId); + ProblemDetailResponse mainProblem = ProblemDetailResponse.of( + problem.getMainProblemImageUrl(), + problem.getPrescriptionImageUrls(), + problemSubmit.getStatus() + ); + + // 새끼문항 해설 생성 + List childProblem = problem.getChildProblems().stream() + .map(cp -> ChildProblemDetailResponse.of( + cp.getImageUrl(), + cp.getPrescriptionImageUrls(), + childProblemSubmitRepository.findByMemberIdAndPublishIdAndChildProblemIdElseThrow(memberId, publishId, + cp.getId()).getStatus() + )).toList(); + + // 처방 정보 생성 + PrescriptionResponse prescription = PrescriptionResponse.of(childProblem, mainProblem); + + // 문항 번호 추출 + ProblemSet problemSet = problemSetRepository.findByIdElseThrow(publish.getProblemSetId()); + List problemIds = problemSet.getProblemIds(); + int number = problemIds.indexOf(problemId); + if (number == -1) { + throw new NotFoundException(ErrorCode.PROBLEM_NOT_FOUND_IN_PROBLEM_SET); + } + + return CommentaryGetResponse.of( + number + 1, + problem.getAnswer(), + problem.getMainAnalysisImageUrl(), + problem.getMainHandwritingExplanationImageUrl(), + problem.getReadingTipImageUrl(), + problem.getSeniorTipImageUrl(), + prescription + ); + } + + private void denyAccessToFuturePublish(Publish publish){ + if (publish.getPublishedDate().isAfter(LocalDate.now())) { + throw new InvalidValueException(ErrorCode.FUTURE_PUBLISH_NOT_ACCESSIBLE); + } + } +} diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ProblemsGetService.java similarity index 73% rename from src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java rename to src/main/java/com/moplus/moplus_server/client/submit/service/ProblemsGetService.java index 472455d..49d1af1 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/ClientGetService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ProblemsGetService.java @@ -8,12 +8,8 @@ import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; import com.moplus.moplus_server.client.submit.dto.response.AllProblemGetResponse; import com.moplus.moplus_server.client.submit.dto.response.ChildProblemClientGetResponse; -import com.moplus.moplus_server.client.submit.dto.response.ChildProblemDetailResponse; -import com.moplus.moplus_server.client.submit.dto.response.CommentaryGetResponse; import com.moplus.moplus_server.client.submit.dto.response.DayProgress; -import com.moplus.moplus_server.client.submit.dto.response.PrescriptionResponse; import com.moplus.moplus_server.client.submit.dto.response.ProblemClientGetResponse; -import com.moplus.moplus_server.client.submit.dto.response.ProblemDetailResponse; import com.moplus.moplus_server.client.submit.repository.ChildProblemSubmitRepository; import com.moplus.moplus_server.client.submit.repository.ProblemSubmitRepository; import com.moplus.moplus_server.domain.problem.domain.childProblem.ChildProblem; @@ -29,14 +25,13 @@ import java.time.LocalDate; import java.util.ArrayList; import java.util.List; -import javax.swing.undo.CannotUndoException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor -public class ClientGetService { +public class ProblemsGetService { private final PublishRepository publishRepository; private final ProblemSubmitRepository problemSubmitRepository; @@ -45,57 +40,6 @@ public class ClientGetService { private final ChildProblemSubmitRepository childProblemSubmitRepository; private final ChildProblemRepository childProblemRepository; - @Transactional(readOnly = true) - public CommentaryGetResponse getCommentary(Long publishId, Long problemId) { - Long memberId = 1L; - - // 발행 조회 - Publish publish = publishRepository.findByIdElseThrow(publishId); - denyAccessToFuturePublish(publish); - - // 문항 제출 조회 - ProblemSubmit problemSubmit = problemSubmitRepository.findByMemberIdAndPublishIdAndProblemIdElseThrow(memberId, - publishId, problemId); - - // 문항 해설 생성 - Problem problem = problemRepository.findByIdElseThrow(problemId); - ProblemDetailResponse mainProblem = ProblemDetailResponse.of( - problem.getMainProblemImageUrl(), - problem.getPrescriptionImageUrls(), - problemSubmit.getStatus() - ); - - // 새끼문항 해설 생성 - List childProblem = problem.getChildProblems().stream() - .map(cp -> ChildProblemDetailResponse.of( - cp.getImageUrl(), - cp.getPrescriptionImageUrls(), - childProblemSubmitRepository.findByMemberIdAndPublishIdAndChildProblemIdElseThrow(memberId, publishId, - cp.getId()).getStatus() - )).toList(); - - // 처방 정보 생성 - PrescriptionResponse prescription = PrescriptionResponse.of(childProblem, mainProblem); - - // 문항 번호 추출 - ProblemSet problemSet = problemSetRepository.findByIdElseThrow(publish.getProblemSetId()); - List problemIds = problemSet.getProblemIds(); - int number = problemIds.indexOf(problemId); - if (number == -1) { - throw new NotFoundException(ErrorCode.PROBLEM_NOT_FOUND_IN_PROBLEM_SET); - } - - return CommentaryGetResponse.of( - number + 1, - problem.getAnswer(), - problem.getMainAnalysisImageUrl(), - problem.getMainHandwritingExplanationImageUrl(), - problem.getReadingTipImageUrl(), - problem.getSeniorTipImageUrl(), - prescription - ); - } - @Transactional(readOnly = true) public List getAllProblem(int year, int month) { Long memberId = 1L; From f612ecbe87c5ad92aa17dd4217899b1387b53f88 Mon Sep 17 00:00:00 2001 From: HongGit Date: Sun, 23 Mar 2025 20:40:48 +0900 Subject: [PATCH 13/14] =?UTF-8?q?[fix/#94]=20Dto=20mapper=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/CommentaryGetResponse.java | 15 +++++++-------- .../dto/response/ProblemDetailResponse.java | 7 ++++--- .../submit/service/CommentaryGetService.java | 9 ++------- .../client/submit/service/ProblemsGetService.java | 14 +++++++++++--- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/CommentaryGetResponse.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/CommentaryGetResponse.java index 5c0ba7c..e1b7c38 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/CommentaryGetResponse.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/CommentaryGetResponse.java @@ -1,5 +1,6 @@ package com.moplus.moplus_server.client.submit.dto.response; +import com.moplus.moplus_server.domain.problem.domain.problem.Problem; import lombok.Builder; @Builder @@ -12,16 +13,14 @@ public record CommentaryGetResponse( String seniorTipImageUrl, PrescriptionResponse prescription ) { - public static CommentaryGetResponse of(int problemNumber, String answer, String mainAnalysisImageUrl, - String mainHandwritingExplanationImageUrl, String readingTipImageUrl, - String seniorTipImageUrl, PrescriptionResponse prescription) { + public static CommentaryGetResponse of(int problemNumber, Problem problem, PrescriptionResponse prescription) { return CommentaryGetResponse.builder() .problemNumber(problemNumber) - .answer(answer) - .mainAnalysisImageUrl(mainAnalysisImageUrl) - .mainHandwritingExplanationImageUrl(mainHandwritingExplanationImageUrl) - .readingTipImageUrl(readingTipImageUrl) - .seniorTipImageUrl(seniorTipImageUrl) + .answer(problem.getAnswer()) + .mainAnalysisImageUrl(problem.getMainAnalysisImageUrl()) + .mainHandwritingExplanationImageUrl(problem.getMainHandwritingExplanationImageUrl()) + .readingTipImageUrl(problem.getReadingTipImageUrl()) + .seniorTipImageUrl(problem.getSeniorTipImageUrl()) .prescription(prescription) .build(); } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemDetailResponse.java b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemDetailResponse.java index aa31cf0..2b6f047 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemDetailResponse.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/dto/response/ProblemDetailResponse.java @@ -1,6 +1,7 @@ package com.moplus.moplus_server.client.submit.dto.response; import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus; +import com.moplus.moplus_server.domain.problem.domain.problem.Problem; import java.util.List; import lombok.Builder; @@ -10,10 +11,10 @@ public record ProblemDetailResponse( List prescriptionImageUrls, ProblemSubmitStatus submitStatus ) { - public static ProblemDetailResponse of(String imageUrl, List prescriptionImageUrls, ProblemSubmitStatus submitStatus) { + public static ProblemDetailResponse of(Problem problem, ProblemSubmitStatus submitStatus) { return ProblemDetailResponse.builder() - .imageUrl(imageUrl) - .prescriptionImageUrls(prescriptionImageUrls) + .imageUrl(problem.getMainProblemImageUrl()) + .prescriptionImageUrls(problem.getPrescriptionImageUrls()) .submitStatus(submitStatus) .build(); } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/CommentaryGetService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/CommentaryGetService.java index 11cdd25..cbbb914 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/CommentaryGetService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/CommentaryGetService.java @@ -47,8 +47,7 @@ public CommentaryGetResponse getCommentary(Long publishId, Long problemId) { // 문항 해설 생성 Problem problem = problemRepository.findByIdElseThrow(problemId); ProblemDetailResponse mainProblem = ProblemDetailResponse.of( - problem.getMainProblemImageUrl(), - problem.getPrescriptionImageUrls(), + problem, problemSubmit.getStatus() ); @@ -74,11 +73,7 @@ public CommentaryGetResponse getCommentary(Long publishId, Long problemId) { return CommentaryGetResponse.of( number + 1, - problem.getAnswer(), - problem.getMainAnalysisImageUrl(), - problem.getMainHandwritingExplanationImageUrl(), - problem.getReadingTipImageUrl(), - problem.getSeniorTipImageUrl(), + problem, prescription ); } diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ProblemsGetService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ProblemsGetService.java index 49d1af1..fc95938 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/ProblemsGetService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ProblemsGetService.java @@ -137,15 +137,23 @@ public ChildProblemClientGetResponse getChildProblem(Long publishId, Long proble ChildProblemSubmit childProblemSubmit = childProblemSubmitRepository.findByMemberIdAndPublishIdAndChildProblemIdElseThrow( memberId, publishId, childProblemId); - int sequence = 0; + int childProblemNumber = 0; for (int i = 0; i < problem.getChildProblems().size(); i++) { if (problem.getChildProblems().get(i).getId().equals(childProblemId)) { - sequence = i + 1; + childProblemNumber = i + 1; break; } } - return ChildProblemClientGetResponse.of(problem.getNumber(), sequence, childProblem.getImageUrl(), childProblemSubmit.getStatus()); + // 문항 번호 추출 + ProblemSet problemSet = problemSetRepository.findByIdElseThrow(publish.getProblemSetId()); + List problemIds = problemSet.getProblemIds(); + int problemNumber = problemIds.indexOf(problemId); + if (problemNumber == -1) { + throw new NotFoundException(ErrorCode.PROBLEM_NOT_FOUND_IN_PROBLEM_SET); + } + + return ChildProblemClientGetResponse.of(problemNumber + 1, childProblemNumber + 1, childProblem.getImageUrl(), childProblemSubmit.getStatus()); } private void denyAccessToFuturePublish(Publish publish){ From 5b2c7e43bda86977b5b1b7b497461963ccc6669c Mon Sep 17 00:00:00 2001 From: HongGit Date: Sun, 23 Mar 2025 20:43:50 +0900 Subject: [PATCH 14/14] =?UTF-8?q?[fix/#94]=20=EB=A7=A4=EC=A7=81=EB=84=98?= =?UTF-8?q?=EB=B2=84=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/submit/service/ProblemsGetService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/moplus/moplus_server/client/submit/service/ProblemsGetService.java b/src/main/java/com/moplus/moplus_server/client/submit/service/ProblemsGetService.java index fc95938..ecf174e 100644 --- a/src/main/java/com/moplus/moplus_server/client/submit/service/ProblemsGetService.java +++ b/src/main/java/com/moplus/moplus_server/client/submit/service/ProblemsGetService.java @@ -39,12 +39,14 @@ public class ProblemsGetService { private final ProblemSetRepository problemSetRepository; private final ChildProblemSubmitRepository childProblemSubmitRepository; private final ChildProblemRepository childProblemRepository; + private static final int MIN_MONTH = 1; + private static final int MAX_MONTH = 12; @Transactional(readOnly = true) public List getAllProblem(int year, int month) { Long memberId = 1L; - if (month < 1 || month > 12) { + if (month < MIN_MONTH || month > MAX_MONTH) { throw new InvalidValueException(ErrorCode.INVALID_MONTH_ERROR); } LocalDate startDate = LocalDate.of(year, month, 1);