From da52cf2951b16884ecf08085bbab2d42452a3bf9 Mon Sep 17 00:00:00 2001 From: daeun084 <030804jk@naver.com> Date: Sun, 17 Nov 2024 19:57:05 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EA=B0=90=EC=A0=95=20=EB=B6=84=EC=84=9D?= =?UTF-8?q?=20=EB=A0=88=ED=8F=AC=ED=8A=B8=20=EC=83=81=EC=84=B8=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/controller/ReportController.java | 5 ++ .../dev/model/converter/ReportConverter.java | 16 ++++- .../model/dto/response/ReportResponse.java | 43 ++++++++++++ .../dev/repository/EmotionRepository.java | 12 ++++ .../LearnMate/dev/service/ReportService.java | 68 ++++++++++++++++--- 5 files changed, 131 insertions(+), 13 deletions(-) diff --git a/src/main/java/LearnMate/dev/controller/ReportController.java b/src/main/java/LearnMate/dev/controller/ReportController.java index 1221d07..7b40936 100644 --- a/src/main/java/LearnMate/dev/controller/ReportController.java +++ b/src/main/java/LearnMate/dev/controller/ReportController.java @@ -17,4 +17,9 @@ public class ReportController { public ApiResponse getEmotionReport() { return ApiResponse.onSuccessData("감정 분석 레포트 조회 성공", reportService.getEmotionReport()); } + + @GetMapping("/detail") + public ApiResponse getEmotionDetailReport() { + return ApiResponse.onSuccessData("감정 분석 상세 레포트 조회 성공", reportService.getEmotionDetailReport()); + } } diff --git a/src/main/java/LearnMate/dev/model/converter/ReportConverter.java b/src/main/java/LearnMate/dev/model/converter/ReportConverter.java index 765b404..f68ad7e 100644 --- a/src/main/java/LearnMate/dev/model/converter/ReportConverter.java +++ b/src/main/java/LearnMate/dev/model/converter/ReportConverter.java @@ -13,15 +13,27 @@ public static ReportResponse.ReportEmotionDto toReportEmotionDto(ReportResponse. .count(emotionDto.getCount()) .build(); } - public static ReportResponse.ReportDto toReportDto(List emotionDtoList) { - List reportEmotionDtoList = emotionDtoList.stream() + public static List toReportEmotionDtoList(List emotionDtoList) { + return emotionDtoList.stream() .map(ReportConverter::toReportEmotionDto) .toList(); + } + public static ReportResponse.ReportDto toReportDto(List reportEmotionDtoList) { return ReportResponse.ReportDto.builder() .emotionReport(reportEmotionDtoList) .build(); } + public static ReportResponse.ReportDetailDto toReportDetailDto(List reportEmotionDtoList, + List emotionOnDayDtoList, + List emotionRankDtoList) { + return ReportResponse.ReportDetailDto.builder() + .emotionReport(reportEmotionDtoList) + .emotionOnDayList(emotionOnDayDtoList) + .emotionRankDtoList(emotionRankDtoList) + .build(); + } + } diff --git a/src/main/java/LearnMate/dev/model/dto/response/ReportResponse.java b/src/main/java/LearnMate/dev/model/dto/response/ReportResponse.java index 9a34f2c..c0131df 100644 --- a/src/main/java/LearnMate/dev/model/dto/response/ReportResponse.java +++ b/src/main/java/LearnMate/dev/model/dto/response/ReportResponse.java @@ -6,6 +6,8 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.List; public class ReportResponse { @@ -39,6 +41,35 @@ public static class ReportEmotionDto { } + @Getter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class EmotionOnDayDto { + + private String emotion; + private String emoticon; + private String day; + + public EmotionOnDayDto(EmotionSpectrum emotion, LocalDateTime date) { + this.emotion = emotion.getValue(); + this.emoticon = emotion.getEmoticon(); + this.day = date.format(DateTimeFormatter.ofPattern("MM/dd")); + } + } + + @Getter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class EmotionRankDto { + + private String emotion; + private String emoticon; + private Long rank; + + } + @Getter @Builder @AllArgsConstructor @@ -49,6 +80,18 @@ public static class ReportDto { } + @Getter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class ReportDetailDto { + + private List emotionReport; + private List emotionOnDayList; + private List emotionRankDtoList; + + } + } diff --git a/src/main/java/LearnMate/dev/repository/EmotionRepository.java b/src/main/java/LearnMate/dev/repository/EmotionRepository.java index a592115..1a60114 100644 --- a/src/main/java/LearnMate/dev/repository/EmotionRepository.java +++ b/src/main/java/LearnMate/dev/repository/EmotionRepository.java @@ -23,4 +23,16 @@ List findEmotionDtoByUser( @Param(value = "startDate") LocalDate startDate, @Param(value = "endDate") LocalDate endDate, @Param(value = "user") User user); + + @Query("SELECT new LearnMate.dev.model.dto.response.ReportResponse$EmotionOnDayDto(e.emotion, e.createdAt) " + + "FROM Emotion e " + + "JOIN e.diary d " + + "WHERE d.user = :user " + + "AND DATE(e.createdAt) >= :startDate " + + "AND DATE(e.createdAt) <= :endDate " + + "ORDER BY e.createdAt asc ") + List findEmotionOnDayDtoByUser( + @Param(value = "startDate") LocalDate startDate, + @Param(value = "endDate") LocalDate endDate, + @Param(value = "user") User user); } diff --git a/src/main/java/LearnMate/dev/service/ReportService.java b/src/main/java/LearnMate/dev/service/ReportService.java index 5272dbb..f653ee5 100644 --- a/src/main/java/LearnMate/dev/service/ReportService.java +++ b/src/main/java/LearnMate/dev/service/ReportService.java @@ -15,10 +15,8 @@ import org.springframework.stereotype.Service; import java.time.LocalDate; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; @Service @@ -29,32 +27,84 @@ public class ReportService { /* - * user가 2주동안 겪은 각 감정의 개수를 리스트 형태로 반환 + * user의 2주동안 나타난 각 감정의 개수를 리스트 형태로 반환 * @return */ public ReportResponse.ReportDto getEmotionReport() { Long userId = getUserIdFromAuthentication(); User user = findUserById(userId); + LocalDate now = LocalDate.now(); + LocalDate twoWeekAgo = now.minusDays(14); + // 2주동안 나타난 각 감정의 개수 반환 + List emotionDtoList = getEmotionDtoList(twoWeekAgo, now, user); + List reportEmotionDtoList = ReportConverter.toReportEmotionDtoList(emotionDtoList); + + return ReportConverter.toReportDto(reportEmotionDtoList); + } + + /* + * user의 2주동안 나타난 각 감정의 개수, 각 날짜에 나타난 감정, 가장 많이 나타난 감정 리스트를 반환 + * @return + */ + public ReportResponse.ReportDetailDto getEmotionDetailReport() { + Long userId = getUserIdFromAuthentication(); + User user = findUserById(userId); + LocalDate now = LocalDate.now(); LocalDate twoWeekAgo = now.minusDays(14); + + // 각 감정의 개수 List emotionDtoList = getEmotionDtoList(twoWeekAgo, now, user); + List reportEmotionDtoList = ReportConverter.toReportEmotionDtoList(emotionDtoList); + + // 각 날짜에 나타난 감정 + List emotionOnDayDtoList = getEmotionOnDay(twoWeekAgo, now, user); + // 해당 기간동안 가장 많이 나타난 감정 3개 + List emotionRankDtoList = getEmotionRank(reportEmotionDtoList); + + return ReportConverter.toReportDetailDto(reportEmotionDtoList, emotionOnDayDtoList, emotionRankDtoList); + } + + private List getEmotionDtoList(LocalDate startDate, LocalDate endDate, User user) { + List emotionDtoList = emotionRepository.findEmotionDtoByUser(startDate, endDate, user); + return getDefaultEmotionDtoAndParse(emotionDtoList); + } + + private List getDefaultEmotionDtoAndParse(List emotionDtoList) { // 각 감정에 대한 결과 emotiondto를 mapping Map emotionDtoMap = emotionDtoList.stream() .collect(Collectors.toMap(ReportResponse.EmotionDto::getEmotionSpectrum, dto -> dto)); // 0개 나타난 emotion dto 추가 및 정렬 - List completeEmotionList = Arrays.stream(EmotionSpectrum.values()) + return Arrays.stream(EmotionSpectrum.values()) .map(emotionSpectrum -> emotionDtoMap.getOrDefault( emotionSpectrum, new ReportResponse.EmotionDto(emotionSpectrum, 0L) // 기본값으로 초기화된 DTO )) .sorted(Comparator.comparingInt(ReportResponse.EmotionDto::getOrder)) // 정렬 .toList(); + } - return ReportConverter.toReportDto(completeEmotionList); + private List getEmotionOnDay(LocalDate startDate, LocalDate endDate, User user) { + return emotionRepository.findEmotionOnDayDtoByUser(startDate, endDate, user); + } + + private List getEmotionRank(List emotionDtoList) { + AtomicLong rankCounter = new AtomicLong(1); + + return emotionDtoList.stream() + // count 기준 내림차순 정렬 + .sorted(Comparator.comparingLong(ReportResponse.ReportEmotionDto::getCount).reversed()) + .limit(3) // 상위 3개만 추출 + .map(dto -> new ReportResponse.EmotionRankDto( // dto 변환 + dto.getEmotion(), + dto.getEmoticon(), + rankCounter.getAndIncrement() // 랭크 할당 + )) + .toList(); } private Long getUserIdFromAuthentication() { @@ -66,8 +116,4 @@ private Long getUserIdFromAuthentication() { private User findUserById(Long userId) { return userRepository.findById(userId).orElseThrow(() -> new ApiException(ErrorStatus._USER_NOT_FOUND)); } - - private List getEmotionDtoList(LocalDate startDate, LocalDate endDate, User user) { - return emotionRepository.findEmotionDtoByUser(startDate, endDate, user); - } }