From 2b66eb1cb8a4ef85f1228fb5821b46e54c90a6b8 Mon Sep 17 00:00:00 2001 From: joonghyun Date: Mon, 1 Jul 2024 19:12:33 +0900 Subject: [PATCH 1/5] =?UTF-8?q?#89=20fix:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20dto=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/dto/GetAttendanceRes.java | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 src/main/java/ollie/wecare/challenge/dto/GetAttendanceRes.java diff --git a/src/main/java/ollie/wecare/challenge/dto/GetAttendanceRes.java b/src/main/java/ollie/wecare/challenge/dto/GetAttendanceRes.java deleted file mode 100644 index 1aa8de8..0000000 --- a/src/main/java/ollie/wecare/challenge/dto/GetAttendanceRes.java +++ /dev/null @@ -1,33 +0,0 @@ -package ollie.wecare.challenge.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import ollie.wecare.challenge.entity.ChallengeAttendance; -import ollie.wecare.program.dto.DateDto; - -import java.time.LocalDateTime; - -@Data -@AllArgsConstructor -@Builder -@NoArgsConstructor -public class GetAttendanceRes { - private DateDto attendanceDate; - - public static GetAttendanceRes fromAttendance(ChallengeAttendance attendance) { - return GetAttendanceRes.builder(). - attendanceDate(convertToDateDto(attendance.getAttendanceDate())).build(); - } - - private static DateDto convertToDateDto(LocalDateTime dueDate) { - if (dueDate == null) return null; - return new DateDto( - dueDate.getYear(), - dueDate.getMonthValue(), - dueDate.getDayOfMonth()); - } - - -} From bad3697e3d15698c5e4e11f83af34d5470a158f0 Mon Sep 17 00:00:00 2001 From: joonghyun Date: Mon, 1 Jul 2024 19:14:27 +0900 Subject: [PATCH 2/5] =?UTF-8?q?#89=20fix:=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ChallengeController.java | 65 +++----- .../dto/ChallengeDetailResponse.java | 12 ++ .../ChallengeAttendanceRepository.java | 7 +- .../repository/ChallengeRepository.java | 2 +- .../challenge/service/ChallengeService.java | 156 +++++++++--------- .../common/base/BaseResponseStatus.java | 2 +- 6 files changed, 115 insertions(+), 129 deletions(-) create mode 100644 src/main/java/ollie/wecare/challenge/dto/ChallengeDetailResponse.java diff --git a/src/main/java/ollie/wecare/challenge/controller/ChallengeController.java b/src/main/java/ollie/wecare/challenge/controller/ChallengeController.java index f98807d..8353dd1 100644 --- a/src/main/java/ollie/wecare/challenge/controller/ChallengeController.java +++ b/src/main/java/ollie/wecare/challenge/controller/ChallengeController.java @@ -7,6 +7,7 @@ import ollie.wecare.challenge.service.ChallengeService; import ollie.wecare.common.base.BaseException; import ollie.wecare.common.base.BaseResponse; +import ollie.wecare.user.service.AuthService; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -21,75 +22,51 @@ public class ChallengeController { private final ChallengeService challengeService; + private final AuthService authService; - /* - * 참여 중인 챌린지 조회 - * */ + // 참여 중인 챌린지 목록 조회 @GetMapping - @ResponseBody public BaseResponse> getMyChallenges() throws BaseException { - return new BaseResponse<>(challengeService.getMyChallenges()); + return challengeService.getMyChallenges(authService.getUserIdx()); } - /* - * 챌린지 인증코드 발급 - * */ + // 챌린지 인증코드 발급 @PostMapping("/attendance/{challengeIdx}") - @ResponseBody public BaseResponse getAttendanceCode(@PathVariable(value = "challengeIdx") Long challengeIdx) { return new BaseResponse<>(challengeService.getAttendanceCode(challengeIdx)); } - - /* - * 챌린지 인증 - * */ + // 챌린지 인증 //TODO : PathVariable로 변경 @PostMapping("/attendance") - @ResponseBody public BaseResponse attendChallenge(@RequestBody AttendChallengeReq attendChallengeReq) throws BaseException { challengeService.attendChallenge(attendChallengeReq); return new BaseResponse<>(SUCCESS); } - /* - * 챌린지 참여 현황 조회(월별) - * */ + // 챌린지 상세 조회 @GetMapping("/attendance/{challengeIdx}") - @ResponseBody - public BaseResponse> getAttendance(@PathVariable("challengeIdx") Long challengeIdx, - @RequestParam(value = "year", required = false, defaultValue = "0") Long year, - @RequestParam(value = "month", required = false, defaultValue = "0") Long month) { - return new BaseResponse<>(challengeService.getAttendance(challengeIdx, year, month)); + public BaseResponse getChallengeDetail(@PathVariable Long challengeIdx) { + return challengeService.getChallengeDetail(authService.getUserIdx(), challengeIdx); } - /* - * 새로운 챌린지 참여 - * */ + // 새로운 챌린지 참여 @PostMapping("/participation") - @ResponseBody public BaseResponse participateChallenge(@RequestBody PostChallengeReq postChallengeReq) throws BaseException { challengeService.participateChallenge(postChallengeReq); return new BaseResponse<>(SUCCESS); - } - /* - * 챌린지 검색 - * */ - @GetMapping("/search") - @ResponseBody - public BaseResponse> getChallenges(@RequestParam(value = "searchWord", defaultValue = "", required = false) String searchWord)throws BaseException { - return new BaseResponse<>(challengeService.getChallenges(searchWord)); - } - - /* - * 챌린지 광고 조회 - * */ - @GetMapping("/ads") - @ResponseBody - public BaseResponse getChallengeAds() { - return new BaseResponse<>(challengeService.getChallengeAds()); - } +// // 챌린지 검색 +// @GetMapping("/search") +// public BaseResponse> getChallenges(@RequestParam(value = "searchWord", defaultValue = "", required = false) String searchWord)throws BaseException { +// return new BaseResponse<>(challengeService.getChallenges(searchWord)); +// } + +// // 챌린지 광고 조회 +// @GetMapping("/ads") +// public BaseResponse getChallengeAds() { +// return new BaseResponse<>(challengeService.getChallengeAds()); +// } } diff --git a/src/main/java/ollie/wecare/challenge/dto/ChallengeDetailResponse.java b/src/main/java/ollie/wecare/challenge/dto/ChallengeDetailResponse.java new file mode 100644 index 0000000..59a6c9e --- /dev/null +++ b/src/main/java/ollie/wecare/challenge/dto/ChallengeDetailResponse.java @@ -0,0 +1,12 @@ +package ollie.wecare.challenge.dto; + +import ollie.wecare.program.dto.DateDto; + +import java.util.List; + +public record ChallengeDetailResponse(String name, + Integer participantsCount, + List attendanceList, + Integer totalAchievementRate, + Integer myAchievementRate) { +} diff --git a/src/main/java/ollie/wecare/challenge/repository/ChallengeAttendanceRepository.java b/src/main/java/ollie/wecare/challenge/repository/ChallengeAttendanceRepository.java index 9dcbbe2..60657a3 100644 --- a/src/main/java/ollie/wecare/challenge/repository/ChallengeAttendanceRepository.java +++ b/src/main/java/ollie/wecare/challenge/repository/ChallengeAttendanceRepository.java @@ -1,15 +1,18 @@ package ollie.wecare.challenge.repository; +import ollie.wecare.challenge.entity.Challenge; import ollie.wecare.challenge.entity.ChallengeAttendance; +import ollie.wecare.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import java.time.LocalDateTime; import java.util.List; @Repository public interface ChallengeAttendanceRepository extends JpaRepository { List findByUser_UserIdx(Long userIdx); List findByUser_UserIdxAndChallenge_ChallengeIdx(Long userIdx, Long challengeIdx); - List findByUser_UserIdxAndChallenge_ChallengeIdxAndAttendanceDateBetweenOrderByAttendanceDate(Long userIdx, Long challengeIdx, LocalDateTime start, LocalDateTime last); + List findByUserAndChallengeOrderByCreatedDate(User user, Challenge challenge); + Integer countByUserAndChallenge(User user, Challenge challenge); + List findByUserAndStatusEquals(User user, String status); } diff --git a/src/main/java/ollie/wecare/challenge/repository/ChallengeRepository.java b/src/main/java/ollie/wecare/challenge/repository/ChallengeRepository.java index 383b30e..ccf4a06 100644 --- a/src/main/java/ollie/wecare/challenge/repository/ChallengeRepository.java +++ b/src/main/java/ollie/wecare/challenge/repository/ChallengeRepository.java @@ -23,5 +23,5 @@ public interface ChallengeRepository extends JpaRepository { Page findMostParticipatedChallenge(Pageable pageable); Optional findTop1ByOrderByCreatedDateDesc(); - + Optional findByChallengeIdxAndStatusEquals(Long challengeIdx, String status); } diff --git a/src/main/java/ollie/wecare/challenge/service/ChallengeService.java b/src/main/java/ollie/wecare/challenge/service/ChallengeService.java index 78e5a5e..fe1021b 100644 --- a/src/main/java/ollie/wecare/challenge/service/ChallengeService.java +++ b/src/main/java/ollie/wecare/challenge/service/ChallengeService.java @@ -8,23 +8,21 @@ import ollie.wecare.challenge.repository.ChallengeAttendanceRepository; import ollie.wecare.challenge.repository.ChallengeRepository; import ollie.wecare.common.base.BaseException; +import ollie.wecare.common.base.BaseResponse; import ollie.wecare.common.enums.Role; +import ollie.wecare.program.dto.DateDto; import ollie.wecare.user.entity.User; import ollie.wecare.user.repository.UserRepository; import ollie.wecare.user.service.AuthService; -import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDate; import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.temporal.TemporalAdjusters; import java.util.*; -import java.util.stream.Collectors; + import static ollie.wecare.common.base.BaseResponseStatus.*; +import static ollie.wecare.common.constants.Constants.ACTIVE; @Service @RequiredArgsConstructor @@ -38,22 +36,17 @@ public class ChallengeService { private final AuthService authService; - /* - * 참여 중인 챌린지 조회 - * */ - public List getMyChallenges() throws BaseException { - //TODO : 특정 get 요청만 인증받지 않도록 변경 - Long userIdx = authService.getUserIdx(); - if(userIdx == null) throw new BaseException(INVALID_ACCESS_TOKEN); - List participationList = challengeAttendanceRepository.findByUser_UserIdx(userIdx); - Long participationNum = (long)participationList.size(); - - Set challengeSet = new HashSet<>(); - for(ChallengeAttendance ca : participationList) - challengeSet.add(ca.getChallenge()); - - List challengesList = new ArrayList<>(challengeSet); - return challengesList.stream().map(challenge -> GetChallengesRes.fromChallenge(challenge, participationNum)).toList(); + // 참여중인 챌린지 목록 조회 + public BaseResponse> getMyChallenges(Long userIdx) throws BaseException { + User user = userRepository.findByUserIdxAndStatusEquals(userIdx, ACTIVE).orElseThrow(() -> new BaseException(INVALID_USER_IDX)); + + List attendances = challengeAttendanceRepository.findByUserAndStatusEquals(user, ACTIVE); + List challenges = attendances.stream() + .map(ChallengeAttendance::getChallenge) + .distinct() + .toList(); + List challengeList = challenges.stream().map(challenge -> GetChallengesRes.fromChallenge(challenge, calculateMyAchievementRate(user, challenge))).toList(); + return new BaseResponse<>(challengeList); } /* @@ -73,7 +66,6 @@ public GetAttendanceCodeReq getAttendanceCode(Long challengeIdx) { return GetAttendanceCodeReq.builder().code(code).build(); } - /* * 챌린지 인증 * */ @@ -85,7 +77,7 @@ public void attendChallenge(AttendChallengeReq attendChallengeReq) throws BaseEx ChallengeAttendance challengeAttendance = ChallengeAttendance.builder() .user(userRepository.findById(authService.getUserIdx()).orElseThrow(()->new BaseException(INVALID_ACCESS_TOKEN))) .challenge(challengeRepository.findById(attendChallengeReq.getChallengeIdx()).orElseThrow(()-> new BaseException(INVALID_CHALLENGE_IDX))) - .attendanceDate(LocalDateTime.now()).build(); + .build(); challengeAttendanceRepository.save(challengeAttendance); } } @@ -98,70 +90,72 @@ public void participateChallenge(PostChallengeReq postChallengeReq) throws BaseE ChallengeAttendance challengeAttendance = ChallengeAttendance.builder() .user(userRepository.findById(authService.getUserIdx()).orElseThrow(()->new BaseException(INVALID_ACCESS_TOKEN))) .challenge(challengeRepository.findById(postChallengeReq.getChallengeIdx()).orElseThrow(()-> new BaseException(INVALID_CHALLENGE_IDX))) - .attendanceDate(LocalDateTime.now()).build(); + .build(); challengeAttendanceRepository.save(challengeAttendance); } - /* - * 챌린지 검색 - * */ - public List getChallenges(String searchWord) { - Long userIdx = authService.getUserIdx(); - if(userIdx == null) throw new BaseException(INVALID_ACCESS_TOKEN); - List challenges = challengeRepository.findByNameContaining(searchWord); - List challengeResult = new ArrayList<>(); - for(Challenge challenge : challenges) { - List challengeAttendances = challengeAttendanceRepository.findByUser_UserIdxAndChallenge_ChallengeIdx(userIdx, challenge.getChallengeIdx()); - if(challengeAttendances == null || challengeAttendances.isEmpty()) - challengeResult.add(challenge); - } - - return challengeResult.stream().map(challenge -> GetChallengesRes.fromChallenge(challenge, 0L)).toList(); +// /* +// * 챌린지 검색 +// * */ +// public List getChallenges(String searchWord) { +// Long userIdx = authService.getUserIdx(); +// if(userIdx == null) throw new BaseException(INVALID_ACCESS_TOKEN); +// List challenges = challengeRepository.findByNameContaining(searchWord); +// List challengeResult = new ArrayList<>(); +// +// for(Challenge challenge : challenges) { +// List challengeAttendances = challengeAttendanceRepository.findByUser_UserIdxAndChallenge_ChallengeIdx(userIdx, challenge.getChallengeIdx()); +// if(challengeAttendances == null || challengeAttendances.isEmpty()) +// challengeResult.add(challenge); +// } +// return challengeResult.stream().map(challenge -> GetChallengesRes.fromChallenge(challenge, 0L).toList(); +// } + + // 챌린지 상세 조회 + public BaseResponse getChallengeDetail(Long userIdx, Long challengeIdx) { + User user = userRepository.findByUserIdxAndStatusEquals(userIdx, ACTIVE).orElseThrow(() -> new BaseException(INVALID_USER_IDX)); + Challenge challenge = challengeRepository.findByChallengeIdxAndStatusEquals(challengeIdx, ACTIVE).orElseThrow(() -> new BaseException(INVALID_CHALLENGE_IDX)); + if (!challenge.getParticipants().contains(user)) throw new BaseException(NO_PARTICIPANT); + + List attendanceList = challengeAttendanceRepository.findByUserAndChallengeOrderByCreatedDate(user, challenge).stream() + .map(challengeAttendance -> convertToDateDto(challengeAttendance.getCreatedDate())) + .toList(); + + ChallengeDetailResponse challengeDetail = new ChallengeDetailResponse(challenge.getName(), challenge.getParticipants().size(), + attendanceList, challenge.getAttendanceRate(), calculateMyAchievementRate(user, challenge)); + return new BaseResponse<>(challengeDetail); } - /* - * 챌린지 참여 현황 조회(월별) - * */ - public List getAttendance(Long challengeIdx, Long year, Long month) { - Long userIdx = authService.getUserIdx(); - if(userIdx == null) throw new BaseException(INVALID_ACCESS_TOKEN); - int y = year != null && year > 0 ? year.intValue() : LocalDateTime.now().getYear(); - int m = month != null && month > 0 ? month.intValue() : LocalDateTime.now().getMonthValue(); - - LocalDateTime firstDay = LocalDate.of(y, m, 1).atStartOfDay(); - LocalDateTime lastDay = firstDay.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX); - - /*int y = year.intValue(); - int m = month.intValue(); - LocalDateTime firstDay = LocalDate.of(y, m, 1).atStartOfDay(); - LocalDateTime lastDay = LocalDate.of(y, m, 1).atStartOfDay(); - if(year == 0) { - firstDay = YearMonth.from(LocalDateTime.now().toLocalDate()).atDay(1).atStartOfDay(); - lastDay = YearMonth.from(LocalDateTime.now().toLocalDate()).atEndOfMonth().atStartOfDay(); - }*/ - return challengeAttendanceRepository.findByUser_UserIdxAndChallenge_ChallengeIdxAndAttendanceDateBetweenOrderByAttendanceDate(userIdx, challengeIdx, firstDay, lastDay) - .stream() - .skip(1L) - .map(challengeAttendance -> GetAttendanceRes.fromAttendance(challengeAttendance)) - .collect(Collectors.toList()); + // DateDto 형태 변환 + private static DateDto convertToDateDto(LocalDateTime dateTime) { + if (dateTime == null) return null; + return new DateDto( + dateTime.getYear(), + dateTime.getMonthValue(), + dateTime.getDayOfMonth()); } - /* - * 챌린지 배너 조회 (홈화면) - * */ - public GetChallengeAdsRes getChallengeAds() { - - Challenge mostAttendancedChallenge = challengeRepository.findTop1ByOrderByAttendanceRateDesc().orElseThrow(()-> new BaseException(NO_CHALLENGE)); - Challenge mostParticipatedChallenge = challengeRepository.findMostParticipatedChallenge(PageRequest.of(0, 1)).getContent().get(0); - Challenge mostRecentlyStartedChallenge = challengeRepository.findTop1ByOrderByCreatedDateDesc().orElseThrow(()-> new BaseException(NO_CHALLENGE)); - - - return GetChallengeAdsRes.builder() - .mostAttendancedChallenge(GetChallengesRes.fromChallenge(mostAttendancedChallenge, 0L)) - .mostParticipatedChallenge(GetChallengesRes.fromChallenge(mostParticipatedChallenge, 0L)) - .mostRecentlyStartedChallenge(GetChallengesRes.fromChallenge(mostRecentlyStartedChallenge, 0L)).build(); - + // 챌린지 개인 달성률 계산 + private Integer calculateMyAchievementRate(User user, Challenge challenge) { + Integer attendanceCount = challengeAttendanceRepository.countByUserAndChallenge(user, challenge); + if (attendanceCount == null) return 0; + else return (attendanceCount/challenge.getTotalNum()) * 100; } - +// /* +// * 챌린지 배너 조회 (홈화면) +// * */ +// public GetChallengeAdsRes getChallengeAds() { +// +// Challenge mostAttendancedChallenge = challengeRepository.findTop1ByOrderByAttendanceRateDesc().orElseThrow(()-> new BaseException(NO_CHALLENGE)); +// Challenge mostParticipatedChallenge = challengeRepository.findMostParticipatedChallenge(PageRequest.of(0, 1)).getContent().get(0); +// Challenge mostRecentlyStartedChallenge = challengeRepository.findTop1ByOrderByCreatedDateDesc().orElseThrow(()-> new BaseException(NO_CHALLENGE)); +// +// +// return GetChallengeAdsRes.builder() +// .mostAttendancedChallenge(GetChallengesRes.fromChallenge(mostAttendancedChallenge, 0L)) +// .mostParticipatedChallenge(GetChallengesRes.fromChallenge(mostParticipatedChallenge, 0L)) +// .mostRecentlyStartedChallenge(GetChallengesRes.fromChallenge(mostRecentlyStartedChallenge, 0L)).build(); +// +// } } diff --git a/src/main/java/ollie/wecare/common/base/BaseResponseStatus.java b/src/main/java/ollie/wecare/common/base/BaseResponseStatus.java index a2b2f1b..de4d7bf 100644 --- a/src/main/java/ollie/wecare/common/base/BaseResponseStatus.java +++ b/src/main/java/ollie/wecare/common/base/BaseResponseStatus.java @@ -35,9 +35,9 @@ public enum BaseResponseStatus { ACCESS_DENIED(false, HttpStatus.BAD_REQUEST, "접근 권한이 없습니다."), NULL_ACCESS_TOKEN(false, HttpStatus.BAD_REQUEST, "Access token이 비었습니다."), - // program INVALID_PROGRAM_IDX(false, HttpStatus.BAD_REQUEST, "잘못된 ProgramIdx 입니다."), + NO_PARTICIPANT(false, HttpStatus.BAD_REQUEST, "해당 챌린지의 참여자가 아닙니다."), // challenge INVALID_ATTENDANCE_CODE(false, HttpStatus.BAD_REQUEST, "잘못된 인증번호입니다."), From fcf6a8dbd95d5744c1e049d967e737b3353568bc Mon Sep 17 00:00:00 2001 From: joonghyun Date: Mon, 1 Jul 2024 19:15:27 +0900 Subject: [PATCH 3/5] =?UTF-8?q?#89=20fix:=20challenge=EC=9D=98=20totalNum,?= =?UTF-8?q?=20attendanceRate=EC=9D=84=20Integer=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wecare/challenge/dto/GetChallengesRes.java | 13 ++++++------- .../ollie/wecare/challenge/entity/Challenge.java | 6 ++---- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/java/ollie/wecare/challenge/dto/GetChallengesRes.java b/src/main/java/ollie/wecare/challenge/dto/GetChallengesRes.java index 0424f05..95263f2 100644 --- a/src/main/java/ollie/wecare/challenge/dto/GetChallengesRes.java +++ b/src/main/java/ollie/wecare/challenge/dto/GetChallengesRes.java @@ -16,27 +16,26 @@ public class GetChallengesRes { private String name; - private Long participantsNum; + private Integer participantsCount; private String location; private String schedule; - private Long attendanceRate; + private Integer myAttendanceRate; - private Long totalAttendanceRate; + private Integer totalAttendanceRate; - public static GetChallengesRes fromChallenge(Challenge challenge, Long userParticipationNum) { + public static GetChallengesRes fromChallenge(Challenge challenge, Integer myAttendanceRate) { return GetChallengesRes.builder() .challengeIdx(challenge.getChallengeIdx()) .name(challenge.getName()) - .participantsNum((long) challenge.getParticipants().size()) + .participantsCount(challenge.getParticipants().size()) .location(challenge.getProgram().getLocation()) .schedule(challenge.getProgram().getSchedule()) - .attendanceRate(Math.round((double)userParticipationNum/challenge.getTotalNum()) * 100) + .myAttendanceRate(myAttendanceRate) .totalAttendanceRate(challenge.getAttendanceRate()).build(); - } } diff --git a/src/main/java/ollie/wecare/challenge/entity/Challenge.java b/src/main/java/ollie/wecare/challenge/entity/Challenge.java index 3faed1c..c60177e 100644 --- a/src/main/java/ollie/wecare/challenge/entity/Challenge.java +++ b/src/main/java/ollie/wecare/challenge/entity/Challenge.java @@ -45,9 +45,7 @@ public void updateAttendanceCode(String attendanceCode) { @OneToMany(fetch = FetchType.LAZY) private List participants; - private Long totalNum; - - private Long attendanceRate; - + private Integer totalNum; + private Integer attendanceRate; } From cb9db9bede1c26be6c9a2858944ab38ee924560a Mon Sep 17 00:00:00 2001 From: joonghyun Date: Mon, 1 Jul 2024 19:16:35 +0900 Subject: [PATCH 4/5] =?UTF-8?q?#89=20fix:=20ChallengeAttendance=EC=9D=98?= =?UTF-8?q?=20attendanceDate=20=EC=BB=AC=EB=9F=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/entity/ChallengeAttendance.java | 7 ----- .../program/controller/ProgramController.java | 12 ++++---- .../wecare/program/dto/PostProgramReq.java | 2 +- .../program/service/ProgramService.java | 28 +++++++++---------- 4 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/main/java/ollie/wecare/challenge/entity/ChallengeAttendance.java b/src/main/java/ollie/wecare/challenge/entity/ChallengeAttendance.java index 7111c41..3d2f615 100644 --- a/src/main/java/ollie/wecare/challenge/entity/ChallengeAttendance.java +++ b/src/main/java/ollie/wecare/challenge/entity/ChallengeAttendance.java @@ -9,7 +9,6 @@ import ollie.wecare.user.entity.User; import org.hibernate.annotations.DynamicInsert; -import java.time.LocalDateTime; @Entity @Getter @Builder @@ -30,10 +29,4 @@ public class ChallengeAttendance extends BaseEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "challenge_idx") private Challenge challenge; - - //TODO : createdDate로 대체해서 사용하는 것 고려해보기 - private LocalDateTime attendanceDate; - - - } diff --git a/src/main/java/ollie/wecare/program/controller/ProgramController.java b/src/main/java/ollie/wecare/program/controller/ProgramController.java index 93f7e04..b6ee28c 100644 --- a/src/main/java/ollie/wecare/program/controller/ProgramController.java +++ b/src/main/java/ollie/wecare/program/controller/ProgramController.java @@ -39,10 +39,10 @@ public BaseResponse getProgram(@PathVariable(value = "progr return new BaseResponse<>(programService.getProgram(programIdx)); } - // 프로그램 등록 - @PostMapping - public BaseResponse saveProgram(@RequestBody PostProgramReq postProgramReq) throws BaseException { - programService.saveProgram(postProgramReq); - return new BaseResponse<>(SUCCESS); - } +// // 프로그램 등록 +// @PostMapping +// public BaseResponse saveProgram(@RequestBody PostProgramReq postProgramReq) throws BaseException { +// programService.saveProgram(postProgramReq); +// return new BaseResponse<>(SUCCESS); +// } } diff --git a/src/main/java/ollie/wecare/program/dto/PostProgramReq.java b/src/main/java/ollie/wecare/program/dto/PostProgramReq.java index 604a0c8..dec2945 100644 --- a/src/main/java/ollie/wecare/program/dto/PostProgramReq.java +++ b/src/main/java/ollie/wecare/program/dto/PostProgramReq.java @@ -19,7 +19,7 @@ public class PostProgramReq { private String description; - //private List tags; + //private List tags; public static Program toProgram(PostProgramReq postProgramReq) { return Program.builder().name(postProgramReq.getName()) diff --git a/src/main/java/ollie/wecare/program/service/ProgramService.java b/src/main/java/ollie/wecare/program/service/ProgramService.java index 04b9e43..9639d38 100644 --- a/src/main/java/ollie/wecare/program/service/ProgramService.java +++ b/src/main/java/ollie/wecare/program/service/ProgramService.java @@ -62,18 +62,18 @@ public GetProgramDetailRes getProgram(Long programIdx) { programRepository.findById(programIdx).orElseThrow(()-> new BaseException(INVALID_PROGRAM_IDX))); } - public void saveProgram(PostProgramReq postProgramReq) { - User user = userRepository.findById(authService.getUserIdx()).orElseThrow(()-> new BaseException(INVALID_USER_IDX)); - if(!user.getRole().equals(Role.Admin)) throw new BaseException(INVALID_ROLE); - - Program program = PostProgramReq.toProgram(postProgramReq); - programRepository.save(program); - - this.saveChallenge(PostProgramReq.toProgram(postProgramReq), user); - } - - public void saveChallenge(Program program, User user) { - challengeRepository.save(Challenge.builder().program(program).name(program.getName()).attendanceRate(0L) - .admin(user).host(program.getHost()).totalNum(0L).build()); - } +// public void saveProgram(PostProgramReq postProgramReq) { +// User user = userRepository.findById(authService.getUserIdx()).orElseThrow(()-> new BaseException(INVALID_USER_IDX)); +// if(!user.getRole().equals(Role.Admin)) throw new BaseException(INVALID_ROLE); +// +// Program program = PostProgramReq.toProgram(postProgramReq); +// programRepository.save(program); +// +// this.saveChallenge(PostProgramReq.toProgram(postProgramReq), user); +// } +// +// public void saveChallenge(Program program, User user) { +// challengeRepository.save(Challenge.builder().program(program).name(program.getName()).attendanceRate(0L) +// .admin(user).host(program.getHost()).totalNum(0L).build()); +// } } From a9baa2dd657e18b2d09f12105225586080dc626b Mon Sep 17 00:00:00 2001 From: Haeun-Y Date: Mon, 1 Jul 2024 22:23:41 +0900 Subject: [PATCH 5/5] =?UTF-8?q?#60=20fix:=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20API=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ChallengeController.java | 10 ++--- .../ChallengeAttendanceRepository.java | 2 +- .../challenge/service/ChallengeService.java | 45 ++++++++++--------- .../program/controller/ProgramController.java | 12 ++--- .../wecare/program/dto/PostProgramReq.java | 15 +++++-- .../program/dto/ProgramListResponse.java | 10 ++++- .../ollie/wecare/program/entity/Program.java | 2 +- .../java/ollie/wecare/program/entity/Tag.java | 5 ++- .../program/repository/TagRepository.java | 7 +++ .../program/service/ProgramService.java | 45 +++++++++++-------- .../wecare/user/service/UserService.java | 6 +++ 11 files changed, 101 insertions(+), 58 deletions(-) create mode 100644 src/main/java/ollie/wecare/program/repository/TagRepository.java diff --git a/src/main/java/ollie/wecare/challenge/controller/ChallengeController.java b/src/main/java/ollie/wecare/challenge/controller/ChallengeController.java index 8353dd1..e83b922 100644 --- a/src/main/java/ollie/wecare/challenge/controller/ChallengeController.java +++ b/src/main/java/ollie/wecare/challenge/controller/ChallengeController.java @@ -58,11 +58,11 @@ public BaseResponse participateChallenge(@RequestBody PostChallengeReq p return new BaseResponse<>(SUCCESS); } -// // 챌린지 검색 -// @GetMapping("/search") -// public BaseResponse> getChallenges(@RequestParam(value = "searchWord", defaultValue = "", required = false) String searchWord)throws BaseException { -// return new BaseResponse<>(challengeService.getChallenges(searchWord)); -// } + // 챌린지 검색 + @GetMapping("/search") + public BaseResponse> getChallenges(@RequestParam(value = "searchWord", defaultValue = "", required = false) String searchWord)throws BaseException { + return new BaseResponse<>(challengeService.getChallenges(searchWord)); + } // // 챌린지 광고 조회 // @GetMapping("/ads") diff --git a/src/main/java/ollie/wecare/challenge/repository/ChallengeAttendanceRepository.java b/src/main/java/ollie/wecare/challenge/repository/ChallengeAttendanceRepository.java index 60657a3..fd2964b 100644 --- a/src/main/java/ollie/wecare/challenge/repository/ChallengeAttendanceRepository.java +++ b/src/main/java/ollie/wecare/challenge/repository/ChallengeAttendanceRepository.java @@ -11,7 +11,7 @@ @Repository public interface ChallengeAttendanceRepository extends JpaRepository { List findByUser_UserIdx(Long userIdx); - List findByUser_UserIdxAndChallenge_ChallengeIdx(Long userIdx, Long challengeIdx); + List findByUserAndChallenge_ChallengeIdx(User user, Long challengeIdx); List findByUserAndChallengeOrderByCreatedDate(User user, Challenge challenge); Integer countByUserAndChallenge(User user, Challenge challenge); List findByUserAndStatusEquals(User user, String status); diff --git a/src/main/java/ollie/wecare/challenge/service/ChallengeService.java b/src/main/java/ollie/wecare/challenge/service/ChallengeService.java index fe1021b..671a89e 100644 --- a/src/main/java/ollie/wecare/challenge/service/ChallengeService.java +++ b/src/main/java/ollie/wecare/challenge/service/ChallengeService.java @@ -13,7 +13,7 @@ import ollie.wecare.program.dto.DateDto; import ollie.wecare.user.entity.User; import ollie.wecare.user.repository.UserRepository; -import ollie.wecare.user.service.AuthService; +import ollie.wecare.user.service.UserService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -34,7 +34,7 @@ public class ChallengeService { private final UserRepository userRepository; private final ChallengeRepository challengeRepository; - private final AuthService authService; + private final UserService userService; // 참여중인 챌린지 목록 조회 public BaseResponse> getMyChallenges(Long userIdx) throws BaseException { @@ -53,7 +53,8 @@ public BaseResponse> getMyChallenges(Long userIdx) throws * 챌린지 인증코드 발급 * */ public GetAttendanceCodeReq getAttendanceCode(Long challengeIdx) { - User user = userRepository.findById(authService.getUserIdx()).orElseThrow(()-> new BaseException(INVALID_USER_IDX)); + + User user = userService.getUserWithValidation(); if(!user.getRole().equals(Role.Admin)) throw new BaseException(INVALID_ROLE); Challenge challenge = challengeRepository.findById(challengeIdx).orElseThrow(() -> new BaseException(INVALID_CHALLENGE_IDX)); @@ -75,7 +76,7 @@ public void attendChallenge(AttendChallengeReq attendChallengeReq) throws BaseEx throw new BaseException(INVALID_ATTENDANCE_CODE); else { ChallengeAttendance challengeAttendance = ChallengeAttendance.builder() - .user(userRepository.findById(authService.getUserIdx()).orElseThrow(()->new BaseException(INVALID_ACCESS_TOKEN))) + .user(userService.getUserWithValidation()) .challenge(challengeRepository.findById(attendChallengeReq.getChallengeIdx()).orElseThrow(()-> new BaseException(INVALID_CHALLENGE_IDX))) .build(); challengeAttendanceRepository.save(challengeAttendance); @@ -88,28 +89,30 @@ public void attendChallenge(AttendChallengeReq attendChallengeReq) throws BaseEx @Transactional public void participateChallenge(PostChallengeReq postChallengeReq) throws BaseException { ChallengeAttendance challengeAttendance = ChallengeAttendance.builder() - .user(userRepository.findById(authService.getUserIdx()).orElseThrow(()->new BaseException(INVALID_ACCESS_TOKEN))) + .user(userService.getUserWithValidation()) .challenge(challengeRepository.findById(postChallengeReq.getChallengeIdx()).orElseThrow(()-> new BaseException(INVALID_CHALLENGE_IDX))) .build(); challengeAttendanceRepository.save(challengeAttendance); } -// /* -// * 챌린지 검색 -// * */ -// public List getChallenges(String searchWord) { -// Long userIdx = authService.getUserIdx(); -// if(userIdx == null) throw new BaseException(INVALID_ACCESS_TOKEN); -// List challenges = challengeRepository.findByNameContaining(searchWord); -// List challengeResult = new ArrayList<>(); -// -// for(Challenge challenge : challenges) { -// List challengeAttendances = challengeAttendanceRepository.findByUser_UserIdxAndChallenge_ChallengeIdx(userIdx, challenge.getChallengeIdx()); -// if(challengeAttendances == null || challengeAttendances.isEmpty()) -// challengeResult.add(challenge); -// } -// return challengeResult.stream().map(challenge -> GetChallengesRes.fromChallenge(challenge, 0L).toList(); -// } + /* + * 챌린지 검색 + * */ + public List getChallenges(String searchWord) { + User user = userService.getUserWithValidation(); + List challenges = challengeRepository.findByNameContaining(searchWord); + List challengeResult = new ArrayList<>(); + + for(Challenge challenge : challenges) { + List challengeAttendances = challengeAttendanceRepository.findByUserAndChallenge_ChallengeIdx(user, challenge.getChallengeIdx()); + if(challengeAttendances == null || challengeAttendances.isEmpty()) + challengeResult.add(challenge); + } + return challengeResult.stream() + .map(challenge -> GetChallengesRes.fromChallenge(challenge, 0)) + .toList(); + + } // 챌린지 상세 조회 public BaseResponse getChallengeDetail(Long userIdx, Long challengeIdx) { diff --git a/src/main/java/ollie/wecare/program/controller/ProgramController.java b/src/main/java/ollie/wecare/program/controller/ProgramController.java index b6ee28c..93f7e04 100644 --- a/src/main/java/ollie/wecare/program/controller/ProgramController.java +++ b/src/main/java/ollie/wecare/program/controller/ProgramController.java @@ -39,10 +39,10 @@ public BaseResponse getProgram(@PathVariable(value = "progr return new BaseResponse<>(programService.getProgram(programIdx)); } -// // 프로그램 등록 -// @PostMapping -// public BaseResponse saveProgram(@RequestBody PostProgramReq postProgramReq) throws BaseException { -// programService.saveProgram(postProgramReq); -// return new BaseResponse<>(SUCCESS); -// } + // 프로그램 등록 + @PostMapping + public BaseResponse saveProgram(@RequestBody PostProgramReq postProgramReq) throws BaseException { + programService.saveProgram(postProgramReq); + return new BaseResponse<>(SUCCESS); + } } diff --git a/src/main/java/ollie/wecare/program/dto/PostProgramReq.java b/src/main/java/ollie/wecare/program/dto/PostProgramReq.java index dec2945..4cc01cc 100644 --- a/src/main/java/ollie/wecare/program/dto/PostProgramReq.java +++ b/src/main/java/ollie/wecare/program/dto/PostProgramReq.java @@ -9,7 +9,9 @@ public class PostProgramReq { private String name; - private LocalDateTime dueDate; + private DateDto dueDate; + + private DateDto openDate; private String location; @@ -19,19 +21,24 @@ public class PostProgramReq { private String description; - //private List tags; + private String category; public static Program toProgram(PostProgramReq postProgramReq) { return Program.builder().name(postProgramReq.getName()) - .dueDate(postProgramReq.getDueDate()) + .dueDate(convertToLocalDateTime(postProgramReq.getDueDate())) + .openDate(convertToLocalDateTime(postProgramReq.getOpenDate())) .location((postProgramReq.getLocation())) .host(postProgramReq.getHost()) .schedule(postProgramReq.getSchedule()) .description(postProgramReq.getDescription()) - /*.tags(postProgramReq.getTags())*/ .build(); } + private static LocalDateTime convertToLocalDateTime(DateDto dateDto) { + if(dateDto == null) return null; + return LocalDateTime.of(dateDto.year(), dateDto.month(), dateDto.day(), 0, 0, 0); + } + } diff --git a/src/main/java/ollie/wecare/program/dto/ProgramListResponse.java b/src/main/java/ollie/wecare/program/dto/ProgramListResponse.java index 93693eb..1e9b614 100644 --- a/src/main/java/ollie/wecare/program/dto/ProgramListResponse.java +++ b/src/main/java/ollie/wecare/program/dto/ProgramListResponse.java @@ -26,7 +26,7 @@ public static ProgramListResponse fromProgram(Program program) { program.getName(), convertToDateDto(program.getOpenDate()), convertToDateDto(program.getDueDate()), - program.getLocation(), + getLocationTag(program) != null ? getCategoryTag(program).getTagName() : null, getCategoryTag(program) != null ? getCategoryTag(program).getTagName() : null); } @@ -37,4 +37,12 @@ private static TagEnum getCategoryTag(Program program) { .findFirst() .orElse(null); } + + private static TagEnum getLocationTag(Program program) { + return program.getTags().stream() + .map(Tag::getName) + .filter(tagEnum -> tagEnum.getParent() == TagEnum.LOCATION) + .findFirst() + .orElse(null); + } } diff --git a/src/main/java/ollie/wecare/program/entity/Program.java b/src/main/java/ollie/wecare/program/entity/Program.java index 61b4c93..e35f065 100644 --- a/src/main/java/ollie/wecare/program/entity/Program.java +++ b/src/main/java/ollie/wecare/program/entity/Program.java @@ -35,7 +35,7 @@ public class Program extends BaseEntity { private String description; - @OneToMany(fetch = FetchType.LAZY) + @OneToMany(mappedBy = "program") private List tags; public void setTags(List tags) { diff --git a/src/main/java/ollie/wecare/program/entity/Tag.java b/src/main/java/ollie/wecare/program/entity/Tag.java index f55a76f..e12872e 100644 --- a/src/main/java/ollie/wecare/program/entity/Tag.java +++ b/src/main/java/ollie/wecare/program/entity/Tag.java @@ -9,6 +9,8 @@ @Entity @Getter @DynamicInsert +@Builder +@AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Tag extends BaseEntity { @@ -20,10 +22,11 @@ public class Tag extends BaseEntity { @Enumerated(EnumType.STRING) private TagEnum name; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne @JoinColumn(name = "program_idx") private Program program; + public void setProgram(Program program) { this.program = program; if (program != null) { program.getTags().add(this); } diff --git a/src/main/java/ollie/wecare/program/repository/TagRepository.java b/src/main/java/ollie/wecare/program/repository/TagRepository.java new file mode 100644 index 0000000..4fcca95 --- /dev/null +++ b/src/main/java/ollie/wecare/program/repository/TagRepository.java @@ -0,0 +1,7 @@ +package ollie.wecare.program.repository; + +import ollie.wecare.program.entity.Tag; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TagRepository extends JpaRepository { +} diff --git a/src/main/java/ollie/wecare/program/service/ProgramService.java b/src/main/java/ollie/wecare/program/service/ProgramService.java index 9639d38..1dd9b19 100644 --- a/src/main/java/ollie/wecare/program/service/ProgramService.java +++ b/src/main/java/ollie/wecare/program/service/ProgramService.java @@ -6,16 +6,19 @@ import ollie.wecare.common.base.BaseException; import ollie.wecare.common.base.BaseResponse; import ollie.wecare.common.enums.Role; +import ollie.wecare.common.enums.TagEnum; import ollie.wecare.program.dto.GetProgramDetailRes; import ollie.wecare.program.dto.GetProgramRes; import ollie.wecare.program.dto.PostProgramReq; import ollie.wecare.program.dto.ProgramListResponse; import ollie.wecare.program.entity.Program; +import ollie.wecare.program.entity.Tag; import ollie.wecare.program.repository.ProgramRepository; +import ollie.wecare.program.repository.TagRepository; import ollie.wecare.user.entity.User; -import ollie.wecare.user.repository.UserRepository; -import ollie.wecare.user.service.AuthService; +import ollie.wecare.user.service.UserService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; import java.time.LocalDateTime; @@ -27,13 +30,14 @@ @Service @RequiredArgsConstructor +@Transactional public class ProgramService { - private final AuthService authService; + private final UserService userService; private final ProgramRepository programRepository; private final ChallengeRepository challengeRepository; - private final UserRepository userRepository; + private final TagRepository tagRepository; // 프로그램 월별 조회 public List getPrograms(Long year, Long month) { @@ -62,18 +66,23 @@ public GetProgramDetailRes getProgram(Long programIdx) { programRepository.findById(programIdx).orElseThrow(()-> new BaseException(INVALID_PROGRAM_IDX))); } -// public void saveProgram(PostProgramReq postProgramReq) { -// User user = userRepository.findById(authService.getUserIdx()).orElseThrow(()-> new BaseException(INVALID_USER_IDX)); -// if(!user.getRole().equals(Role.Admin)) throw new BaseException(INVALID_ROLE); -// -// Program program = PostProgramReq.toProgram(postProgramReq); -// programRepository.save(program); -// -// this.saveChallenge(PostProgramReq.toProgram(postProgramReq), user); -// } -// -// public void saveChallenge(Program program, User user) { -// challengeRepository.save(Challenge.builder().program(program).name(program.getName()).attendanceRate(0L) -// .admin(user).host(program.getHost()).totalNum(0L).build()); -// } + public void saveProgram(PostProgramReq postProgramReq) { + User user = userService.getUserWithValidation(); + if(!user.getRole().equals(Role.Admin)) throw new BaseException(INVALID_ROLE); + + Program program = PostProgramReq.toProgram(postProgramReq); + programRepository.save(program); + this.saveTag(postProgramReq, program); + //this.saveChallenge(PostProgramReq.toProgram(postProgramReq), user); + } + + public void saveTag(PostProgramReq postProgramReq, Program program) { + tagRepository.save(Tag.builder().name(TagEnum.getEnumByName(postProgramReq.getCategory())).program(program).build()); + tagRepository.save(Tag.builder().name(TagEnum.getEnumByName(postProgramReq.getLocation())).program(program).build()); + } + + public void saveChallenge(Program program, User user) { + challengeRepository.save(Challenge.builder().program(program).name(program.getName()).attendanceRate(0) + .admin(user).host(program.getHost()).totalNum(0).build()); + } } diff --git a/src/main/java/ollie/wecare/user/service/UserService.java b/src/main/java/ollie/wecare/user/service/UserService.java index 7b72f07..934271a 100644 --- a/src/main/java/ollie/wecare/user/service/UserService.java +++ b/src/main/java/ollie/wecare/user/service/UserService.java @@ -202,4 +202,10 @@ private Long getUserIdxWithValidation() throws BaseException { if (userIdx == null) throw new BaseException(NULL_ACCESS_TOKEN); return userIdx; } + + public User getUserWithValidation() throws BaseException { + User user = this.getUserByUserIdx(this.getUserIdxWithValidation()); + if(user == null) throw new BaseException(INVALID_USER_IDX); + return user; + } }