From a4728a6eb53ea9c9852d1d99e9ac1371c9b0b9cd Mon Sep 17 00:00:00 2001 From: miiiinju1 Date: Thu, 21 Sep 2023 13:51:25 +0900 Subject: [PATCH] =?UTF-8?q?:recycle:=20[FIX]=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EC=8B=9C=ED=97=98=20=EC=A2=85=EB=A3=8C=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81=20#33?= =?UTF-8?q?1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/SolvedCheckService.java | 10 +- .../service/CalculateRatingService.java | 6 +- .../testExit/service/TestExitService.java | 39 +++++--- .../repository/TestTypeRepository.java | 4 +- .../testStart/service/AddTestService.java | 5 - .../service/SaveProblemsService.java | 4 - .../service/TestProgressCheckService.java | 66 +++++++++++++ .../testStart/service/TestStartUseCase.java | 93 ++++--------------- 8 files changed, 123 insertions(+), 104 deletions(-) create mode 100644 src/main/java/swm_nm/morandi/domain/testStart/service/TestProgressCheckService.java diff --git a/src/main/java/swm_nm/morandi/domain/testDuring/service/SolvedCheckService.java b/src/main/java/swm_nm/morandi/domain/testDuring/service/SolvedCheckService.java index 5a82d615..07f6dcee 100644 --- a/src/main/java/swm_nm/morandi/domain/testDuring/service/SolvedCheckService.java +++ b/src/main/java/swm_nm/morandi/domain/testDuring/service/SolvedCheckService.java @@ -38,7 +38,9 @@ public class SolvedCheckService { public List isSolvedCheck(TestCheckDto testCheckDto) { Long testId = testCheckDto.getTestId(); String bojId = testCheckDto.getBojId(); - checkAttemptedProblemResult(testId, bojId); + Tests test = testRepository.findById(testId) + .orElseThrow(() -> new MorandiException(TestErrorCode.TEST_NOT_FOUND)); + checkAttemptedProblemResult(test, bojId); List attemptProblems = attemptProblemRepository.findAttemptProblemsByTest_TestId(testId); List attemptProblemDtos = new ArrayList<>(); long number = 1; @@ -51,9 +53,8 @@ public List isSolvedCheck(TestCheckDto testCheckDto) { } @Transactional - public void checkAttemptedProblemResult(Long testId, String bojId) { - Tests test = testRepository.findById(testId).orElseThrow(() -> new MorandiException(TestErrorCode.TEST_NOT_FOUND)); - List attemptProblems = attemptProblemRepository.findAttemptProblemsByTest_TestId(testId); + public void checkAttemptedProblemResult(Tests test, String bojId) { + List attemptProblems = attemptProblemRepository.findAttemptProblemsByTest_TestId(test.getTestId()); attemptProblems.stream() .filter(attemptProblem -> !attemptProblem.getIsSolved()) @@ -68,6 +69,7 @@ public void checkAttemptedProblemResult(Long testId, String bojId) { }); } + public boolean isSolvedProblem(AttemptProblem attemptProblem, String bojId) { Problem problem = attemptProblem.getProblem(); Long bojProblemId = problem.getBojProblemId(); diff --git a/src/main/java/swm_nm/morandi/domain/testExit/service/CalculateRatingService.java b/src/main/java/swm_nm/morandi/domain/testExit/service/CalculateRatingService.java index a9f16e35..b1f2febb 100644 --- a/src/main/java/swm_nm/morandi/domain/testExit/service/CalculateRatingService.java +++ b/src/main/java/swm_nm/morandi/domain/testExit/service/CalculateRatingService.java @@ -27,11 +27,9 @@ public class CalculateRatingService { private final TestRepository testRepository; @Transactional - public Long calculateTestRating(Member member, Long testId) { + public Long calculateTestRating(Member member, Tests test) { List attemptProblems - = attemptProblemRepository.findAttemptProblemsByTest_TestId(testId); - Tests test = testRepository.findById(testId) - .orElseThrow(() -> new MorandiException(TestErrorCode.TEST_NOT_FOUND)); + = attemptProblemRepository.findAttemptProblemsByTest_TestId(test.getTestId()); Integer problemCount = test.getProblemCount(); long rating = getRating(problemCount); long addRating = 0L; diff --git a/src/main/java/swm_nm/morandi/domain/testExit/service/TestExitService.java b/src/main/java/swm_nm/morandi/domain/testExit/service/TestExitService.java index e376dd75..e5966d23 100644 --- a/src/main/java/swm_nm/morandi/domain/testExit/service/TestExitService.java +++ b/src/main/java/swm_nm/morandi/domain/testExit/service/TestExitService.java @@ -43,16 +43,28 @@ public class TestExitService { private final CalculateRatingService calculateRatingService; private final SolvedCheckService solvedCheckService; + + //Controller에서 사용되는 것 + public List testExit(TestCheckDto testCheckDto) + { + Long memberId = SecurityUtils.getCurrentMemberId(); + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new MorandiException(AuthErrorCode.MEMBER_NOT_FOUND)); + Tests test = testRepository.findById(testCheckDto.getTestId()) + .orElseThrow(() -> new MorandiException(TestErrorCode.TEST_NOT_FOUND)); + TestType testType = testTypeRepository.findTestTypeByTestTypename(test.getTestTypename()) + .orElseThrow(() -> new MorandiException(TestTypeErrorCode.TEST_TYPE_NOT_FOUND)); + return testExit(testCheckDto,member,test,testType); + } + @Transactional - public List testExit(TestCheckDto testCheckDto) { - Long testId = testCheckDto.getTestId(); + public List testExit(TestCheckDto testCheckDto,Member member,Tests test,TestType testType) { String bojId = testCheckDto.getBojId(); - Long testTypeId = testCheckDto.getTestTypeId(); - solvedCheckService.checkAttemptedProblemResult(testId, bojId); - saveTestResult(testId, testTypeId); + solvedCheckService.checkAttemptedProblemResult(test, bojId); + saveTestResult(member,test, testType); - List attemptProblems = attemptProblemRepository.findAttemptProblemsByTest_TestId(testId); + List attemptProblems = attemptProblemRepository.findAttemptProblemsByTest_TestId(test.getTestId()); List attemptProblemDtos = new ArrayList<>(); long number = 1; @@ -65,13 +77,9 @@ public List testExit(TestCheckDto testCheckDto) { } @Transactional - public void saveTestResult(Long testId, Long testTypeId) { - Long memberId = SecurityUtils.getCurrentMemberId(); - Member member = memberRepository.findById(memberId).orElseThrow(() -> new MorandiException(AuthErrorCode.MEMBER_NOT_FOUND)); - Tests test = testRepository.findById(testId).orElseThrow(() -> new MorandiException(TestErrorCode.TEST_NOT_FOUND)); - TestType testType = testTypeRepository.findById(testTypeId).orElseThrow(() -> new MorandiException(TestTypeErrorCode.TEST_TYPE_NOT_FOUND)); + public void saveTestResult(Member member,Tests test, TestType testType) { test.setTestStatus(TestStatus.COMPLETED); - List attemptProblems = attemptProblemRepository.findAllByTest_TestId(testId); + List attemptProblems = attemptProblemRepository.findAllByTest_TestId(test.getTestId()); long correct = attemptProblems.stream() .filter(AttemptProblem::getIsSolved) .count(); @@ -81,8 +89,13 @@ public void saveTestResult(Long testId, Long testTypeId) { testType.updateAverageCorrectAnswerRate(correct / total); // 테스트 레이팅 저장 - test.setTestRating(calculateRatingService.calculateTestRating(member, testId)); + test.setTestRating(calculateRatingService.calculateTestRating(member, test)); member.setCurrentTestId(-1L); + + // 테스트 결과 저장 + testTypeRepository.save(testType); + testRepository.save(test); + memberRepository.save(member); } } diff --git a/src/main/java/swm_nm/morandi/domain/testInfo/repository/TestTypeRepository.java b/src/main/java/swm_nm/morandi/domain/testInfo/repository/TestTypeRepository.java index 30c6dd58..e3f0098a 100644 --- a/src/main/java/swm_nm/morandi/domain/testInfo/repository/TestTypeRepository.java +++ b/src/main/java/swm_nm/morandi/domain/testInfo/repository/TestTypeRepository.java @@ -2,6 +2,8 @@ import org.springframework.data.jpa.repository.JpaRepository; import swm_nm.morandi.domain.testExit.entity.TestType; -public interface TestTypeRepository extends JpaRepository { +import java.util.Optional; +public interface TestTypeRepository extends JpaRepository { + Optional findTestTypeByTestTypename(String testTypename); } diff --git a/src/main/java/swm_nm/morandi/domain/testStart/service/AddTestService.java b/src/main/java/swm_nm/morandi/domain/testStart/service/AddTestService.java index 3eb61ab0..b55e1d53 100644 --- a/src/main/java/swm_nm/morandi/domain/testStart/service/AddTestService.java +++ b/src/main/java/swm_nm/morandi/domain/testStart/service/AddTestService.java @@ -26,14 +26,9 @@ public class AddTestService { private final TestRepository testRepository; - private final TestTypeRepository testTypeRepository; - - private final MemberRepository memberRepository; - private final TestScheduler testScheduler; @Transactional public Tests startTestByTestTypeId(TestType testType, Member member) { - Tests test = Tests.builder() .testDate(LocalDateTime.now()) // 테스트가 시작된 시간 .testTime(testType.getTestTime()) diff --git a/src/main/java/swm_nm/morandi/domain/testStart/service/SaveProblemsService.java b/src/main/java/swm_nm/morandi/domain/testStart/service/SaveProblemsService.java index f82aad5a..8d1735d7 100644 --- a/src/main/java/swm_nm/morandi/domain/testStart/service/SaveProblemsService.java +++ b/src/main/java/swm_nm/morandi/domain/testStart/service/SaveProblemsService.java @@ -27,10 +27,6 @@ @Slf4j public class SaveProblemsService { - private final MemberRepository memberRepository; - - private final TestRepository testRepository; - private final ProblemRepository problemRepository; private final AttemptProblemRepository attemptProblemRepository; diff --git a/src/main/java/swm_nm/morandi/domain/testStart/service/TestProgressCheckService.java b/src/main/java/swm_nm/morandi/domain/testStart/service/TestProgressCheckService.java new file mode 100644 index 00000000..93c24b07 --- /dev/null +++ b/src/main/java/swm_nm/morandi/domain/testStart/service/TestProgressCheckService.java @@ -0,0 +1,66 @@ +package swm_nm.morandi.domain.testStart.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import swm_nm.morandi.domain.member.entity.Member; +import swm_nm.morandi.domain.testDuring.dto.TestCheckDto; +import swm_nm.morandi.domain.testExit.entity.TestType; +import swm_nm.morandi.domain.testExit.entity.Tests; +import swm_nm.morandi.domain.testExit.service.TestExitService; +import swm_nm.morandi.domain.testInfo.repository.TestRepository; +import swm_nm.morandi.domain.testInfo.repository.TestTypeRepository; +import swm_nm.morandi.global.exception.MorandiException; +import swm_nm.morandi.global.exception.errorcode.TestErrorCode; +import swm_nm.morandi.global.exception.errorcode.TestTypeErrorCode; + +import java.time.Duration; +import java.time.LocalDateTime; + +@Service +@RequiredArgsConstructor +public class TestProgressCheckService { + + private final TestRepository testRepository; + private final TestTypeRepository testTypeRepository; + private final TestExitService testExitService; + + private void extracted(Tests test) { + Duration duration = Duration.between(test.getTestDate(), LocalDateTime.now()); + test.setRemainingTime(test.getTestTime() * 60 - duration.getSeconds()); + } + + private void extracted(TestType testType, Member member, Tests test) { + TestCheckDto testCheckDto = TestCheckDto.builder() + .testId(test.getTestId()) + .testTypeId(testType.getTestTypeId()) + .bojId(member.getBojId()) + .build(); + testExitService.testExit(testCheckDto,member,test,testType); + } + + //TODO Redis 이용하여 + // 현재 테스트가 진행중인지 확인하도록 + public Tests isTestinProgress(Member member){ + if (member.getCurrentTestId() == null) + member.setCurrentTestId(-1L); + + // 현재 테스트가 진행중이라면 + if (member.getCurrentTestId() != -1) { + Long currentTestId = member.getCurrentTestId(); + Tests test = testRepository.findById(currentTestId).orElseThrow(() -> new MorandiException(TestErrorCode.TEST_NOT_FOUND)); + + // 테스트 시작 시간과 현재 시간을 비교하여 남은 시간 계산 + extracted(test); + + if (test.getRemainingTime() > 0) { // 시간이 남았을경우 진행중인 테스트 반환 + return test;//getTestStartResponseDto(currentTestId, test); + } + else { // 시간이 마감된 테스트 종료 + TestType testType = testTypeRepository.findTestTypeByTestTypename(test.getTestTypename()) + .orElseThrow(() -> new MorandiException(TestTypeErrorCode.TEST_TYPE_NOT_FOUND)); + extracted(testType, member, test); + } + } + return null; + } +} diff --git a/src/main/java/swm_nm/morandi/domain/testStart/service/TestStartUseCase.java b/src/main/java/swm_nm/morandi/domain/testStart/service/TestStartUseCase.java index 12543ecc..221b5c3b 100644 --- a/src/main/java/swm_nm/morandi/domain/testStart/service/TestStartUseCase.java +++ b/src/main/java/swm_nm/morandi/domain/testStart/service/TestStartUseCase.java @@ -40,26 +40,18 @@ public class TestStartUseCase { private final AddTestService addTestService; - private final GetProblemsService getProblemsService; - private final SaveProblemsService saveProblemsService; - private final TempCodeInitializer tempCodeInitializer; + private final MemberInfoService memberInfoService; + private final TestTypeRepository testTypeRepository; + private final TestProgressCheckService testProgressCheckService; private final MemberRepository memberRepository; - - private final TestRepository testRepository; - private final AttemptProblemRepository attemptProblemRepository; - private final ObjectMapper objectMapper; - - private final MemberInfoService memberInfoService; - - private final TestExitService testExitService; + //이미 테스트 중인지 확인 - private final TestTypeRepository testTypeRepository; public TestStartResponseDto getTestStartsData(Long testTypeId) { Long memberId = SecurityUtils.getCurrentMemberId(); @@ -67,43 +59,37 @@ public TestStartResponseDto getTestStartsData(Long testTypeId) { () -> new MorandiException(MemberErrorCode.MEMBER_NOT_FOUND)); //TODO Redis 이용하여 - // 현재 테스트가 진행중인지 확인하도록 - if (member.getCurrentTestId() == null) - member.setCurrentTestId(-1L); - - // 현재 테스트가 진행중이라면 - if (member.getCurrentTestId() != -1) { - Long currentTestId = member.getCurrentTestId(); - Tests test = testRepository.findById(currentTestId).orElseThrow(() -> new MorandiException(TestErrorCode.TEST_NOT_FOUND)); - - // 테스트 시작 시간과 현재 시간을 비교하여 남은 시간 계산 - extracted(test); - - if (test.getRemainingTime() > 0) { // 시간이 남았을경우 진행중인 테스트 반환 - return getTestStartResponseDto(currentTestId, test); - } - else { // 시간이 마감된 테스트 종료 - extracted(testTypeId, member, test); - } + //현재 테스트가 진행중인지 확인하도록 + //이미 테스트 중인지 확인 + Tests test = testProgressCheckService.isTestinProgress(member); + if(test!=null) + { + return getTestStartResponseDto(member.getCurrentTestId(), test); } - // 현재 진행중인 테스트가 없을 경우 아래 로직 진행 + + TestType testType = testTypeRepository.findById(testTypeId).orElseThrow(() -> new MorandiException(TestTypeErrorCode.TEST_TYPE_NOT_FOUND)); - Tests test = addTestService.startTestByTestTypeId(testType, member); + // 현재 진행중인 테스트가 없을 경우 테스트 타입에 맞는 테스트 시작 + test = addTestService.startTestByTestTypeId(testType, member); String bojId = memberInfoService.getMemberInfo().getBojId(); List bojProblems = new ArrayList<>(); + // 테스트 시작시 문제 가져오기 getProblemsService.getProblemsByTestType(testType, bojProblems); + + // API로 문제 가져오기 getProblemsService.getProblemsByApi(testType, bojId, bojProblems); + // 테스트 시작시 문제 저장 saveProblemsService.saveAttemptProblems(member, test, bojProblems); // 테스트 시작시 코드 캐시 초기화 tempCodeInitializer.initTempCodeCacheWhenTestStart(test); - TestStartResponseDto testStartResponseDto = getTestStartResponseDto(test, bojProblems); - return testStartResponseDto; + + return getTestStartResponseDto(test, bojProblems); } private static TestStartResponseDto getTestStartResponseDto(Tests test, List bojProblems) { @@ -119,19 +105,6 @@ private static TestStartResponseDto getTestStartResponseDto(Tests test, List attemptProblems = attemptProblemRepository.findAttemptProblemsByTest_TestId(currentTestId); List bojProblemIds = attemptProblems.stream().map(AttemptProblem::getProblem) @@ -146,30 +119,4 @@ private TestStartResponseDto getTestStartResponseDto(Long currentTestId, Tests t // 테스트 시작에 대한 ResponseDto 반환 return testStartResponseDto; } - - private boolean isSolvedProblem(AttemptProblem attemptProblem, String bojId) { - Problem problem = attemptProblem.getProblem(); - Long bojProblemId = problem.getBojProblemId(); - String apiURL = "https://solved.ac/api/v3/search/problem"; - String query = apiURL + "/?query=" + "id:" + bojProblemId.toString() + "%26@" + bojId; - - URI uri = URI.create(query); - - WebClient webClient = WebClient.builder().build(); - String jsonString = webClient.get() - .uri(uri) - .retrieve() - .bodyToMono(String.class) - .block(); - try { - JsonNode jsonNode = objectMapper.readTree(jsonString); - JsonNode checkNode = jsonNode.get("count"); - return checkNode.asLong() == 1L; - - } catch (NullPointerException e) { - throw new RuntimeException("Node null 반환했습니다."); - } catch (JsonProcessingException e) { - throw new RuntimeException("json 파싱에 실패했습니다."); - } - } }