diff --git a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/project/service/Impl/ProjectServiceImpl.java b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/project/service/Impl/ProjectServiceImpl.java index 2b834a1..bada540 100644 --- a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/project/service/Impl/ProjectServiceImpl.java +++ b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/project/service/Impl/ProjectServiceImpl.java @@ -177,12 +177,12 @@ public ProjectJoinResponseDto joinProject(Long memberId, ProjectJoinRequestDto p if ( projectJoinRequestDto.getProjectId() == null ) { throw new BadRequestException("공백일 수 없습니다. (reviewTemplateId)"); } - if (userProjectRepository.existsByMemberIdAndProjectId(memberId, projectJoinRequestDto.getProjectId())){ - throw new BadRequestException(("이미 프로젝트에 참여한 팀원입니다.")); - } if (userProjectRepository.existsByProjectIdAndNickname(projectJoinRequestDto.getProjectId(),projectJoinRequestDto.getMemberProjectNickname())){ throw new BadRequestException(("이미 프로젝트에 있는 닉네임입니다.")); } + if (userProjectRepository.existsByMemberIdAndProjectId(memberId, projectJoinRequestDto.getProjectId())){ + throw new BadRequestException(("이미 프로젝트에 참여한 팀원입니다.")); + } Member member = findMemberById(memberId); Project project = findProjectById(projectJoinRequestDto.getProjectId()); diff --git a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/controller/ReviewController.java b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/controller/ReviewController.java index 18a3f97..b3b80f3 100644 --- a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/controller/ReviewController.java +++ b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/controller/ReviewController.java @@ -1,13 +1,9 @@ package com.puzzling.puzzlingServer.api.review.controller; import com.puzzling.puzzlingServer.api.review.dto.request.Review5FRequestDto; -import com.puzzling.puzzlingServer.api.review.dto.response.MyReviewProjectResponseDto; -import com.puzzling.puzzlingServer.api.review.dto.response.ReviewActionPlanResponseDto; +import com.puzzling.puzzlingServer.api.review.dto.response.*; import com.puzzling.puzzlingServer.api.review.dto.request.ReviewAARRequestDto; -import com.puzzling.puzzlingServer.api.review.dto.response.ReviewPreviousTemplateResponseDto; -import com.puzzling.puzzlingServer.api.review.dto.response.ReviewTeamStatusResponseDto; -import com.puzzling.puzzlingServer.api.review.dto.response.ReviewTemplateGetResponseDto; import com.puzzling.puzzlingServer.api.review.dto.request.ReviewTILRequestDto; import com.puzzling.puzzlingServer.api.review.service.ReviewService; import com.puzzling.puzzlingServer.common.response.ApiResponse; @@ -65,6 +61,12 @@ public ApiResponse getTeamReviewStatus(@PathVariabl return ApiResponse.success(SuccessStatus.GET_REVIEW_TEAM_STATUS_SUCCESS, reviewService.getTeamReviewStatus(projectId, startDate, endDate)); } + @GetMapping("member/{memberId}/project/{projectId}/team/review") + public ApiResponse getMyReviewDetail(@PathVariable Long memberId, @PathVariable Long projectId, + @RequestParam String startDate, @RequestParam String endDate) { + return ApiResponse.success(SuccessStatus.GET_MY_REVIEWS_DETAIL_SUCCESS, reviewService.getMyReviewDetail(memberId, projectId, startDate, endDate)); + } + @GetMapping("member/{memberId}/project/{projectId}/review") public ApiResponse getMyReviewProjects(@PathVariable Long memberId, @PathVariable Long projectId) { return ApiResponse.success(SuccessStatus.GET_PROJECT_MY_REVIEWS_SUCCESS, reviewService.getMyReviewProjects(memberId, projectId)); diff --git a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/dto/response/ReviewContentObjectDto.java b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/dto/response/ReviewContentObjectDto.java new file mode 100644 index 0000000..dfca252 --- /dev/null +++ b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/dto/response/ReviewContentObjectDto.java @@ -0,0 +1,19 @@ +package com.puzzling.puzzlingServer.api.review.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import static lombok.AccessLevel.PRIVATE; + +@Getter +@NoArgsConstructor(access = PRIVATE) +@AllArgsConstructor +public class ReviewContentObjectDto { + private String title; + private String content; + + public static ReviewContentObjectDto of (String title, String content) { + return new ReviewContentObjectDto(title, content); + } +} diff --git a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/dto/response/ReviewDetailResponseDto.java b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/dto/response/ReviewDetailResponseDto.java new file mode 100644 index 0000000..159fe58 --- /dev/null +++ b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/dto/response/ReviewDetailResponseDto.java @@ -0,0 +1,26 @@ +package com.puzzling.puzzlingServer.api.review.dto.response; + +import com.puzzling.puzzlingServer.api.review.domain.Review; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +import static lombok.AccessLevel.PRIVATE; + +@Getter +@NoArgsConstructor(access = PRIVATE) +@AllArgsConstructor +public class ReviewDetailResponseDto { + private Long reviewId; + private String reviewDay; + private String reviewDate; + private Long reviewTemplateId; + private List contents; + + public static ReviewDetailResponseDto of (Long reviewId, String reviewDay, String reviewDate, + Long reviewTemplateId, List contents) { + return new ReviewDetailResponseDto(reviewId, reviewDay, reviewDate, reviewTemplateId, contents); + } +} diff --git a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/service/Impl/ReviewServiceImpl.java b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/service/Impl/ReviewServiceImpl.java index 8c90e4c..5bbee21 100644 --- a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/service/Impl/ReviewServiceImpl.java +++ b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/service/Impl/ReviewServiceImpl.java @@ -27,8 +27,13 @@ import com.puzzling.puzzlingServer.api.template.domain.ReviewAAR; import com.puzzling.puzzlingServer.api.template.domain.ReviewTIL; import com.puzzling.puzzlingServer.api.template.domain.ReviewTemplate; +import com.puzzling.puzzlingServer.api.template.strategy.AARReviewTemplateStrategy; +import com.puzzling.puzzlingServer.api.template.strategy.FiveFReviewTemplateStrategy; +import com.puzzling.puzzlingServer.api.template.strategy.ReviewTemplateStrategy; +import com.puzzling.puzzlingServer.api.template.strategy.TILReviewTemplateStrategy; import com.puzzling.puzzlingServer.common.exception.BadRequestException; import com.puzzling.puzzlingServer.common.exception.NotFoundException; +import com.puzzling.puzzlingServer.common.util.DateUtil; import lombok.RequiredArgsConstructor; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Service; @@ -42,8 +47,7 @@ import java.util.stream.Collectors; import static com.puzzling.puzzlingServer.common.response.ErrorStatus.NOT_FOUND_PROJECT; -import static com.puzzling.puzzlingServer.common.util.DateUtil.checkTodayIsReviewDay; -import static com.puzzling.puzzlingServer.common.util.DateUtil.getDayOfWeek; +import static com.puzzling.puzzlingServer.common.util.DateUtil.*; @Service @@ -84,7 +88,7 @@ public void createReviewTIL(Long memberId, Long projectId, ReviewTILRequestDto r Review review = Review.builder() .userProject(userProject) .reviewTemplate(reviewTemplate) - .reviewDate("123") + .reviewDate(convertLocalDatetoString(LocalDate.now())) .memberId(memberId) .projectId(projectId) .build(); @@ -115,7 +119,7 @@ public void createReview5F(Long memberId, Long projectId, Review5FRequestDto rev Review review = Review.builder() .userProject(userProject) .reviewTemplate(reviewTemplate) - .reviewDate("123") + .reviewDate(convertLocalDatetoString(LocalDate.now())) .memberId(memberId) .projectId(projectId) .build(); @@ -148,7 +152,7 @@ public void createReviewAAR(Long memberId, Long projectId, ReviewAARRequestDto r Review review = Review.builder() .userProject(userProject) .reviewTemplate(reviewTemplate) - .reviewDate("123") + .reviewDate(convertLocalDatetoString(LocalDate.now())) .memberId(memberId) .projectId(projectId) .build(); @@ -177,10 +181,6 @@ public ReviewPreviousTemplateResponseDto getPreviousReviewTemplate(Long memberId public List getReviewActionPlans(Long memberId, Long projectId) { List findReviews = reviewRepository.findAllByMemberIdAndProjectIdOrderByReviewDateDesc(memberId, projectId); - if (findReviews.isEmpty()) { - throw new BadRequestException("유저가 해당 프로젝트 팀원이 아닙니다."); - } - return findReviews.stream() .map(findReview -> { String reviewTemplateName = findReview.getReviewTemplate().getName(); @@ -233,17 +233,58 @@ public List getTeamReviewStatus(Long projectId, Str return result; } - private Project findProjectById (Long projectId) { - return projectRepository.findById(projectId).orElseThrow(() -> - new NotFoundException(NOT_FOUND_PROJECT.getMessage())); + @Override + @Transactional + public List getMyReviewDetail(Long memberId, Long projectId, String startDate, String endDate) { + List result = new ArrayList<>(); + String reviewCycle = findProjectById(projectId).getReviewCycle(); + + List reviewDates = generateReviewDates(startDate, endDate, reviewCycle); + + for (String reviewDate : reviewDates) { + Optional findReview = reviewRepository.findByMemberIdAndProjectIdAndReviewDate(memberId, projectId, reviewDate); + List reviewContent = new ArrayList<>(); + + if (findReview.isPresent()) { + Review reviewValue = findReview.get(); + String reviewTemplateName = reviewValue.getReviewTemplate().getName(); + + switch (reviewTemplateName) { + case "TIL": + ReviewTIL reviewTIL = findReviewByReviewId(reviewValue.getId(), reviewTILRepository, "TIL"); + TILReviewTemplateStrategy TILStrategy = new TILReviewTemplateStrategy(); + TILStrategy.getReviewContents(reviewTIL, reviewContent); + break; + case "5F": + Review5F review5F = findReviewByReviewId(reviewValue.getId(), review5FRepository, "5F"); + FiveFReviewTemplateStrategy FiveFStrategy = new FiveFReviewTemplateStrategy(); + FiveFStrategy.getReviewContents(review5F, reviewContent); + break; + case "AAR": + ReviewAAR reviewAAR = findReviewByReviewId(reviewValue.getId(), reviewAARRepository, "AAR"); + AARReviewTemplateStrategy AARStrategy = new AARReviewTemplateStrategy(); + AARStrategy.getReviewContents(reviewAAR, reviewContent); + break; + default: + throw new BadRequestException("올바르지 않은 리뷰 템플릿 이름: " + reviewTemplateName); + } + + result.add(ReviewDetailResponseDto.of(reviewValue.getId(), getDayOfWeek(reviewDate), reviewDate, + reviewValue.getReviewTemplate().getId(), reviewContent)); + } else { + result.add(ReviewDetailResponseDto.of(null, getDayOfWeek(reviewDate), reviewDate, + null, null)); + } + } + return result; } - + + + @Override + @Transactional public List getMyReviewProjects(Long memberId, Long projectId) { List findReviews = reviewRepository.findAllByMemberIdAndProjectIdOrderByReviewDateDesc(memberId, projectId); - if (findReviews.isEmpty()) { - throw new BadRequestException("유저가 해당 프로젝트 팀원이 아닙니다."); - } return findReviews.stream() .map(findReview -> { String reviewTemplateName = findReview.getReviewTemplate().getName(); @@ -265,6 +306,11 @@ public List getMyReviewProjects(Long memberId, Long .collect(Collectors.toList()); } + private Project findProjectById (Long projectId) { + return projectRepository.findById(projectId).orElseThrow(() -> + new NotFoundException(NOT_FOUND_PROJECT.getMessage())); + } + private ReviewTemplate findReviewTemplateById (Long reviewTemplateId) { return reviewTemplateRepository.findById(reviewTemplateId) .orElseThrow(() -> new NotFoundException("해당하는 회고 팀플릿이 없습니다.")); diff --git a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/service/ReviewService.java b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/service/ReviewService.java index 116707b..85c73b2 100644 --- a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/service/ReviewService.java +++ b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/review/service/ReviewService.java @@ -1,13 +1,9 @@ package com.puzzling.puzzlingServer.api.review.service; import com.puzzling.puzzlingServer.api.review.dto.request.Review5FRequestDto; -import com.puzzling.puzzlingServer.api.review.dto.response.MyReviewProjectResponseDto; -import com.puzzling.puzzlingServer.api.review.dto.response.ReviewActionPlanResponseDto; +import com.puzzling.puzzlingServer.api.review.dto.response.*; import com.puzzling.puzzlingServer.api.review.dto.request.ReviewAARRequestDto; -import com.puzzling.puzzlingServer.api.review.dto.response.ReviewPreviousTemplateResponseDto; -import com.puzzling.puzzlingServer.api.review.dto.response.ReviewTeamStatusResponseDto; -import com.puzzling.puzzlingServer.api.review.dto.response.ReviewTemplateGetResponseDto; import com.puzzling.puzzlingServer.api.review.dto.request.ReviewTILRequestDto; @@ -30,4 +26,6 @@ public interface ReviewService { List getMyReviewProjects(Long memberId, Long projectId); + List getMyReviewDetail(Long memberId, Long projectId, String startDate, String endDate); + } diff --git a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/template/strategy/AARReviewTemplateStrategy.java b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/template/strategy/AARReviewTemplateStrategy.java new file mode 100644 index 0000000..d67a6fe --- /dev/null +++ b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/template/strategy/AARReviewTemplateStrategy.java @@ -0,0 +1,18 @@ +package com.puzzling.puzzlingServer.api.template.strategy; + +import com.puzzling.puzzlingServer.api.review.dto.response.ReviewContentObjectDto; +import com.puzzling.puzzlingServer.api.template.domain.ReviewAAR; + +import java.util.List; + +public class AARReviewTemplateStrategy implements ReviewTemplateStrategy { + @Override + public List getReviewContents(ReviewAAR review, List reviewContent) { + reviewContent.add(new ReviewContentObjectDto("초기의 목표", review.getInitialGoal())); + reviewContent.add(new ReviewContentObjectDto("결과", review.getResult())); + reviewContent.add(new ReviewContentObjectDto("차이가 발생한 이유", review.getDifference())); + reviewContent.add(new ReviewContentObjectDto("지속하고 싶은 점", review.getPersistence())); + reviewContent.add(new ReviewContentObjectDto("앞으로의 목적", review.getActionPlan())); + return reviewContent; + } +} diff --git a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/template/strategy/FiveFReviewTemplateStrategy.java b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/template/strategy/FiveFReviewTemplateStrategy.java new file mode 100644 index 0000000..6e7e617 --- /dev/null +++ b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/template/strategy/FiveFReviewTemplateStrategy.java @@ -0,0 +1,18 @@ +package com.puzzling.puzzlingServer.api.template.strategy; + +import com.puzzling.puzzlingServer.api.review.dto.response.ReviewContentObjectDto; +import com.puzzling.puzzlingServer.api.template.domain.Review5F; + +import java.util.List; + +public class FiveFReviewTemplateStrategy implements ReviewTemplateStrategy { + @Override + public List getReviewContents(Review5F review, List reviewContent) { + reviewContent.add(new ReviewContentObjectDto("Fact", review.getFact())); + reviewContent.add(new ReviewContentObjectDto("Feeling", review.getFeeling())); + reviewContent.add(new ReviewContentObjectDto("Finding", review.getFinding())); + reviewContent.add(new ReviewContentObjectDto("Future action", review.getActionPlan())); + reviewContent.add(new ReviewContentObjectDto("Feedback", review.getFeedback())); + return reviewContent; + } +} diff --git a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/template/strategy/ReviewTemplateStrategy.java b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/template/strategy/ReviewTemplateStrategy.java new file mode 100644 index 0000000..1b394aa --- /dev/null +++ b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/template/strategy/ReviewTemplateStrategy.java @@ -0,0 +1,10 @@ +package com.puzzling.puzzlingServer.api.template.strategy; + +import com.puzzling.puzzlingServer.api.review.domain.Review; +import com.puzzling.puzzlingServer.api.review.dto.response.ReviewContentObjectDto; + +import java.util.List; + +public interface ReviewTemplateStrategy { + List getReviewContents(T review, List reviewContent); +} diff --git a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/template/strategy/TILReviewTemplateStrategy.java b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/template/strategy/TILReviewTemplateStrategy.java new file mode 100644 index 0000000..4ac9669 --- /dev/null +++ b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/api/template/strategy/TILReviewTemplateStrategy.java @@ -0,0 +1,17 @@ +package com.puzzling.puzzlingServer.api.template.strategy; + +import com.puzzling.puzzlingServer.api.review.dto.response.ReviewContentObjectDto; +import com.puzzling.puzzlingServer.api.template.domain.ReviewTIL; + +import java.util.List; + +public class TILReviewTemplateStrategy implements ReviewTemplateStrategy { + @Override + public List getReviewContents(ReviewTIL review, List reviewContent) { + reviewContent.add(new ReviewContentObjectDto("잘한 점", review.getLiked())); + reviewContent.add(new ReviewContentObjectDto("아쉬운 점", review.getLacked())); + reviewContent.add(new ReviewContentObjectDto("배운 점", review.getActionPlan())); + return reviewContent; + } + +} diff --git a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/common/response/SuccessStatus.java b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/common/response/SuccessStatus.java index d0ab8d0..5cfdd23 100644 --- a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/common/response/SuccessStatus.java +++ b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/common/response/SuccessStatus.java @@ -36,7 +36,8 @@ public enum SuccessStatus { GET_REVIEW_PREVIOUS_TEMPLATE_SUCCESS(HttpStatus.OK, "이전 회고 템플릿 조회 성공"), GET_REVIEW_ACTION_PLAN_SUCCESS(HttpStatus.OK, "ACTIONPLAN 내용 조회 성공"), GET_REVIEW_TEAM_STATUS_SUCCESS(HttpStatus.OK, "팀원 회고 상황 조회 성공"), - GET_PROJECT_MY_REVIEWS_SUCCESS(HttpStatus.OK, "해당 프로젝트 내 회고 리스트 조회 성공") + GET_PROJECT_MY_REVIEWS_SUCCESS(HttpStatus.OK, "해당 프로젝트 내 회고 리스트 조회 성공"), + GET_MY_REVIEWS_DETAIL_SUCCESS(HttpStatus.OK, "회고 상세 조회 성공") ; private final HttpStatus httpStatus; diff --git a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/common/util/DateUtil.java b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/common/util/DateUtil.java index 19ff2fb..4c2c39b 100644 --- a/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/common/util/DateUtil.java +++ b/puzzlingServer/src/main/java/com/puzzling/puzzlingServer/common/util/DateUtil.java @@ -29,4 +29,9 @@ public static String getDayOfWeek(String dateStr) { return dayOfWeekKorean; } + + public static String convertLocalDatetoString(LocalDate localDate) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + return localDate.format(formatter); + } }