From b504edd9d971999abc82306760ccb2f0927e6af1 Mon Sep 17 00:00:00 2001 From: HyunJun Mun <137624597+Mouon@users.noreply.github.com> Date: Wed, 7 Feb 2024 19:28:23 +0900 Subject: [PATCH] =?UTF-8?q?Feat=20:=20CHAT-278-BE-API-=ED=83=9C=EA=B7=B8-?= =?UTF-8?q?=EC=83=81=EC=84=B8-=ED=86=B5=EA=B3=84=20(#42)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat : DTO 추가 상세 태그 통계를 위해 detailstatic dto 추가 * Feat : 컨트롤러 계층, 서비스 계층 추가 기존의 매서드 최대한 활용해서 구현, 파라매터로 카테고리까지 받게, 전체에대한 부분은 자바 로직을 통해 구현 * Chore : 주석 추가 코드 로직 설명 추가 (추후 리펙토링시 용이하기 위함) * Chore : 주석 추가 * Feat : 수정사항 반영 DTO 맵으로 바꾸고, 맵을 순회하며 데이터 매핑 + 전체 따로 처리 * Feat : 수정사항 반영 DTO 맵으로 바꾸고, 맵을 순회하며 데이터 매핑 + 전체 따로 처리 * Feat : 수정사항 반영 DTO 구조 바꾸고, 변경에따른 tagList 로직 수정 * Feat : 레포지토리 수정사항 반영 레포지토리 일반적으로 수정, 쿼리문이 복잡해서 맞는지 모르겠음.. * Revert "Feat : 수정사항 반영" This reverts commit 9153cf67e91afb009c17504bab89866da0f2cf1e. # Conflicts: # src/main/java/com/kuit/chatdiary/repository/diary/TagSearchRepository.java * Fix : 커밋 취소 * Fix : 커밋 취소 * Feat : 서비스 단 수정 statisticsMap을 채우는 부분에서, ".limit(10)" 추가를 통해 결과 10개로 제한 * Chore : 주석 추가 * Feat : 컨트롤러 도메인 커밋 반영 * Fix : 커밋 수정사항 반영 --- .../diary/DiaryTagStatisticsController.java | 11 ++++ .../dto/diary/TagDetailStatisticsDTO.java | 14 ++++ .../diary/TagDetailStatisticsResponseDTO.java | 20 ++++++ .../repository/diary/DiaryTagRepository.java | 1 + .../diary/DiaryTagStatisticsService.java | 64 +++++++++++++++++-- 5 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/kuit/chatdiary/dto/diary/TagDetailStatisticsDTO.java create mode 100644 src/main/java/com/kuit/chatdiary/dto/diary/TagDetailStatisticsResponseDTO.java diff --git a/src/main/java/com/kuit/chatdiary/controller/diary/DiaryTagStatisticsController.java b/src/main/java/com/kuit/chatdiary/controller/diary/DiaryTagStatisticsController.java index 17c148d0..13e0d637 100644 --- a/src/main/java/com/kuit/chatdiary/controller/diary/DiaryTagStatisticsController.java +++ b/src/main/java/com/kuit/chatdiary/controller/diary/DiaryTagStatisticsController.java @@ -1,5 +1,6 @@ package com.kuit.chatdiary.controller.diary; +import com.kuit.chatdiary.dto.diary.TagDetailStatisticsResponseDTO; import com.kuit.chatdiary.dto.diary.TagStatisticsWithDateResponseDTO; import com.kuit.chatdiary.service.diary.DiaryTagStatisticsService; import org.springframework.http.ResponseEntity; @@ -22,4 +23,14 @@ public ResponseEntity getTagStatistics( TagStatisticsWithDateResponseDTO tagStatistics = diaryTagStatisticsService.calculateTagStatistics(memberId, type); return ResponseEntity.ok(tagStatistics); } + + @GetMapping("/tags/detail") + public ResponseEntity geDetailTagStatistics( + @RequestParam("memberId") Long memberId, + @RequestParam("type") String type + ) { + TagDetailStatisticsResponseDTO tagStatistics = diaryTagStatisticsService.calculateTagDetailStatistics(memberId,type); + return ResponseEntity.ok(tagStatistics); + } + } diff --git a/src/main/java/com/kuit/chatdiary/dto/diary/TagDetailStatisticsDTO.java b/src/main/java/com/kuit/chatdiary/dto/diary/TagDetailStatisticsDTO.java new file mode 100644 index 00000000..5b82bedb --- /dev/null +++ b/src/main/java/com/kuit/chatdiary/dto/diary/TagDetailStatisticsDTO.java @@ -0,0 +1,14 @@ +package com.kuit.chatdiary.dto.diary; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + + +@Getter +@Setter +@AllArgsConstructor +public class TagDetailStatisticsDTO { + private Long count; + private String[] tags; +} diff --git a/src/main/java/com/kuit/chatdiary/dto/diary/TagDetailStatisticsResponseDTO.java b/src/main/java/com/kuit/chatdiary/dto/diary/TagDetailStatisticsResponseDTO.java new file mode 100644 index 00000000..b21362f5 --- /dev/null +++ b/src/main/java/com/kuit/chatdiary/dto/diary/TagDetailStatisticsResponseDTO.java @@ -0,0 +1,20 @@ +package com.kuit.chatdiary.dto.diary; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.sql.Date; +import java.util.List; +import java.util.Map; + + +@AllArgsConstructor +@Getter +@Setter +public class TagDetailStatisticsResponseDTO { + private Date startDate; + private Date endDate; + private Map> statistics; + +} diff --git a/src/main/java/com/kuit/chatdiary/repository/diary/DiaryTagRepository.java b/src/main/java/com/kuit/chatdiary/repository/diary/DiaryTagRepository.java index 2eb601eb..db124f55 100644 --- a/src/main/java/com/kuit/chatdiary/repository/diary/DiaryTagRepository.java +++ b/src/main/java/com/kuit/chatdiary/repository/diary/DiaryTagRepository.java @@ -28,4 +28,5 @@ public List findTagStatisticsByMember(Long memberId, Date startDate, D .getResultList(); } + } diff --git a/src/main/java/com/kuit/chatdiary/service/diary/DiaryTagStatisticsService.java b/src/main/java/com/kuit/chatdiary/service/diary/DiaryTagStatisticsService.java index 73355502..9487e67d 100644 --- a/src/main/java/com/kuit/chatdiary/service/diary/DiaryTagStatisticsService.java +++ b/src/main/java/com/kuit/chatdiary/service/diary/DiaryTagStatisticsService.java @@ -1,14 +1,13 @@ package com.kuit.chatdiary.service.diary; -import com.kuit.chatdiary.dto.diary.DateRangeDTO; -import com.kuit.chatdiary.dto.diary.TagStatisticResponseDTO; -import com.kuit.chatdiary.dto.diary.TagStatisticsWithDateResponseDTO; +import com.kuit.chatdiary.dto.diary.*; import com.kuit.chatdiary.repository.diary.DiaryTagRepository; import org.springframework.stereotype.Service; import java.sql.Date; import java.time.LocalDate; import java.util.*; +import java.util.stream.Collectors; @Service public class DiaryTagStatisticsService { @@ -30,6 +29,46 @@ public TagStatisticsWithDateResponseDTO calculateTagStatistics(Long memberId, St return new TagStatisticsWithDateResponseDTO(dateRange.getStartDate(), dateRange.getEndDate(), statisticsList); } + + public TagDetailStatisticsResponseDTO calculateTagDetailStatistics(Long memberId, String type) { + LocalDate localDate = LocalDate.now(); + DateRangeDTO dateRange = calculateDateRangeBasedOnType(type, localDate); + List tagStatistics = diaryTagRepository.findTagStatisticsByMember(memberId, dateRange.getStartDate(), dateRange.getEndDate()); + + Map>> categoryTagsMap = new HashMap<>(); + + String[] categories = {"전체", "인물", "행동", "장소", "감정"}; + for (String category : categories) { + categoryTagsMap.put(category, new HashMap<>()); + } + + for (Object[] row : tagStatistics) { + String category = (String) row[0]; + String tagName = (String) row[1]; + Long count = (Long) row[2]; + + /** 카테고리로 맵 가져오기 + * 맵에 특정 카운트에 해당하는 집합 없으면 새로운 집합 생성 + * */ + categoryTagsMap.get(category).computeIfAbsent(count, k -> new HashSet<>()).add(tagName); + categoryTagsMap.get("전체").computeIfAbsent(count, k -> new HashSet<>()).add(tagName); + } + + Map> statisticsMap = new HashMap<>(); + for (String category : categories) { + List categoryStats = categoryTagsMap.get(category).entrySet().stream() + .map(entry -> new TagDetailStatisticsDTO(entry.getKey(), entry.getValue().toArray(new String[0]))) + .sorted(Comparator.comparingLong(TagDetailStatisticsDTO::getCount).reversed()) + .limit(10) + .collect(Collectors.toList()); + statisticsMap.put(category, categoryStats); + } + + return new TagDetailStatisticsResponseDTO(dateRange.getStartDate(),dateRange.getEndDate(), statisticsMap); + } + + + /** 타입별로 나눠서 계산 */ private DateRangeDTO calculateDateRangeBasedOnType(String type, LocalDate date) { return staticsType(type, date); @@ -51,17 +90,34 @@ private List buildStatisticsList(List tagStat return statisticsList; } + /** 리스안에 리스트안에 리스트 와 같은 구조로 가공 (맵안에 맵) + * 카테고리로 한번 묶고, 횟수로 그 안에서 그릅화 하기 위함 + * */ + private List buildDetailStatisticsList(Map> countMap) { + return countMap.entrySet().stream() + .map(entry -> new TagDetailStatisticsDTO(entry.getKey(), entry.getValue().toArray(new String[0]))) + .sorted(Comparator.comparingLong(TagDetailStatisticsDTO::getCount).reversed()) + .collect(Collectors.toList()); + } + + /** 정렬 메서드 */ private void sortStatisticsListByCount(List statisticsList) { statisticsList.sort(Comparator.comparingLong(TagStatisticResponseDTO::getCount).reversed()); } + /** 정렬 메서드 재탕 + * 반환하는 자료형이 달라서 분리됬지만.. 리펙시 묶는것 가능해보임 + * */ + private void sortDetailStatisticsListByCount(List statisticsList) { + statisticsList.sort(Comparator.comparingLong(TagDetailStatisticsDTO::getCount).reversed()); + } public double calculatePercent(long count,long totalTags){ double percentage = (double) count / totalTags * 100; return Math.round(percentage*10)/10.0; } - /** 코드 더 줄이고 싶은데.. */ + /** 통계에서 공통으로 사용하는 메서드라 나중에 합칠수 있을듯*/ public DateRangeDTO staticsType(String type, LocalDate localDate){ LocalDate startDate; LocalDate endDate;