From 340714d97d690748e39aa021ef8e6249fc5cd6a7 Mon Sep 17 00:00:00 2001 From: dayoung030303 Date: Tue, 27 May 2025 00:00:27 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A7=80=EC=8B=9D=EC=B9=B4=EB=93=9C(=EC=98=A4?= =?UTF-8?q?=EB=8A=98=EC=9D=98=20=EB=82=A0=EC=A7=9C)=20=EB=AA=A9=EB=A1=9D?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20->=20=EC=9B=90=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=82=A0=EC=A7=9C=20=EC=A7=80=EC=A0=95=20=EB=B2=94=EC=9C=84=20?= =?UTF-8?q?=ED=99=95=EC=9E=A5=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20build.gradle=EB=B6=80=EB=B6=84=EC=97=90=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80(=EB=B9=8C=EB=93=9C=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=EB=A1=9C=20=EC=9D=B8=ED=95=B4)=20=EB=B0=8F?= =?UTF-8?q?=20=EC=B9=B4=EB=93=9C=20=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../card/controller/CardController.java | 6 +- .../card/controller/StatsController.java | 39 +++++++++-- .../card/domain/entity/Card.java | 2 + .../card/repository/CardRepository.java | 10 ++- .../card/service/CardService.java | 19 +++--- .../card/service/StatsService.java | 65 +++++++++++++++++-- 7 files changed, 117 insertions(+), 25 deletions(-) diff --git a/build.gradle b/build.gradle index 299c887..4155f82 100644 --- a/build.gradle +++ b/build.gradle @@ -29,6 +29,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web-services' implementation 'org.mariadb.jdbc:mariadb-java-client:3.4.1' implementation 'org.springframework.boot:spring-boot-starter-data-jpa:3.3.4' + implementation 'org.jboss.logging:jboss-logging:3.5.0.Final' //새로 추가 debug문제로 인해 compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' diff --git a/src/main/java/com/example/gp_backend_data/card/controller/CardController.java b/src/main/java/com/example/gp_backend_data/card/controller/CardController.java index f5b5951..7522e7f 100644 --- a/src/main/java/com/example/gp_backend_data/card/controller/CardController.java +++ b/src/main/java/com/example/gp_backend_data/card/controller/CardController.java @@ -76,7 +76,9 @@ public ResponseEntity deleteCard(@PathVariable UUID cardId) { } @GetMapping("/by-date") - public List getCardsByCreatedAt(@RequestParam("createdAt") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate createdAt) { - return cardService.getCardsByCreatedAt(createdAt); + public ResponseEntity> getCardsByCreatedAt(@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate createdAt) { + List cards = cardService.getCardsByCreatedAt(createdAt); + return ResponseEntity.ok(cards); + } } diff --git a/src/main/java/com/example/gp_backend_data/card/controller/StatsController.java b/src/main/java/com/example/gp_backend_data/card/controller/StatsController.java index 6d070b0..638adbd 100644 --- a/src/main/java/com/example/gp_backend_data/card/controller/StatsController.java +++ b/src/main/java/com/example/gp_backend_data/card/controller/StatsController.java @@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.server.ResponseStatusException; +import java.time.LocalDate; import java.util.List; @RestController @@ -20,16 +21,42 @@ public class StatsController { private final StatsService statsService; +// @GetMapping("/latest-activities") +// public ResponseEntity> getTodayActivities( +// @RequestParam String filterByDate, +// @RequestParam String groupBy +// ) { +// if (!"today".equals(filterByDate) || !"spaceId".equals(groupBy)) { +// throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid filterByDate or groupBy parameter"); +// } +// +// List activities = statsService.getTodayActivitiesGroupedBySpace(); +// return ResponseEntity.ok(activities); +// } + @GetMapping("/latest-activities") - public ResponseEntity> getTodayActivities( + public ResponseEntity> getActivities( @RequestParam String filterByDate, - @RequestParam String groupBy + @RequestParam String groupBy, + @RequestParam(required = false) String from, + @RequestParam(required = false) String to ) { - if (!"today".equals(filterByDate) || !"spaceId".equals(groupBy)) { - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid filterByDate or groupBy parameter"); + if (!"spaceId".equals(groupBy)) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid groupBy parameter"); + } + + if ("today".equals(filterByDate)) { + return ResponseEntity.ok(statsService.getTodayActivitiesGroupedBySpace()); + } else if ("range".equals(filterByDate)) { + if (from == null || to == null) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Missing 'from' or 'to' parameter for date range"); + } + + LocalDate fromDate = LocalDate.parse(from); + LocalDate toDate = LocalDate.parse(to); + return ResponseEntity.ok(statsService.getActivitiesByDateRangeGroupedBySpace(fromDate, toDate)); } - List activities = statsService.getTodayActivitiesGroupedBySpace(); - return ResponseEntity.ok(activities); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid filterByDate parameter"); } } diff --git a/src/main/java/com/example/gp_backend_data/card/domain/entity/Card.java b/src/main/java/com/example/gp_backend_data/card/domain/entity/Card.java index 4234609..f60ccaf 100644 --- a/src/main/java/com/example/gp_backend_data/card/domain/entity/Card.java +++ b/src/main/java/com/example/gp_backend_data/card/domain/entity/Card.java @@ -1,5 +1,6 @@ package com.example.gp_backend_data.card.domain.entity; +import com.example.gp_backend_data.space.domain.entity.Space; import jakarta.persistence.*; import lombok.*; import org.hibernate.annotations.CreationTimestamp; @@ -48,5 +49,6 @@ public class Card { @OneToMany(mappedBy = "card", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List cardlinks; + } diff --git a/src/main/java/com/example/gp_backend_data/card/repository/CardRepository.java b/src/main/java/com/example/gp_backend_data/card/repository/CardRepository.java index 273f5c5..8255f51 100644 --- a/src/main/java/com/example/gp_backend_data/card/repository/CardRepository.java +++ b/src/main/java/com/example/gp_backend_data/card/repository/CardRepository.java @@ -7,6 +7,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -17,7 +18,10 @@ public interface CardRepository extends JpaRepository { void deleteByCardId(byte[] cardId); @Query("SELECT DISTINCT c FROM Card c " + "JOIN c.cardlinks cl " + "WHERE cl.chatId = :threadId") Page findByCardlinkedThreadId(@Param("threadId") byte[] threadId, Pageable pageable); - List findByCreatedAtBetween(LocalDateTime start, LocalDateTime end); - @Query("SELECT c FROM Card c WHERE DATE(c.createdAt) = CURRENT_DATE") - List findTodayCreatedCards(); + @Query("SELECT c FROM Card c WHERE DATE(c.createdAt) = :createdDate") + List findAllByCreatedDate(@Param("createdDate") LocalDate createdDate); +// @Query("SELECT c FROM Card c WHERE DATE(c.createdAt) = CURRENT_DATE") +// List findTodayCreatedCards(); + @Query("SELECT c FROM Card c WHERE c.createdAt >= :start AND c.createdAt < :end") + List findCardsCreatedBetween(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end); } diff --git a/src/main/java/com/example/gp_backend_data/card/service/CardService.java b/src/main/java/com/example/gp_backend_data/card/service/CardService.java index 09a72a4..f578ad1 100644 --- a/src/main/java/com/example/gp_backend_data/card/service/CardService.java +++ b/src/main/java/com/example/gp_backend_data/card/service/CardService.java @@ -197,23 +197,24 @@ public void deleteCard(UUID cardId) { //오늘 생성된 지식카드 목록 조회 @Transactional - public List getCardsByCreatedAt(LocalDate createdAt) { - // createdAt의 하루 시작과 끝 구하기 - LocalDateTime startOfDay = createdAt.atStartOfDay(); - LocalDateTime endOfDay = createdAt.atTime(LocalTime.MAX); + public List getCardsByCreatedAt(LocalDate date) { + List cards = cardRepository.findAllByCreatedDate(date); - List cards = cardRepository.findByCreatedAtBetween(startOfDay, endOfDay); + if (cards.isEmpty()) { + throw new ResponseStatusException(HttpStatus.NO_CONTENT); + } - return cards.stream() - .map(card -> CardListResponse.builder() + return cards.stream().map(card -> + CardListResponse.builder() .cardId(uuidHelper.convertByteArrayToUUID(card.getCardId())) .spaceId(uuidHelper.convertByteArrayToUUID(card.getSpaceId())) .title(card.getTitle()) .createdAt(card.getCreatedAt()) - .build()) - .collect(Collectors.toList()); + .build() + ).collect(Collectors.toList()); } + //특정 스레드에 하이라이트된 하이링크 목록 조회 @Transactional public List getCardlinkedCards(UUID threadId, int count, int page, String sortBy) { diff --git a/src/main/java/com/example/gp_backend_data/card/service/StatsService.java b/src/main/java/com/example/gp_backend_data/card/service/StatsService.java index 50b8f22..081955d 100644 --- a/src/main/java/com/example/gp_backend_data/card/service/StatsService.java +++ b/src/main/java/com/example/gp_backend_data/card/service/StatsService.java @@ -16,6 +16,8 @@ import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -32,15 +34,68 @@ public class StatsService { private final CardlinkRepository cardlinkRepository; private final UUIDHelper uuidHelper; +// public List getTodayActivitiesGroupedBySpace() { +// List todayCards = cardRepository.findTodayCreatedCards(); +// +// if (todayCards.isEmpty()) { +// throw new ResponseStatusException(HttpStatus.NOT_FOUND, "No activity found for today."); +// } +// +// // 그룹핑 +// Map> groupedBySpace = todayCards.stream() +// .collect(Collectors.groupingBy(card -> uuidHelper.convertByteArrayToUUID(card.getSpaceId()).toString())); +// +// List results = new ArrayList<>(); +// +// for (Map.Entry> entry : groupedBySpace.entrySet()) { +// UUID spaceId = UUID.fromString(entry.getKey()); +// Space space = spaceRepository.findById(uuidHelper.convertUUIDToByteArray(spaceId)) +// .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Space not found")); +// +// List cardResponses = entry.getValue().stream().map(card -> { +// List cardlinks = cardlinkRepository.findByCard(card).stream() +// .map(link -> CardlinkResponse.builder() +// .cardlinkId(uuidHelper.convertByteArrayToUUID(link.getCardlinkId())) +// .chatId(uuidHelper.convertByteArrayToUUID(link.getChatId())) +// .content(link.getContent()) +// .build()) +// .toList(); +// +// return CardSpaceResponse.builder() +// .cardId(uuidHelper.convertByteArrayToUUID(card.getCardId())) +// .title(card.getTitle()) +// .aiSummary(card.getAiSummary()) +// .createdAt(card.getCreatedAt()) +// .cardlinks(cardlinks) +// .build(); +// }).toList(); +// +// results.add(LatestActivityResponse.builder() +// .spaceId(spaceId) +// .spaceName(space.getTitle()) +// .cards(cardResponses) +// .build()); +// } +// +// return results; +// } + public List getTodayActivitiesGroupedBySpace() { - List todayCards = cardRepository.findTodayCreatedCards(); + LocalDate today = LocalDate.now(); + return getActivitiesByDateRangeGroupedBySpace(today, today); + } + + public List getActivitiesByDateRangeGroupedBySpace(LocalDate from, LocalDate to) { + LocalDateTime start = from.atStartOfDay(); + LocalDateTime end = to.plusDays(1).atStartOfDay(); // exclusive upper bound + + List cards = cardRepository.findCardsCreatedBetween(start, end); - if (todayCards.isEmpty()) { - throw new ResponseStatusException(HttpStatus.NOT_FOUND, "No activity found for today."); + if (cards.isEmpty()) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "No activity found for selected date range."); } - // 그룹핑 - Map> groupedBySpace = todayCards.stream() + Map> groupedBySpace = cards.stream() .collect(Collectors.groupingBy(card -> uuidHelper.convertByteArrayToUUID(card.getSpaceId()).toString())); List results = new ArrayList<>();