From 53dde6d2123f51801e5ccfef70295a806237aa39 Mon Sep 17 00:00:00 2001 From: daydeuk Date: Tue, 18 Apr 2023 01:06:59 +0900 Subject: [PATCH] =?UTF-8?q?Refactor=20:=20=EC=BD=94=EB=93=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A5=98=EC=97=90=20=EB=A7=9E=EC=B6=B0=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81=20=EC=A7=84=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/UserServiceClient.java | 12 +- .../dto}/BaekjoonListResponseDto.java | 2 +- .../dto}/CommitResponseDto.java | 2 +- .../dto}/DateProblemResponseDto.java | 2 +- .../dto}/UserResponseDto.java | 2 +- .../controller/AlgoController.java | 53 ++ .../controller/AuthController.java | 14 +- .../controller/ChallengeController.java | 95 +--- .../controller/CommitController.java | 21 +- .../service/ChallengeService.java | 50 -- .../service/ChallengeServiceImpl.java | 515 ------------------ .../service/SchedulerService.java | 4 + .../service/SchedulerServiceImpl.java | 53 +- .../service/algo/AlgoChallengeService.java | 21 + .../algo/AlgoChallengeServiceImpl.java | 221 ++++++++ .../challenge/BasicChallengeService.java | 9 +- .../challenge/BasicChallengeServicelmpl.java | 158 +++++- .../commit/CommitChallengeService.java | 19 + .../commit/CommitChallengeServiceImpl.java | 148 +++++ .../service/common/CommonServiceImpl.java | 1 + 20 files changed, 738 insertions(+), 664 deletions(-) rename backend/challenge-service/src/main/java/com/example/challengeservice/{dto/response => client/dto}/BaekjoonListResponseDto.java (85%) rename backend/challenge-service/src/main/java/com/example/challengeservice/{dto/response => client/dto}/CommitResponseDto.java (85%) rename backend/challenge-service/src/main/java/com/example/challengeservice/{dto/response => client/dto}/DateProblemResponseDto.java (84%) rename backend/challenge-service/src/main/java/com/example/challengeservice/{dto/response => client/dto}/UserResponseDto.java (88%) create mode 100644 backend/challenge-service/src/main/java/com/example/challengeservice/controller/AlgoController.java delete mode 100644 backend/challenge-service/src/main/java/com/example/challengeservice/service/ChallengeService.java delete mode 100644 backend/challenge-service/src/main/java/com/example/challengeservice/service/ChallengeServiceImpl.java create mode 100644 backend/challenge-service/src/main/java/com/example/challengeservice/service/algo/AlgoChallengeService.java create mode 100644 backend/challenge-service/src/main/java/com/example/challengeservice/service/algo/AlgoChallengeServiceImpl.java create mode 100644 backend/challenge-service/src/main/java/com/example/challengeservice/service/commit/CommitChallengeService.java create mode 100644 backend/challenge-service/src/main/java/com/example/challengeservice/service/commit/CommitChallengeServiceImpl.java diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/client/UserServiceClient.java b/backend/challenge-service/src/main/java/com/example/challengeservice/client/UserServiceClient.java index 0e99cbb..c29f18f 100644 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/client/UserServiceClient.java +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/client/UserServiceClient.java @@ -1,14 +1,14 @@ package com.example.challengeservice.client; +import com.example.challengeservice.client.dto.BaekjoonListResponseDto; +import com.example.challengeservice.client.dto.CommitResponseDto; +import com.example.challengeservice.client.dto.DateProblemResponseDto; +import com.example.challengeservice.client.dto.UserResponseDto; import com.example.challengeservice.common.result.ListResult; import com.example.challengeservice.common.result.SingleResult; import com.example.challengeservice.dto.request.CommitRequestDto; import com.example.challengeservice.dto.request.ProblemRequestDto; -import com.example.challengeservice.dto.response.BaekjoonListResponseDto; -import com.example.challengeservice.dto.response.CommitResponseDto; -import com.example.challengeservice.dto.response.DateProblemResponseDto; -import com.example.challengeservice.dto.response.UserResponseDto; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*; @@ -25,10 +25,10 @@ public interface UserServiceClient { @GetMapping("/user/baekjoon/date/{userId}") ListResult getDateBaekjoonList(@PathVariable Long userId, - @RequestParam("startDate") String startDate,@RequestParam("endDate") String endDate); + @RequestParam("startDate") String startDate, @RequestParam("endDate") String endDate); @GetMapping("/user/commit/{userId}/{commitDate}") SingleResult getCommitRecord(@PathVariable("userId") Long userId, - @PathVariable("commitDate") String commitDate); + @PathVariable("commitDate") String commitDate); @PostMapping("/user/commit/{userId}") SingleResult updateCommitCount(@PathVariable Long userId, @RequestBody CommitRequestDto requestDto); diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/dto/response/BaekjoonListResponseDto.java b/backend/challenge-service/src/main/java/com/example/challengeservice/client/dto/BaekjoonListResponseDto.java similarity index 85% rename from backend/challenge-service/src/main/java/com/example/challengeservice/dto/response/BaekjoonListResponseDto.java rename to backend/challenge-service/src/main/java/com/example/challengeservice/client/dto/BaekjoonListResponseDto.java index e2dc8ac..191980d 100644 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/dto/response/BaekjoonListResponseDto.java +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/client/dto/BaekjoonListResponseDto.java @@ -1,4 +1,4 @@ -package com.example.challengeservice.dto.response; +package com.example.challengeservice.client.dto; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/dto/response/CommitResponseDto.java b/backend/challenge-service/src/main/java/com/example/challengeservice/client/dto/CommitResponseDto.java similarity index 85% rename from backend/challenge-service/src/main/java/com/example/challengeservice/dto/response/CommitResponseDto.java rename to backend/challenge-service/src/main/java/com/example/challengeservice/client/dto/CommitResponseDto.java index c28d7b5..32356ac 100644 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/dto/response/CommitResponseDto.java +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/client/dto/CommitResponseDto.java @@ -1,4 +1,4 @@ -package com.example.challengeservice.dto.response; +package com.example.challengeservice.client.dto; import lombok.AllArgsConstructor; diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/dto/response/DateProblemResponseDto.java b/backend/challenge-service/src/main/java/com/example/challengeservice/client/dto/DateProblemResponseDto.java similarity index 84% rename from backend/challenge-service/src/main/java/com/example/challengeservice/dto/response/DateProblemResponseDto.java rename to backend/challenge-service/src/main/java/com/example/challengeservice/client/dto/DateProblemResponseDto.java index 22a63ab..323ac54 100644 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/dto/response/DateProblemResponseDto.java +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/client/dto/DateProblemResponseDto.java @@ -1,4 +1,4 @@ -package com.example.challengeservice.dto.response; +package com.example.challengeservice.client.dto; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/dto/response/UserResponseDto.java b/backend/challenge-service/src/main/java/com/example/challengeservice/client/dto/UserResponseDto.java similarity index 88% rename from backend/challenge-service/src/main/java/com/example/challengeservice/dto/response/UserResponseDto.java rename to backend/challenge-service/src/main/java/com/example/challengeservice/client/dto/UserResponseDto.java index f58de14..979c621 100644 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/dto/response/UserResponseDto.java +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/client/dto/UserResponseDto.java @@ -1,4 +1,4 @@ -package com.example.challengeservice.dto.response; +package com.example.challengeservice.client.dto; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/controller/AlgoController.java b/backend/challenge-service/src/main/java/com/example/challengeservice/controller/AlgoController.java new file mode 100644 index 0000000..d2a51b0 --- /dev/null +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/controller/AlgoController.java @@ -0,0 +1,53 @@ +package com.example.challengeservice.controller; + +import com.example.challengeservice.common.response.ResponseService; +import com.example.challengeservice.common.result.Result; +import com.example.challengeservice.common.result.SingleResult; +import com.example.challengeservice.dto.response.SolvedListResponseDto; +import com.example.challengeservice.service.algo.AlgoChallengeService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/challenges") +@Slf4j +@RequiredArgsConstructor +public class AlgoController { + private ResponseService responseService; + private AlgoChallengeService algoChallengeService; + + /** + * 신대득 + * 유저 백준 아이디를 통해 해당 유저의 푼 문제 리스트 찾기 (크롤링) + * 나온 결과를 계산해서 user에 넣어줘야한다. + */ + @GetMapping("/baekjoon/{baekjoonId}") + public SingleResult solvedProblemList(@PathVariable("baekjoonId") String baekjoonId){ + return responseService.getSingleResult(algoChallengeService.solvedProblemList(baekjoonId)); + } + + /** + * 신대득 + * 선택한 유저가 + * 해당 날짜에 푼 문제를 조회하는 API + * @param userId // 조회 할 유저의 id + * @param selectDate // 조회 할 날짜 + * @return + */ + @GetMapping("/baekjoon/users/date") + public SingleResult checkDateUserBaekjoon(@RequestParam Long userId, @RequestParam String selectDate){ + return responseService.getSingleResult(algoChallengeService.checkDateUserBaekjoon(userId, selectDate)); + } + + /** + * 신대득 + * 유저가 푼 문제 리스트 갱신 + */ + @PostMapping("/baekjoon/update/users/{userId}") + public Result updateUserBaekjoon(@PathVariable String userId){ + algoChallengeService.updateUserBaekjoon(Long.parseLong(userId)); + return responseService.getSuccessResult(); + } + +} diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/controller/AuthController.java b/backend/challenge-service/src/main/java/com/example/challengeservice/controller/AuthController.java index 574172b..5766683 100644 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/controller/AuthController.java +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/controller/AuthController.java @@ -11,8 +11,9 @@ import com.example.challengeservice.dto.response.*; import com.example.challengeservice.exception.ApiException; import com.example.challengeservice.exception.ExceptionEnum; -import com.example.challengeservice.service.ChallengeService; +import com.example.challengeservice.service.algo.AlgoChallengeService; import com.example.challengeservice.service.challenge.BasicChallengeService; +import com.example.challengeservice.service.commit.CommitChallengeService; import com.example.challengeservice.service.photo.PhotoChallengeService; import com.example.challengeservice.validator.DateValidator; import lombok.RequiredArgsConstructor; @@ -32,11 +33,12 @@ @RequiredArgsConstructor public class AuthController { private final ResponseService responseService; - private final ChallengeService challengeService; private static final String USER_ID = "userId"; private final PhotoChallengeService photoChallengeService; private final BasicChallengeService basicChallengeService; + private final AlgoChallengeService algoChallengeService; + private final CommitChallengeService commitChallengeService; /** * 챌린지방 생성 @@ -134,7 +136,7 @@ public ListResult getTeamChallengeRecord(HttpServletRequest r @GetMapping("/baekjoon/users/recent") public SingleResult getRecentUserBaekjoon(HttpServletRequest request){ Long userId = Long.parseLong(request.getHeader(USER_ID)); - return responseService.getSingleResult(challengeService.getRecentUserBaekjoon(userId)); + return responseService.getSingleResult(algoChallengeService.getRecentUserBaekjoon(userId)); } /** @@ -145,7 +147,7 @@ public SingleResult getRecentUserBaekjoon(HttpServletReque @GetMapping("/commit/users/recent") public SingleResult getRecentUserCommit(HttpServletRequest request){ Long userId = Long.parseLong(request.getHeader(USER_ID)); - return responseService.getSingleResult(challengeService.getRecentUserCommit(userId)); + return responseService.getSingleResult(commitChallengeService.getRecentUserCommit(userId)); } /** @@ -157,7 +159,7 @@ public SingleResult getRecentUserCommit(HttpServletRequest @GetMapping("/baekjoon/users/progress/{challengeId}") public ProgressResponseDto getProgressUserBaekjoon(HttpServletRequest request, @PathVariable String challengeId){ Long userId = Long.parseLong(request.getHeader(USER_ID)); - return challengeService.getProgressUserBaekjoon(userId, Long.parseLong(challengeId)); + return algoChallengeService.getProgressUserBaekjoon(userId, Long.parseLong(challengeId)); } /** @@ -167,7 +169,7 @@ public ProgressResponseDto getProgressUserBaekjoon(HttpServletRequest request, @ @PostMapping("/certification/users/{challengeId}") public CertificationResponseDto getCertification(HttpServletRequest request, @PathVariable String challengeId){ Long userId= Long.parseLong(request.getHeader(USER_ID)); - return challengeService.getCertification(userId, Long.parseLong(challengeId)); + return basicChallengeService.getCertification(userId, Long.parseLong(challengeId)); } diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/controller/ChallengeController.java b/backend/challenge-service/src/main/java/com/example/challengeservice/controller/ChallengeController.java index 81d19df..381daf9 100644 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/controller/ChallengeController.java +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/controller/ChallengeController.java @@ -1,6 +1,5 @@ package com.example.challengeservice.controller; -import com.example.challengeservice.client.PayServiceClient; import com.example.challengeservice.common.response.ResponseService; import com.example.challengeservice.common.result.ListResult; import com.example.challengeservice.common.result.Result; @@ -8,9 +7,7 @@ import com.example.challengeservice.dto.response.ChallengeRoomResponseDto; import com.example.challengeservice.dto.response.SimpleChallengeResponseDto; import com.example.challengeservice.dto.response.*; -import com.example.challengeservice.dto.response.SolvedListResponseDto; import com.example.challengeservice.infra.amazons3.service.AmazonS3Service; -import com.example.challengeservice.service.ChallengeService; import com.example.challengeservice.service.SchedulerService; import com.example.challengeservice.service.challenge.BasicChallengeService; import lombok.RequiredArgsConstructor; @@ -30,7 +27,6 @@ @RequiredArgsConstructor public class ChallengeController { private final ResponseService responseService; - private final ChallengeService challengeService; private final AmazonS3Service s3Service; private final SchedulerService schedulerService; @@ -68,40 +64,6 @@ public SingleResult> challengeInfoList(@Requ } - /** 신대득 - * 유저 백준 아이디를 통해 해당 유저의 푼 문제 리스트 찾기 (크롤링) - * 나온 결과를 계산해서 user에 넣어줘야한다. - * Todo : userId로 baekjoonId 가져오는걸로 바꾸기 - */ - @GetMapping("/baekjoon/{baekjoonId}") - public SingleResult solvedProblemList(@PathVariable("baekjoonId") String baekjoonId){ - return responseService.getSingleResult(challengeService.solvedProblemList(baekjoonId)); - } - - /** - * 신대득 - * 선택한 유저가 - * 해당 날짜에 푼 문제를 조회하는 API - * @param userId // 조회 할 유저의 id - * @param selectDate // 조회 할 날짜 - * @return - */ - @GetMapping("/baekjoon/users/date") - public SingleResult checkDateUserBaekjoon(@RequestParam Long userId, @RequestParam String selectDate){ - return responseService.getSingleResult(challengeService.checkDateUserBaekjoon(userId, selectDate)); - } - - /** - * 유저의 커밋 정보 조회 - * @param userId - * @param selectDate - * @return - */ - @GetMapping("/commit/users/date") - public SingleResult checkDateUserCommit(@RequestParam Long userId, @RequestParam String selectDate){ - return responseService.getSingleResult(challengeService.checkDateUserCommit(userId, selectDate)); - } - /** * @author 신대득 * 현재 user가 참가중인 챌린지 개수 반환 @@ -112,29 +74,6 @@ public SingleResult userChallengeInfo(@PathVariabl } - /** - * @author 신대득 - * 스케줄러로 실행되는 일일 기록 저장의 테스트 API - * @return - */ - @GetMapping("/test/record") - public Result testRecord (){ - challengeService.createDailyRecord(); - return responseService.getSuccessResult(); - } - - /** - * @author 신대득 - * 스케줄러로 실행되는 일일 정산의 테스트 API - * @return - */ - @GetMapping("/test/payment") - public Result testPayment (){ - challengeService.culcDailyPayment(); - return responseService.getSuccessResult(); - } - - /** 기본 사진 업로드 **/ @PostMapping("upload/image") public String updateDefaultImage(@RequestParam("file") MultipartFile multipartFile , @RequestParam("dir") String dir) throws IOException{ @@ -142,6 +81,16 @@ public String updateDefaultImage(@RequestParam("file") MultipartFile multipartFi return s3Service.upload(multipartFile,dir); } + /** + * 해당 챌린지 방 + * 모든 유저의 정보 갱신 + */ + @PostMapping("/update/room/{challengeId}") + public Result updateChallengeRoom(@PathVariable Long challengeId){ + basicChallengeService.updateChallengeRoom(challengeId); + return responseService.getSuccessResult(); + } + /** * @author 신대득 * 챌린지내에서 1등부터 차례대로 랭킹을 반환하는 API @@ -150,26 +99,28 @@ public String updateDefaultImage(@RequestParam("file") MultipartFile multipartFi */ @GetMapping("baekjoon/rank/{challengeId}") public ListResult getTopRank(@PathVariable String challengeId){ - return responseService.getListResult(challengeService.getTopRank(Long.parseLong(challengeId))); + return responseService.getListResult(basicChallengeService.getTopRank(Long.parseLong(challengeId))); } /** - * 신대득 - * 유저가 푼 문제 리스트 갱신 + * @author 신대득 + * 스케줄러로 실행되는 일일 기록 저장의 테스트 API + * @return */ - @PostMapping("/baekjoon/update/users/{userId}") - public Result updateUserBaekjoon(@PathVariable String userId){ - challengeService.updateUserBaekjoon(Long.parseLong(userId)); + @GetMapping("/test/record") + public Result testRecord (){ + schedulerService.createDailyRecord(); return responseService.getSuccessResult(); } /** - * 해당 챌린지 방 - * 모든 유저의 푼 문제 리스트 갱신 + * @author 신대득 + * 스케줄러로 실행되는 일일 정산의 테스트 API + * @return */ - @PostMapping("/baekjoon/update/room/{challengeId}") - public Result updateChallengeRoom(@PathVariable Long challengeId){ - challengeService.updateChallengeRoom(challengeId); + @GetMapping("/test/payment") + public Result testPayment (){ + schedulerService.culcDailyPayment(); return responseService.getSuccessResult(); } diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/controller/CommitController.java b/backend/challenge-service/src/main/java/com/example/challengeservice/controller/CommitController.java index 992221a..7fa3929 100644 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/controller/CommitController.java +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/controller/CommitController.java @@ -1,10 +1,11 @@ package com.example.challengeservice.controller; +import com.example.challengeservice.client.dto.CommitResponseDto; import com.example.challengeservice.common.response.ResponseService; import com.example.challengeservice.common.result.Result; import com.example.challengeservice.common.result.SingleResult; import com.example.challengeservice.dto.response.CommitCountResponseDto; -import com.example.challengeservice.service.ChallengeService; +import com.example.challengeservice.service.commit.CommitChallengeService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; @@ -17,8 +18,7 @@ @RequiredArgsConstructor public class CommitController { private final ResponseService responseService; - - private final ChallengeService challengeService; + private final CommitChallengeService commitChallengeService; /** * 신대득 @@ -27,7 +27,7 @@ public class CommitController { */ @GetMapping("/github/{githubId}") public SingleResult getGithubList(@PathVariable("githubId") String githubId){ - return responseService.getSingleResult(challengeService.getGithubCommit(githubId)); + return responseService.getSingleResult(commitChallengeService.getGithubCommit(githubId)); } /** @@ -37,10 +37,21 @@ public SingleResult getGithubList(@PathVariable("githubI @PostMapping("/github/update/users") public Result updateUserBaekjoon(HttpServletRequest request){ Long userId=Long.parseLong(request.getHeader("userId")); - challengeService.updateUserCommit(userId); + commitChallengeService.updateUserCommit(userId); return responseService.getSuccessResult(); } + /** + * 유저의 커밋 정보 조회 + * @param userId + * @param selectDate + * @return + */ + @GetMapping("/commit/users/date") + public SingleResult checkDateUserCommit(@RequestParam Long userId, @RequestParam String selectDate){ + return responseService.getSingleResult(commitChallengeService.checkDateUserCommit(userId, selectDate)); + } + } diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/service/ChallengeService.java b/backend/challenge-service/src/main/java/com/example/challengeservice/service/ChallengeService.java deleted file mode 100644 index c635469..0000000 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/service/ChallengeService.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.example.challengeservice.service; - -import com.example.challengeservice.dto.request.ChallengeJoinRequestDto; -import com.example.challengeservice.dto.request.ChallengeRecordRequestDto; -import com.example.challengeservice.dto.request.ChallengeRoomRequestDto; -import com.example.challengeservice.dto.request.ReportRecordRequestDto; -import com.example.challengeservice.dto.response.*; -import com.example.challengeservice.entity.ChallengeRoom; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -public interface ChallengeService { - - /** 깃허브 커밋 리스트 찾기 **/ - CommitCountResponseDto getGithubCommit(String githubId); - /** 푼 문제 리스트 찾기 **/ - SolvedListResponseDto solvedProblemList(String baekjoonId); - /** 유저의 백준리스트 가져오기 **/ - void updateUserBaekjoon(Long userId); - /** 방의 모든 유저의 백준 리스트 업데이트 **/ - void updateChallengeRoom(Long challengeRoomId); - /** 해당 유저가 해당 날짜에 푼 알고리즘 리스트 조회 **/ - SolvedListResponseDto checkDateUserBaekjoon(Long userId, String selectDate); - /** 해당 유저가 해당 날짜에 커밋한 개수를 조회 **/ - CommitResponseDto checkDateUserCommit(Long userId, String selectDate); - /** 해당 유저가 최근 5일 동안 푼 문제를 조회 **/ - SolvedMapResponseDto getRecentUserBaekjoon(Long userId); - /** 해당 유저가 최근 5일 동안의 커밋 개수 조회 **/ - SolvedMapResponseDto getRecentUserCommit(Long userId); - /** 스케줄러 저장 메서드 **/ - void createDailyRecord(); - /** 알고리즘 인증 기록 생성하기 **/ - void createAlgoRecord(ChallengeRecordRequestDto requestDto) throws IOException; - /** 해당 방의 하루 정산 **/ - void oneDayCulc(ChallengeRoom challengeRoom); - /** 하루정산을 시키는 스케줄러 **/ - void culcDailyPayment(); - /** 유저의 커밋리스트 업데이트 **/ - void updateUserCommit(Long userId); - /** 커밋 인증 기록을 저장 **/ - void createCommitRecord(ChallengeRecordRequestDto requestDto); - /** 나의 현재 진행상황 보기 **/ - ProgressResponseDto getProgressUserBaekjoon(Long userId, Long challengeId); - /** 챌린지내에서 1등부터 차례대로 랭킹을 반환 **/ - List getTopRank(Long challengeId); - /** 유저가 선택한 챌린지에 대한 증명서 정보를 반환하는 메서드 **/ - CertificationResponseDto getCertification(Long userId, Long challengeRoomId); -} diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/service/ChallengeServiceImpl.java b/backend/challenge-service/src/main/java/com/example/challengeservice/service/ChallengeServiceImpl.java deleted file mode 100644 index 762d0ed..0000000 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/service/ChallengeServiceImpl.java +++ /dev/null @@ -1,515 +0,0 @@ -package com.example.challengeservice.service; - -import com.example.challengeservice.client.UserServiceClient; -import com.example.challengeservice.common.result.SingleResult; -import com.example.challengeservice.dto.request.*; -import com.example.challengeservice.dto.response.*; -import com.example.challengeservice.entity.ChallengeRecord; -import com.example.challengeservice.entity.ChallengeRoom; -import com.example.challengeservice.entity.UserChallenge; -import com.example.challengeservice.exception.ApiException; -import com.example.challengeservice.exception.ExceptionEnum; -import com.example.challengeservice.repository.*; -import com.example.challengeservice.service.challenge.BasicChallengeService; -import com.example.challengeservice.service.common.CommonServiceImpl; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.jsoup.Connection; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.select.Elements; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.io.IOException; -import java.util.*; - -@Service -@RequiredArgsConstructor -@Slf4j -public class ChallengeServiceImpl implements ChallengeService{ - private final UserServiceClient userServiceClient; - private final UserChallengeRepository userChallengeRepository; - private final ChallengeRoomRepository challengeRoomRepository; - private final CommonServiceImpl commonService; - private final ChallengeRecordRepository challengeRecordRepository; - - private final BasicChallengeService basicChallengeService; - - - /** - * githubId로 commit 정보가져오기 - */ - @Override - public CommitCountResponseDto getGithubCommit(String githubId){ - String githubUrl = "https://github.com/"; - githubUrl+=githubId; - Connection conn = Jsoup.connect(githubUrl); - List solvedList= new ArrayList<>(); - int commitCount=0; - try { - Document document = conn.get(); - Elements imageUrlElements = document.getElementsByClass("js-calendar-graph-svg"); - Element element = imageUrlElements.get(0); - String today = commonService.getDate(); - Element todayElement= element.getElementsByTag("Rect").last().getElementsByAttributeValue("data-date", today).first(); - StringTokenizer st= new StringTokenizer(todayElement.text(), " "); - String commitString=st.nextToken(); - if(!commitString.equals("No")){ - commitCount=Integer.parseInt(commitString); - } - - } catch (IOException e) { - e.printStackTrace(); - } catch (Exception e){ - e.printStackTrace(); - } - return CommitCountResponseDto.from(githubId, commitCount); - } - - /** - * explain : 회원이 푼 백준 문제 가져오기 - * @param baekjoonId :백준 아이디 - */ - @Override - public SolvedListResponseDto solvedProblemList(String baekjoonId) { - - String baekJoonUrl = "https://www.acmicpc.net/user/"; - baekJoonUrl+=baekjoonId; - Connection conn = Jsoup.connect(baekJoonUrl); - List solvedList= new ArrayList<>(); - - int count=0; - try { - Document document = conn.get(); - Elements imageUrlElements = document.getElementsByClass("problem-list"); - Element element = imageUrlElements.get(0); - Elements problems= element.getElementsByTag("a"); - for (Element problem : problems) { - solvedList.add(problem.text()); - count++; - } - } catch (IOException e) { - e.printStackTrace(); - } - return SolvedListResponseDto.from(solvedList, count); - } - - /** 챌린지 수정하기 **/ - public void updateChallengeRoom(Long challengeRoomId){ - - ChallengeRoom challengeRoom = basicChallengeService.getChallengeRoomEntity(challengeRoomId); - List userChallengeList = userChallengeRepository.findAllByChallengeRoomId(challengeRoom.getId()); - for(UserChallenge uc :userChallengeList){ - if(challengeRoom.getCategory().equals("ALGO")){ - - updateUserBaekjoon(uc.getUserId()); - - createAlgoRecord(ChallengeRecordRequestDto.from(uc.getUserId(),challengeRoomId)); - } else if(challengeRoom.getCategory().equals("COMMIT")){ - - updateUserCommit(uc.getUserId()); - - createCommitRecord(ChallengeRecordRequestDto.from(uc.getUserId(),challengeRoomId)); - } - } - } - - /** 유저의 백준리스트 업데이트 - * **/ - public void updateUserBaekjoon(Long userId){ - SingleResult userResponseDtoTemp = userServiceClient.getUserInfo(userId); - UserResponseDto userResponseDto=userResponseDtoTemp.getData(); - SingleResult baekjoonListResponseDto = userServiceClient.getUserBaekjoonList(userResponseDto.getUserId()); - - String baekjoonId = baekjoonListResponseDto.getData().getBaekjoonId(); - if(baekjoonId==null){ - return; -// throw new ApiException(ExceptionEnum.ALGO_NOT_EXIST_ID); - } - List diffSolvedList=new ArrayList<>(); - Map problemList = baekjoonListResponseDto.getData().getProblemList(); - List newSolvedList=solvedProblemList(baekjoonId).getSolvedList(); - for(String s:newSolvedList){ - if(problemList.get(s)==null){ - diffSolvedList.add(s); - } - } - if(diffSolvedList.size()==0){ - return; -// throw new ApiException(ExceptionEnum.ALGO_ALREADY_UPDATE); - } - userServiceClient.createProblem(userId, ProblemRequestDto.from(diffSolvedList)); - } - - /** 유저의 커밋리스트 업데이트 **/ - public void updateUserCommit(Long userId) { - SingleResult userResponseDtoTemp = userServiceClient.getUserInfo(userId); - UserResponseDto userResponseDto = userResponseDtoTemp.getData(); - - String today = commonService.getDate(); - // 오늘 날짜의 유저의 커밋 수 조회 - CommitCountResponseDto commitCountResponseDto=getGithubCommit(userResponseDto.getGithub()); - if(commitCountResponseDto.getCommitCount()==0){ - return; - } - userServiceClient.updateCommitCount(userResponseDto.getUserId(), new CommitRequestDto(today, commitCountResponseDto.getCommitCount())); - } - - /** - * 신대득 - * 선택한 유저가 선택한 날짜에 - * 커밋 개수를 반환하는 메서드 - */ - public CommitResponseDto checkDateUserCommit(Long userId, String selectDate){ - updateUserCommit(userId); - UserResponseDto userInfo = userServiceClient.getUserInfo(userId).getData(); - CommitResponseDto commitResponseDto = userServiceClient.getCommitRecord(userId, selectDate).getData(); - return commitResponseDto; - } - - /** - * 신대득 - * 선택한 유저가 선택한 날짜에 - * 푼 문제 리스트를 반환하는 메서드 - */ - public SolvedListResponseDto checkDateUserBaekjoon(Long userId, String selectDate){ - UserResponseDto userInfo = userServiceClient.getUserInfo(userId).getData(); - List dateBaekjoonList = userServiceClient.getDateBaekjoonList(userInfo.getUserId(), selectDate, selectDate).getData(); - List problemList=new ArrayList<>(); - for(DateProblemResponseDto problem:dateBaekjoonList){ - problemList.add(problem.getProblemId()); - } - return SolvedListResponseDto.from(userInfo.getUserId(), problemList, problemList.size(), selectDate); - } - - /** - * 해당 유저의 최근 5일 (오늘 ~ 4일전) - * 푼 문제 리스트를 반환하는 메서드 - */ - @Override - public SolvedMapResponseDto getRecentUserBaekjoon(Long userId) { - String today= commonService.getDate(); - String pastDay=commonService.getPastDay(5, commonService.getDate()); - - List dateBaekjoonList =userServiceClient.getDateBaekjoonList(userId,pastDay,today).getData(); - Map> myMap = new HashMap<>(); - for(int i=0;i<=5;i++){ - myMap.putIfAbsent(commonService.getPastDay(i,commonService.getDate()), new ArrayList<>()); - } - for(DateProblemResponseDto dateProblemResponseDto: dateBaekjoonList){ - String curDate=dateProblemResponseDto.getSuccessDate(); - List problemList= myMap.get(curDate); - problemList.add(dateProblemResponseDto.getProblemId()); - } - return SolvedMapResponseDto.algoFrom(myMap); - } - - @Override - public SolvedMapResponseDto getRecentUserCommit(Long userId) { - String today=commonService.getDate(); - String pastDay=commonService.getPastDay(5, today); - List dateCommitList = userServiceClient.getDateCommitList(userId, pastDay, today).getData(); - - Map myMap = new HashMap<>(); - - for(CommitResponseDto commitResponseDto: dateCommitList){ - myMap.put(commitResponseDto.getCommitDate(), commitResponseDto.getCommitCount()); - } - return SolvedMapResponseDto.commitFrom(myMap); - } - - /** 신대득 - * 인증 정보 저장 (알고리즘) - * 매일 오후 11시 50분에 메서드를 실행시킬 스케줄러 - * **/ - @Scheduled(cron = "0 50 23 * * ?") // 매일 오후 11시 50분 - public void createDailyRecord(){ - String today=commonService.getDate(); - - // 현재 진행중인 알고리즘 챌린지 리스트 조회 - List userAlgoChallengeList = userChallengeRepository.findAllByDateAndCategory(today, "ALGO"); - - // Algo 기록 저장 - for(UserChallenge userChallenge:userAlgoChallengeList){ - createAlgoRecord(ChallengeRecordRequestDto.from(userChallenge.getUserId(), userChallenge.getChallengeRoom().getId())); - } - - // 현재 진행중인 커밋 챌린지 리스트 조회 - List userCommitChallengeList = userChallengeRepository.findAllByDateAndCategory(today, "COMMIT"); - // Commit 기록 저장 - for(UserChallenge userChallenge:userCommitChallengeList){ - createCommitRecord(ChallengeRecordRequestDto.from(userChallenge.getUserId(), userChallenge.getChallengeRoom().getId())); - } - - } - - /** - * 신대득 - * 하루정산 시키기 (1일전 인증기록을 통해서) - */ - @Scheduled(cron = "0 1 0 * * ?") // 매일 오후 0시 1분 - public void culcDailyPayment(){ - List challengingRoomList = challengeRoomRepository.findChallengingRoomByDate(commonService.getPastDay(0,commonService.getDate())); - for(ChallengeRoom challengeRoom: challengingRoomList){ - oneDayCulc(challengeRoom); - } - } - - /** - * 신대득 - * 알고리즘 문제 풀이 인증 기록을 저장하는 메서드 - * @param requestDto - */ - @Override - @Transactional - public void createAlgoRecord(ChallengeRecordRequestDto requestDto) { - ChallengeRoom challengeRoom = basicChallengeService.getChallengeRoomEntity(requestDto.getChallengeRoomId()); - - UserResponseDto user = userServiceClient.getUserInfo(requestDto.getUserId()).getData(); - - // 오늘 날짜 - String date = commonService.getDate(); - - - List todayProblemList = userServiceClient.getDateBaekjoonList(user.getUserId(), date, date).getData(); - - //challengeRoom에서 최소 알고리즘 개수 가져오기 미달이면 Exception 발생 - if(todayProblemList.size() new ApiException(ExceptionEnum.USER_CHALLENGE_NOT_EXIST_EXCEPTION)); - - - // 기존에 이 날짜에 인증기록이 있는지 검사 - Optional algoRecordResponseDto = challengeRecordRepository.findByCreateAtAndUserChallenge(date, userChallenge); - if(algoRecordResponseDto.isPresent()){ - if(algoRecordResponseDto.get().getAlgorithmCount()!=todayProblemList.size()){ - algoRecordResponseDto.get().setAlgorithmCount(todayProblemList.size()); - challengeRecordRepository.save(algoRecordResponseDto.get()); - } - - }else{ - ChallengeRecord challengeRecord = ChallengeRecord.fromAlgo(date, todayProblemList.size(), userChallenge); - challengeRecordRepository.save(challengeRecord); - } - } - - /** - * 커밋 인증 기록을 저장하는 메서드 - */ - @Override - @Transactional - public void createCommitRecord(ChallengeRecordRequestDto requestDto) { - ChallengeRoom challengeRoom = basicChallengeService.getChallengeRoomEntity(requestDto.getChallengeRoomId()); - UserResponseDto user = userServiceClient.getUserInfo(requestDto.getUserId()).getData(); - - String date = commonService.getDate(); - - - SingleResult commitResponseDto = userServiceClient.getCommitRecord(user.getUserId(), date); - - if(commitResponseDto.getData().getCommitCount() new ApiException(ExceptionEnum.USER_CHALLENGE_NOT_EXIST_EXCEPTION)); - - - Optional commitRecordResponseDto = challengeRecordRepository.findByCreateAtAndUserChallenge(date, userChallenge); - if(commitRecordResponseDto.isPresent()){ - - if(commitRecordResponseDto.get().getCommitCount()!=commitResponseDto.getData().getCommitCount()){ - commitRecordResponseDto.get().setCommitCount(commitResponseDto.getData().getCommitCount()); - challengeRecordRepository.save(commitRecordResponseDto.get()); - } - - }else{ - ChallengeRecord challengeRecord = ChallengeRecord.fromCommit(date, commitResponseDto.getData().getCommitCount(), userChallenge); - challengeRecordRepository.save(challengeRecord); - } - } - - /** - * 하루 정산 - * 일단 현재 진행중인 챌린지 방을 받아와야함 입력값으로!! - * **/ - @Override - @Transactional - public void oneDayCulc(ChallengeRoom challengeRoom) { - Integer period = commonService.diffDay(challengeRoom.getStartDate(), challengeRoom.getEndDate()).intValue(); - int oneDayFee = (int)Math.ceil((double) challengeRoom.getEntryFee() / (period+1)); - String beforeOneDay = commonService.getPastDay(0, commonService.getDate()); - - if(commonService.diffDay(beforeOneDay, challengeRoom.getEndDate())<0 || commonService.diffDay(challengeRoom.getStartDate(), beforeOneDay) <0){ - return; - } - - List userChallengeList = userChallengeRepository.findUserChallengesByChallengeRoomId(challengeRoom.getId()); - List successList=new ArrayList<>(); - List failList=new ArrayList<>(); - for (UserChallenge userChallenge : userChallengeList) { - - List challengeRecord = challengeRecordRepository.findByUserChallengeIdAndCreateAt(userChallenge.getId(), beforeOneDay); - if(challengeRecord.size()==0){ - failList.add(userChallenge); - }else{ - if (!(challengeRecord.get(0).isSuccess())) { - failList.add(userChallenge); - } else{ - successList.add(userChallenge); - } - } - } - - Long sum=0L; - for(UserChallenge userChallenge: failList){ - - userChallenge.setDiffPrice(userChallenge.getDiffPrice()-oneDayFee); - userChallengeRepository.save(userChallenge); - sum+=oneDayFee; - } - - Long todayMoney=Long.valueOf((long)Math.ceil((double)sum/successList.size())); - for(UserChallenge userChallenge: successList){ - userChallenge.setDiffPrice(userChallenge.getDiffPrice()+todayMoney); - userChallengeRepository.save(userChallenge); - } - - } - - /** - * 알고리즘 - * 나의 인증현황 - * 진행률, 예치금 + 상금, 성공 / 실패 횟수 - */ - @Override - public ProgressResponseDto getProgressUserBaekjoon(Long userId, Long challengeId){ - - ChallengeRoomResponseDto challengeRoom=basicChallengeService.readChallenge(challengeId); - - UserChallenge userChallenge = userChallengeRepository.findByChallengeRoomIdAndUserId(challengeRoom.getId(), userId) - .orElseThrow(()-> new ApiException(ExceptionEnum.USER_CHALLENGE_LIST_NOT_EXIST)); - - Long challengeLength = commonService.diffDay(challengeRoom.getStartDate(), commonService.getDate()); - if(challengeLength<0){ - challengeLength=-1L; - } - challengeLength++; - Long successCount=0L; - List challengeRecordList = challengeRecordRepository.findAllByUserChallengeIdAndStartDateAndEndDate(userChallenge.getId(), challengeRoom.getStartDate(), challengeRoom.getEndDate(), true); - for(ChallengeRecord cr:challengeRecordList){ - switch(challengeRoom.getCategory()){ - case "ALGO": - if(cr.getAlgorithmCount()>=challengeRoom.getAlgorithmCount()) - successCount++; - break; - case "COMMIT": - if(cr.getCommitCount()>=challengeRoom.getCommitCount()) - successCount++; - break; - case "FREE": - if(cr.isSuccess()) - successCount++; - break; - } - } - Long failCount = challengeLength - successCount; - if(challengeLength==0){ - challengeLength++; - } - String progressRate= String.format("%.2f", (double)(successCount*100)/challengeLength); - - Long curPrice=userChallenge.getDiffPrice() + (long)challengeRoom.getEntryFee(); - return new ProgressResponseDto(progressRate, curPrice, successCount, failCount); - } - - - /** - * 현재 챌린지 방의 탑 랭크 리스트 조회 - */ - @Override - public List getTopRank(Long challengeId) { - ChallengeRoom challengeRoom = basicChallengeService.getChallengeRoomEntity(challengeId); - List userChallengesByChallengeRoomId = userChallengeRepository.findAllByChallengeRoomId(challengeRoom.getId()); - List rankResponseDtoList = new ArrayList<>(); - Long period = commonService.diffDay(challengeRoom.getStartDate(), challengeRoom.getEndDate()) + 1; - for (UserChallenge uc : userChallengesByChallengeRoomId) { - // 현재 uc 중 챌린지 기간 동안의 레코드 조회 - switch (challengeRoom.getCategory()) { - case "ALGO": - List challengeAlgoRecordList = challengeRecordRepository.findAllByUserChallengeIdAndStartDateAndEndDateAlgo(uc.getId(), challengeRoom.getStartDate(), challengeRoom.getEndDate(), true, challengeRoom.getAlgorithmCount()); - rankResponseDtoList.add(new RankResponseDto(0L, uc.getUserId(), uc.getNickname(), (long) challengeAlgoRecordList.size(), period - (long) challengeAlgoRecordList.size())); - break; - case "COMMIT": - List challengeCommitRecordList = challengeRecordRepository.findAllByUserChallengeIdAndStartDateAndEndDateCommit(uc.getId(), challengeRoom.getStartDate(), challengeRoom.getEndDate(), true, challengeRoom.getCommitCount()); - rankResponseDtoList.add(new RankResponseDto(0L, uc.getUserId(), uc.getNickname(), (long) challengeCommitRecordList.size(), period - (long) challengeCommitRecordList.size())); - break; - case "FREE": - List challengeFreeRecordList = challengeRecordRepository.findAllByUserChallengeIdAndStartDateAndEndDateFree(uc.getId(), challengeRoom.getStartDate(), challengeRoom.getEndDate(), true); - rankResponseDtoList.add(new RankResponseDto(0L, uc.getUserId(), uc.getNickname(), (long) challengeFreeRecordList.size(), period-(long)challengeFreeRecordList.size())); - break; - } - Collections.sort(rankResponseDtoList); - for (int i = 0; i < rankResponseDtoList.size(); i++) { - rankResponseDtoList.get(i).setRank((long) i + 1); - } - } - return rankResponseDtoList; - } - - /** - 현재 유저가 들어온 방에서 자신의 진행율을 계산하는 메서드 - */ - public String getProgressRate(Long userChallengeId, ChallengeRoomResponseDto challengeRoom){ - - Long challengeLength = commonService.diffDay(challengeRoom.getStartDate(), challengeRoom.getEndDate()); - if(challengeLength < 0){ - challengeLength = -1L; - } - challengeLength++; - Long successCount = 0L; - List challengeRecordList = challengeRecordRepository.findAllByUserChallengeIdAndStartDateAndEndDate(userChallengeId, challengeRoom.getStartDate(), challengeRoom.getEndDate(), true); - if(challengeRecordList.size() == 0){ - return "0"; - } - for(ChallengeRecord cr:challengeRecordList){ - switch(challengeRoom.getCategory()){ - case "ALGO": - if(cr.getAlgorithmCount()>=challengeRoom.getAlgorithmCount()) - successCount++; - break; - case "COMMIT": - if(cr.getCommitCount()>=challengeRoom.getCommitCount()) - successCount++; - break; - case "FREE": - if(cr.isSuccess()) - successCount++; - break; - } - } - if(challengeLength==0){ - challengeLength++; - } - return String.format("%.2f", (double)(successCount*100)/challengeLength); - } - - /** - * 유저가 선택한 챌린지의 인증서 정보를 조회하는 메서드 - */ - public CertificationResponseDto getCertification(Long userId, Long challengeRoomId){ - ChallengeRoomResponseDto challengeRoom = basicChallengeService.readChallenge(challengeRoomId); - UserChallenge userChallenge = userChallengeRepository.findByChallengeRoomIdAndUserId(challengeRoomId, userId) - .orElseThrow(() -> new ApiException(ExceptionEnum.USER_CHALLENGE_NOT_EXIST_EXCEPTION)); - UserResponseDto userResponseDto= userServiceClient.getUserInfo(userId).getData(); - String progressRate= getProgressRate(userChallenge.getId(), challengeRoom); - - return new CertificationResponseDto(userResponseDto.getName(), userChallenge.getChallengeRoom().getTitle(), userChallenge.getChallengeRoom().getStartDate(), - userChallenge.getChallengeRoom().getEndDate(), progressRate, userChallenge.getId()); - } -} diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/service/SchedulerService.java b/backend/challenge-service/src/main/java/com/example/challengeservice/service/SchedulerService.java index 87f7380..3b1c1ca 100644 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/service/SchedulerService.java +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/service/SchedulerService.java @@ -4,4 +4,8 @@ public interface SchedulerService { /** 종료 챌린지 정산 하기 **/ void endChallengeCalculate(); + /** 하루 기록을 저장시키는 스케줄러 **/ + void createDailyRecord(); + /** 하루 정산을 시키는 스케줄러 **/ + void culcDailyPayment(); } diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/service/SchedulerServiceImpl.java b/backend/challenge-service/src/main/java/com/example/challengeservice/service/SchedulerServiceImpl.java index 2e122c0..e8b0c6d 100644 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/service/SchedulerServiceImpl.java +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/service/SchedulerServiceImpl.java @@ -2,24 +2,73 @@ import com.example.challengeservice.client.PayServiceClient; import com.example.challengeservice.client.dto.ChallengeSettlementRequest; +import com.example.challengeservice.dto.request.ChallengeRecordRequestDto; +import com.example.challengeservice.entity.ChallengeRoom; +import com.example.challengeservice.entity.UserChallenge; import com.example.challengeservice.repository.ChallengeRoomRepository; +import com.example.challengeservice.repository.UserChallengeRepository; +import com.example.challengeservice.service.algo.AlgoChallengeService; +import com.example.challengeservice.service.challenge.BasicChallengeService; +import com.example.challengeservice.service.commit.CommitChallengeService; import com.example.challengeservice.service.common.CommonService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +import java.util.List; + @Service @RequiredArgsConstructor @Slf4j public class SchedulerServiceImpl implements SchedulerService{ private final ChallengeRoomRepository challengeRoomRepository; - private final PayServiceClient payServiceClient; - private final CommonService commonService; + private final UserChallengeRepository userChallengeRepository; + private final BasicChallengeService basicChallengeService; + private final CommitChallengeService commitChallengeService; + private final AlgoChallengeService algoChallengeService; + @Override public void endChallengeCalculate() { payServiceClient.requestChallengeSettlement(new ChallengeSettlementRequest(challengeRoomRepository.findClosedChallengeUser(commonService.getPastDay(0,commonService.getDate())))); } + + /** 신대득 + * 인증 정보 저장 (알고리즘) + * 매일 오후 11시 50분에 메서드를 실행시킬 스케줄러 + * **/ + @Scheduled(cron = "0 50 23 * * ?") // 매일 오후 11시 50분 + public void createDailyRecord(){ + String today=commonService.getDate(); + + // 현재 진행중인 알고리즘 챌린지 리스트 조회 + List userAlgoChallengeList = userChallengeRepository.findAllByDateAndCategory(today, "ALGO"); + + // Algo 기록 저장 + for(UserChallenge userChallenge:userAlgoChallengeList){ + algoChallengeService.createAlgoRecord(ChallengeRecordRequestDto.from(userChallenge.getUserId(), userChallenge.getChallengeRoom().getId())); + } + + // 현재 진행중인 커밋 챌린지 리스트 조회 + List userCommitChallengeList = userChallengeRepository.findAllByDateAndCategory(today, "COMMIT"); + // Commit 기록 저장 + for(UserChallenge userChallenge:userCommitChallengeList){ + commitChallengeService.createCommitRecord(ChallengeRecordRequestDto.from(userChallenge.getUserId(), userChallenge.getChallengeRoom().getId())); + } + } + + /** + * 신대득 + * 하루정산 시키기 (1일전 인증기록을 통해서) + */ + @Scheduled(cron = "0 1 0 * * ?") // 매일 오후 0시 1분 + public void culcDailyPayment(){ + List challengingRoomList = challengeRoomRepository.findChallengingRoomByDate(commonService.getPastDay(0,commonService.getDate())); + for(ChallengeRoom challengeRoom: challengingRoomList){ + basicChallengeService.oneDayCulc(challengeRoom); + } + } } diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/service/algo/AlgoChallengeService.java b/backend/challenge-service/src/main/java/com/example/challengeservice/service/algo/AlgoChallengeService.java new file mode 100644 index 0000000..dddbbbf --- /dev/null +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/service/algo/AlgoChallengeService.java @@ -0,0 +1,21 @@ +package com.example.challengeservice.service.algo; + +import com.example.challengeservice.dto.request.ChallengeRecordRequestDto; +import com.example.challengeservice.dto.response.ProgressResponseDto; +import com.example.challengeservice.dto.response.SolvedListResponseDto; +import com.example.challengeservice.dto.response.SolvedMapResponseDto; + +public interface AlgoChallengeService { + /** 푼 문제 리스트 찾기 **/ + SolvedListResponseDto solvedProblemList(String baekjoonId); + /** 유저의 백준리스트 가져오기 **/ + void updateUserBaekjoon(Long userId); + /** 해당 유저가 해당 날짜에 푼 알고리즘 리스트 조회 **/ + SolvedListResponseDto checkDateUserBaekjoon(Long userId, String selectDate); + /** 해당 유저가 최근 5일 동안 푼 문제를 조회 **/ + SolvedMapResponseDto getRecentUserBaekjoon(Long userId); + /** 알고리즘 인증 기록 생성하기 **/ + void createAlgoRecord(ChallengeRecordRequestDto requestDto); + /** 나의 알고리즘 진행상황 보기 **/ + ProgressResponseDto getProgressUserBaekjoon(Long userId, Long challengeId); +} \ No newline at end of file diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/service/algo/AlgoChallengeServiceImpl.java b/backend/challenge-service/src/main/java/com/example/challengeservice/service/algo/AlgoChallengeServiceImpl.java new file mode 100644 index 0000000..942deba --- /dev/null +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/service/algo/AlgoChallengeServiceImpl.java @@ -0,0 +1,221 @@ +package com.example.challengeservice.service.algo; + +import com.example.challengeservice.client.UserServiceClient; +import com.example.challengeservice.client.dto.BaekjoonListResponseDto; +import com.example.challengeservice.client.dto.DateProblemResponseDto; +import com.example.challengeservice.client.dto.UserResponseDto; +import com.example.challengeservice.common.result.SingleResult; +import com.example.challengeservice.dto.request.ChallengeRecordRequestDto; +import com.example.challengeservice.dto.request.ProblemRequestDto; +import com.example.challengeservice.dto.response.ChallengeRoomResponseDto; +import com.example.challengeservice.dto.response.ProgressResponseDto; +import com.example.challengeservice.dto.response.SolvedListResponseDto; +import com.example.challengeservice.dto.response.SolvedMapResponseDto; +import com.example.challengeservice.entity.ChallengeRecord; +import com.example.challengeservice.entity.ChallengeRoom; +import com.example.challengeservice.entity.UserChallenge; +import com.example.challengeservice.exception.ApiException; +import com.example.challengeservice.exception.ExceptionEnum; +import com.example.challengeservice.repository.ChallengeRecordRepository; +import com.example.challengeservice.repository.UserChallengeRepository; +import com.example.challengeservice.service.challenge.BasicChallengeService; +import com.example.challengeservice.service.common.CommonServiceImpl; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.jsoup.Connection; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.IOException; +import java.util.*; + +@RequiredArgsConstructor +@Service +@Slf4j +public class AlgoChallengeServiceImpl implements AlgoChallengeService{ + private final UserServiceClient userServiceClient; + private final UserChallengeRepository userChallengeRepository; + private final CommonServiceImpl commonService; + private final ChallengeRecordRepository challengeRecordRepository; + private final BasicChallengeService basicChallengeService; + + /** + * explain : 회원이 푼 백준 문제 가져오기 + * @param baekjoonId :백준 아이디 + */ + @Override + public SolvedListResponseDto solvedProblemList(String baekjoonId) { + + String baekJoonUrl = "https://www.acmicpc.net/user/"; + baekJoonUrl+=baekjoonId; + Connection conn = Jsoup.connect(baekJoonUrl); + List solvedList= new ArrayList<>(); + + int count=0; + try { + Document document = conn.get(); + Elements imageUrlElements = document.getElementsByClass("problem-list"); + Element element = imageUrlElements.get(0); + Elements problems= element.getElementsByTag("a"); + for (Element problem : problems) { + solvedList.add(problem.text()); + count++; + } + } catch (IOException e) { + e.printStackTrace(); + } + return SolvedListResponseDto.from(solvedList, count); + } + + /** 유저의 백준리스트 업데이트 + * **/ + public void updateUserBaekjoon(Long userId){ + SingleResult userResponseDtoTemp = userServiceClient.getUserInfo(userId); + UserResponseDto userResponseDto=userResponseDtoTemp.getData(); + SingleResult baekjoonListResponseDto = userServiceClient.getUserBaekjoonList(userResponseDto.getUserId()); + + String baekjoonId = baekjoonListResponseDto.getData().getBaekjoonId(); + if(baekjoonId==null){ + return; + } + List diffSolvedList=new ArrayList<>(); + Map problemList = baekjoonListResponseDto.getData().getProblemList(); + List newSolvedList=solvedProblemList(baekjoonId).getSolvedList(); + for(String s:newSolvedList){ + if(problemList.get(s)==null){ + diffSolvedList.add(s); + } + } + if(diffSolvedList.size()==0){ + return; + } + userServiceClient.createProblem(userId, ProblemRequestDto.from(diffSolvedList)); + } + + /** + * 신대득 + * 선택한 유저가 선택한 날짜에 + * 푼 문제 리스트를 반환하는 메서드 + */ + public SolvedListResponseDto checkDateUserBaekjoon(Long userId, String selectDate){ + UserResponseDto userInfo = userServiceClient.getUserInfo(userId).getData(); + List dateBaekjoonList = userServiceClient.getDateBaekjoonList(userInfo.getUserId(), selectDate, selectDate).getData(); + List problemList=new ArrayList<>(); + for(DateProblemResponseDto problem:dateBaekjoonList){ + problemList.add(problem.getProblemId()); + } + return SolvedListResponseDto.from(userInfo.getUserId(), problemList, problemList.size(), selectDate); + } + + /** + * 해당 유저의 최근 5일 (오늘 ~ 4일전) + * 푼 문제 리스트를 반환하는 메서드 + */ + @Override + public SolvedMapResponseDto getRecentUserBaekjoon(Long userId) { + String today= commonService.getDate(); + String pastDay=commonService.getPastDay(5, commonService.getDate()); + + List dateBaekjoonList =userServiceClient.getDateBaekjoonList(userId,pastDay,today).getData(); + Map> myMap = new HashMap<>(); + for(int i=0;i<=5;i++){ + myMap.putIfAbsent(commonService.getPastDay(i,commonService.getDate()), new ArrayList<>()); + } + for(DateProblemResponseDto dateProblemResponseDto: dateBaekjoonList){ + String curDate=dateProblemResponseDto.getSuccessDate(); + List problemList= myMap.get(curDate); + problemList.add(dateProblemResponseDto.getProblemId()); + } + return SolvedMapResponseDto.algoFrom(myMap); + } + + /** + * 신대득 + * 알고리즘 문제 풀이 인증 기록을 저장하는 메서드 + * @param requestDto + */ + @Override + @Transactional + public void createAlgoRecord(ChallengeRecordRequestDto requestDto) { + ChallengeRoom challengeRoom = basicChallengeService.getChallengeRoomEntity(requestDto.getChallengeRoomId()); + + UserResponseDto user = userServiceClient.getUserInfo(requestDto.getUserId()).getData(); + + // 오늘 날짜 + String date = commonService.getDate(); + + + List todayProblemList = userServiceClient.getDateBaekjoonList(user.getUserId(), date, date).getData(); + + //challengeRoom에서 최소 알고리즘 개수 가져오기 미달이면 Exception 발생 + if(todayProblemList.size() new ApiException(ExceptionEnum.USER_CHALLENGE_NOT_EXIST_EXCEPTION)); + + + // 기존에 이 날짜에 인증기록이 있는지 검사 + Optional algoRecordResponseDto = challengeRecordRepository.findByCreateAtAndUserChallenge(date, userChallenge); + if(algoRecordResponseDto.isPresent()){ + if(algoRecordResponseDto.get().getAlgorithmCount()!=todayProblemList.size()){ + algoRecordResponseDto.get().setAlgorithmCount(todayProblemList.size()); + challengeRecordRepository.save(algoRecordResponseDto.get()); + } + + }else{ + ChallengeRecord challengeRecord = ChallengeRecord.fromAlgo(date, todayProblemList.size(), userChallenge); + challengeRecordRepository.save(challengeRecord); + } + } + + /** + * 알고리즘 + * 나의 인증현황 + * 진행률, 예치금 + 상금, 성공 / 실패 횟수 + */ + @Override + public ProgressResponseDto getProgressUserBaekjoon(Long userId, Long challengeId){ + + ChallengeRoomResponseDto challengeRoom=basicChallengeService.readChallenge(challengeId); + + UserChallenge userChallenge = userChallengeRepository.findByChallengeRoomIdAndUserId(challengeRoom.getId(), userId) + .orElseThrow(()-> new ApiException(ExceptionEnum.USER_CHALLENGE_LIST_NOT_EXIST)); + + Long challengeLength = commonService.diffDay(challengeRoom.getStartDate(), commonService.getDate()); + if(challengeLength<0){ + challengeLength=-1L; + } + challengeLength++; + Long successCount=0L; + List challengeRecordList = challengeRecordRepository.findAllByUserChallengeIdAndStartDateAndEndDate(userChallenge.getId(), challengeRoom.getStartDate(), challengeRoom.getEndDate(), true); + for(ChallengeRecord cr:challengeRecordList){ + switch(challengeRoom.getCategory()){ + case "ALGO": + if(cr.getAlgorithmCount()>=challengeRoom.getAlgorithmCount()) + successCount++; + break; + case "COMMIT": + if(cr.getCommitCount()>=challengeRoom.getCommitCount()) + successCount++; + break; + case "FREE": + if(cr.isSuccess()) + successCount++; + break; + } + } + Long failCount = challengeLength - successCount; + if(challengeLength==0){ + challengeLength++; + } + String progressRate= String.format("%.2f", (double)(successCount*100)/challengeLength); + + Long curPrice=userChallenge.getDiffPrice() + (long)challengeRoom.getEntryFee(); + return new ProgressResponseDto(progressRate, curPrice, successCount, failCount); + } +} diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/service/challenge/BasicChallengeService.java b/backend/challenge-service/src/main/java/com/example/challengeservice/service/challenge/BasicChallengeService.java index 7947ea8..56cd063 100644 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/service/challenge/BasicChallengeService.java +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/service/challenge/BasicChallengeService.java @@ -38,5 +38,12 @@ public interface BasicChallengeService { /** 챌린지방 Entity 가져오기*/ ChallengeRoom getChallengeRoomEntity(Long challengeRoomId); - + /** 챌린지내에서 1등부터 차례대로 랭킹을 반환 **/ + List getTopRank(Long challengeId); + /** 해당 방의 하루 정산 **/ + void oneDayCulc(ChallengeRoom challengeRoom); + /** 유저가 선택한 챌린지에 대한 증명서 정보를 반환하는 메서드 **/ + CertificationResponseDto getCertification(Long userId, Long challengeRoomId); + /** 방의 모든 유저의 백준 리스트 업데이트 **/ + void updateChallengeRoom(Long challengeRoomId); } diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/service/challenge/BasicChallengeServicelmpl.java b/backend/challenge-service/src/main/java/com/example/challengeservice/service/challenge/BasicChallengeServicelmpl.java index 22b7509..c875657 100644 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/service/challenge/BasicChallengeServicelmpl.java +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/service/challenge/BasicChallengeServicelmpl.java @@ -1,9 +1,12 @@ package com.example.challengeservice.service.challenge; import com.example.challengeservice.client.UserServiceClient; +import com.example.challengeservice.client.dto.UserResponseDto; import com.example.challengeservice.dto.request.ChallengeJoinRequestDto; +import com.example.challengeservice.dto.request.ChallengeRecordRequestDto; import com.example.challengeservice.dto.request.ChallengeRoomRequestDto; import com.example.challengeservice.dto.response.*; +import com.example.challengeservice.entity.ChallengeRecord; import com.example.challengeservice.entity.ChallengeRoom; import com.example.challengeservice.entity.UserChallenge; import com.example.challengeservice.exception.ApiException; @@ -13,6 +16,8 @@ import com.example.challengeservice.repository.ChallengeRecordRepository; import com.example.challengeservice.repository.ChallengeRoomRepository; import com.example.challengeservice.repository.UserChallengeRepository; +import com.example.challengeservice.service.algo.AlgoChallengeService; +import com.example.challengeservice.service.commit.CommitChallengeService; import com.example.challengeservice.service.common.CommonServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -25,9 +30,7 @@ import java.io.IOException; import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; @Service @RequiredArgsConstructor @@ -42,6 +45,8 @@ public class BasicChallengeServicelmpl implements BasicChallengeService{ private final UserChallengeRepository userChallengeRepository; private final ChallengeRecordRepository recordRepository; + private final CommitChallengeService commitChallengeService; + private final AlgoChallengeService algoChallengeService; /** * author : 홍금비 @@ -272,5 +277,152 @@ public List getTeamRecord(Long userId ,Long challengeId , Str } } + /** + * 현재 챌린지 방의 탑 랭크 리스트 조회 + */ + @Override + public List getTopRank(Long challengeId) { + ChallengeRoom challengeRoom = getChallengeRoomEntity(challengeId); + List userChallengesByChallengeRoomId = userChallengeRepository.findAllByChallengeRoomId(challengeRoom.getId()); + List rankResponseDtoList = new ArrayList<>(); + Long period = commonService.diffDay(challengeRoom.getStartDate(), challengeRoom.getEndDate()) + 1; + for (UserChallenge uc : userChallengesByChallengeRoomId) { + // 현재 uc 중 챌린지 기간 동안의 레코드 조회 + switch (challengeRoom.getCategory()) { + case "ALGO": + List challengeAlgoRecordList = recordRepository.findAllByUserChallengeIdAndStartDateAndEndDateAlgo(uc.getId(), challengeRoom.getStartDate(), challengeRoom.getEndDate(), true, challengeRoom.getAlgorithmCount()); + rankResponseDtoList.add(new RankResponseDto(0L, uc.getUserId(), uc.getNickname(), (long) challengeAlgoRecordList.size(), period - (long) challengeAlgoRecordList.size())); + break; + case "COMMIT": + List challengeCommitRecordList = recordRepository.findAllByUserChallengeIdAndStartDateAndEndDateCommit(uc.getId(), challengeRoom.getStartDate(), challengeRoom.getEndDate(), true, challengeRoom.getCommitCount()); + rankResponseDtoList.add(new RankResponseDto(0L, uc.getUserId(), uc.getNickname(), (long) challengeCommitRecordList.size(), period - (long) challengeCommitRecordList.size())); + break; + case "FREE": + List challengeFreeRecordList = recordRepository.findAllByUserChallengeIdAndStartDateAndEndDateFree(uc.getId(), challengeRoom.getStartDate(), challengeRoom.getEndDate(), true); + rankResponseDtoList.add(new RankResponseDto(0L, uc.getUserId(), uc.getNickname(), (long) challengeFreeRecordList.size(), period-(long)challengeFreeRecordList.size())); + break; + } + Collections.sort(rankResponseDtoList); + for (int i = 0; i < rankResponseDtoList.size(); i++) { + rankResponseDtoList.get(i).setRank((long) i + 1); + } + } + return rankResponseDtoList; + } + + /** + * 하루 정산 + * 일단 현재 진행중인 챌린지 방을 받아와야함 입력값으로!! + * **/ + @Override + @Transactional + public void oneDayCulc(ChallengeRoom challengeRoom) { + Integer period = commonService.diffDay(challengeRoom.getStartDate(), challengeRoom.getEndDate()).intValue(); + int oneDayFee = (int)Math.ceil((double) challengeRoom.getEntryFee() / (period+1)); + String beforeOneDay = commonService.getPastDay(0, commonService.getDate()); + + if(commonService.diffDay(beforeOneDay, challengeRoom.getEndDate())<0 || commonService.diffDay(challengeRoom.getStartDate(), beforeOneDay) <0){ + return; + } + + List userChallengeList = userChallengeRepository.findUserChallengesByChallengeRoomId(challengeRoom.getId()); + List successList=new ArrayList<>(); + List failList=new ArrayList<>(); + for (UserChallenge userChallenge : userChallengeList) { + + List challengeRecord = recordRepository.findByUserChallengeIdAndCreateAt(userChallenge.getId(), beforeOneDay); + if(challengeRecord.size()==0){ + failList.add(userChallenge); + }else{ + if (!(challengeRecord.get(0).isSuccess())) { + failList.add(userChallenge); + } else{ + successList.add(userChallenge); + } + } + } + + Long sum=0L; + for(UserChallenge userChallenge: failList){ + + userChallenge.setDiffPrice(userChallenge.getDiffPrice()-oneDayFee); + userChallengeRepository.save(userChallenge); + sum+=oneDayFee; + } + + Long todayMoney=Long.valueOf((long)Math.ceil((double)sum/successList.size())); + for(UserChallenge userChallenge: successList){ + userChallenge.setDiffPrice(userChallenge.getDiffPrice()+todayMoney); + userChallengeRepository.save(userChallenge); + } + + } + + + /** + 현재 유저가 들어온 방에서 자신의 진행율을 계산하는 메서드 + */ + public String getProgressRate(Long userChallengeId, ChallengeRoomResponseDto challengeRoom){ + + Long challengeLength = commonService.diffDay(challengeRoom.getStartDate(), challengeRoom.getEndDate()); + if(challengeLength < 0){ + challengeLength = -1L; + } + challengeLength++; + Long successCount = 0L; + List challengeRecordList = recordRepository.findAllByUserChallengeIdAndStartDateAndEndDate(userChallengeId, challengeRoom.getStartDate(), challengeRoom.getEndDate(), true); + if(challengeRecordList.size() == 0){ + return "0"; + } + for(ChallengeRecord cr:challengeRecordList){ + switch(challengeRoom.getCategory()){ + case "ALGO": + if(cr.getAlgorithmCount()>=challengeRoom.getAlgorithmCount()) + successCount++; + break; + case "COMMIT": + if(cr.getCommitCount()>=challengeRoom.getCommitCount()) + successCount++; + break; + case "FREE": + if(cr.isSuccess()) + successCount++; + break; + } + } + if(challengeLength==0){ + challengeLength++; + } + return String.format("%.2f", (double)(successCount*100)/challengeLength); + } + + /** + * 유저가 선택한 챌린지의 인증서 정보를 조회하는 메서드 + */ + public CertificationResponseDto getCertification(Long userId, Long challengeRoomId){ + ChallengeRoomResponseDto challengeRoom = readChallenge(challengeRoomId); + UserChallenge userChallenge = userChallengeRepository.findByChallengeRoomIdAndUserId(challengeRoomId, userId) + .orElseThrow(() -> new ApiException(ExceptionEnum.USER_CHALLENGE_NOT_EXIST_EXCEPTION)); + UserResponseDto userResponseDto= userServiceClient.getUserInfo(userId).getData(); + String progressRate= getProgressRate(userChallenge.getId(), challengeRoom); + + return new CertificationResponseDto(userResponseDto.getName(), userChallenge.getChallengeRoom().getTitle(), userChallenge.getChallengeRoom().getStartDate(), + userChallenge.getChallengeRoom().getEndDate(), progressRate, userChallenge.getId()); + } + + /** 챌린지 방 업데이트 하기 **/ + public void updateChallengeRoom(Long challengeRoomId){ + ChallengeRoom challengeRoom = getChallengeRoomEntity(challengeRoomId); + List userChallengeList = userChallengeRepository.findAllByChallengeRoomId(challengeRoom.getId()); + for(UserChallenge uc :userChallengeList){ + if(challengeRoom.getCategory().equals("ALGO")){ + algoChallengeService.updateUserBaekjoon(uc.getUserId()); + algoChallengeService.createAlgoRecord(ChallengeRecordRequestDto.from(uc.getUserId(),challengeRoomId)); + } else if(challengeRoom.getCategory().equals("COMMIT")){ + commitChallengeService.updateUserCommit(uc.getUserId()); + commitChallengeService.createCommitRecord(ChallengeRecordRequestDto.from(uc.getUserId(),challengeRoomId)); + } + } + } } diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/service/commit/CommitChallengeService.java b/backend/challenge-service/src/main/java/com/example/challengeservice/service/commit/CommitChallengeService.java new file mode 100644 index 0000000..57afb0b --- /dev/null +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/service/commit/CommitChallengeService.java @@ -0,0 +1,19 @@ +package com.example.challengeservice.service.commit; + +import com.example.challengeservice.client.dto.CommitResponseDto; +import com.example.challengeservice.dto.request.ChallengeRecordRequestDto; +import com.example.challengeservice.dto.response.CommitCountResponseDto; +import com.example.challengeservice.dto.response.SolvedMapResponseDto; + +public interface CommitChallengeService { + /** 깃허브 커밋 리스트 찾기 **/ + CommitCountResponseDto getGithubCommit(String githubId); + /** 유저의 커밋리스트 업데이트 **/ + void updateUserCommit(Long userId); + /** 해당 유저가 해당 날짜에 커밋한 개수를 조회 **/ + CommitResponseDto checkDateUserCommit(Long userId, String selectDate); + /** 해당 유저가 최근 5일 동안의 커밋 개수 조회 **/ + SolvedMapResponseDto getRecentUserCommit(Long userId); + /** 커밋 인증 기록을 저장 **/ + void createCommitRecord(ChallengeRecordRequestDto requestDto); +} diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/service/commit/CommitChallengeServiceImpl.java b/backend/challenge-service/src/main/java/com/example/challengeservice/service/commit/CommitChallengeServiceImpl.java new file mode 100644 index 0000000..b248a4c --- /dev/null +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/service/commit/CommitChallengeServiceImpl.java @@ -0,0 +1,148 @@ +package com.example.challengeservice.service.commit; + +import com.example.challengeservice.client.UserServiceClient; +import com.example.challengeservice.client.dto.CommitResponseDto; +import com.example.challengeservice.client.dto.UserResponseDto; +import com.example.challengeservice.common.result.SingleResult; +import com.example.challengeservice.dto.request.ChallengeRecordRequestDto; +import com.example.challengeservice.dto.request.CommitRequestDto; +import com.example.challengeservice.dto.response.CommitCountResponseDto; +import com.example.challengeservice.dto.response.SolvedMapResponseDto; +import com.example.challengeservice.entity.ChallengeRecord; +import com.example.challengeservice.entity.ChallengeRoom; +import com.example.challengeservice.entity.UserChallenge; +import com.example.challengeservice.exception.ApiException; +import com.example.challengeservice.exception.ExceptionEnum; +import com.example.challengeservice.repository.ChallengeRecordRepository; +import com.example.challengeservice.repository.UserChallengeRepository; +import com.example.challengeservice.service.challenge.BasicChallengeService; +import com.example.challengeservice.service.common.CommonService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.jsoup.Connection; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.IOException; +import java.util.*; + + +@RequiredArgsConstructor +@Service +@Slf4j +public class CommitChallengeServiceImpl implements CommitChallengeService{ + private final CommonService commonService; + private final UserServiceClient userServiceClient; + private final BasicChallengeService basicChallengeService; + private final UserChallengeRepository userChallengeRepository; + private final ChallengeRecordRepository challengeRecordRepository; + + /** + * githubId로 commit 정보가져오기 + */ + @Override + public CommitCountResponseDto getGithubCommit(String githubId){ + String githubUrl = "https://github.com/"; + githubUrl+=githubId; + Connection conn = Jsoup.connect(githubUrl); + List solvedList= new ArrayList<>(); + int commitCount=0; + try { + Document document = conn.get(); + Elements imageUrlElements = document.getElementsByClass("js-calendar-graph-svg"); + Element element = imageUrlElements.get(0); + String today = commonService.getDate(); + Element todayElement= element.getElementsByTag("Rect").last().getElementsByAttributeValue("data-date", today).first(); + StringTokenizer st= new StringTokenizer(todayElement.text(), " "); + String commitString=st.nextToken(); + if(!commitString.equals("No")){ + commitCount=Integer.parseInt(commitString); + } + + } catch (IOException e) { + e.printStackTrace(); + } catch (Exception e){ + e.printStackTrace(); + } + return CommitCountResponseDto.from(githubId, commitCount); + } + + /** 유저의 커밋리스트 업데이트 **/ + public void updateUserCommit(Long userId) { + SingleResult userResponseDtoTemp = userServiceClient.getUserInfo(userId); + UserResponseDto userResponseDto = userResponseDtoTemp.getData(); + + String today = commonService.getDate(); + // 오늘 날짜의 유저의 커밋 수 조회 + CommitCountResponseDto commitCountResponseDto=getGithubCommit(userResponseDto.getGithub()); + if(commitCountResponseDto.getCommitCount()==0){ + return; + } + userServiceClient.updateCommitCount(userResponseDto.getUserId(), new CommitRequestDto(today, commitCountResponseDto.getCommitCount())); + } + + /** + * 신대득 + * 선택한 유저가 선택한 날짜에 + * 커밋 개수를 반환하는 메서드 + */ + public CommitResponseDto checkDateUserCommit(Long userId, String selectDate){ + updateUserCommit(userId); + CommitResponseDto commitResponseDto = userServiceClient.getCommitRecord(userId, selectDate).getData(); + return commitResponseDto; + } + + /** 해당 유저가 최근 5일 동안의 커밋 개수 조회 **/ + @Override + public SolvedMapResponseDto getRecentUserCommit(Long userId) { + String today=commonService.getDate(); + String pastDay=commonService.getPastDay(5, today); + List dateCommitList = userServiceClient.getDateCommitList(userId, pastDay, today).getData(); + + Map myMap = new HashMap<>(); + + for(CommitResponseDto commitResponseDto: dateCommitList){ + myMap.put(commitResponseDto.getCommitDate(), commitResponseDto.getCommitCount()); + } + return SolvedMapResponseDto.commitFrom(myMap); + } + + /** + * 커밋 인증 기록을 저장하는 메서드 + */ + @Override + @Transactional + public void createCommitRecord(ChallengeRecordRequestDto requestDto) { + ChallengeRoom challengeRoom = basicChallengeService.getChallengeRoomEntity(requestDto.getChallengeRoomId()); + UserResponseDto user = userServiceClient.getUserInfo(requestDto.getUserId()).getData(); + + String date = commonService.getDate(); + + + SingleResult commitResponseDto = userServiceClient.getCommitRecord(user.getUserId(), date); + + if(commitResponseDto.getData().getCommitCount() new ApiException(ExceptionEnum.USER_CHALLENGE_NOT_EXIST_EXCEPTION)); + + Optional commitRecordResponseDto = challengeRecordRepository.findByCreateAtAndUserChallenge(date, userChallenge); + if(commitRecordResponseDto.isPresent()){ + + if(commitRecordResponseDto.get().getCommitCount()!=commitResponseDto.getData().getCommitCount()){ + commitRecordResponseDto.get().setCommitCount(commitResponseDto.getData().getCommitCount()); + challengeRecordRepository.save(commitRecordResponseDto.get()); + } + + }else{ + ChallengeRecord challengeRecord = ChallengeRecord.fromCommit(date, commitResponseDto.getData().getCommitCount(), userChallenge); + challengeRecordRepository.save(challengeRecord); + } + } +} diff --git a/backend/challenge-service/src/main/java/com/example/challengeservice/service/common/CommonServiceImpl.java b/backend/challenge-service/src/main/java/com/example/challengeservice/service/common/CommonServiceImpl.java index d3214d1..803ebea 100644 --- a/backend/challenge-service/src/main/java/com/example/challengeservice/service/common/CommonServiceImpl.java +++ b/backend/challenge-service/src/main/java/com/example/challengeservice/service/common/CommonServiceImpl.java @@ -44,6 +44,7 @@ public String getPastDay(int n ,String dateString) { return formatter.format(cal.getTime()); } + /** startDate~ endDate의 기간 얻기 **/ @Override public Long diffDay(String startDate, String endDate){ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");