From 6bfbf784d070761bbafbf937de9a5afc80a074b4 Mon Sep 17 00:00:00 2001 From: koosco Date: Thu, 5 Dec 2024 21:38:52 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=AA=A9=ED=91=9C=20=ED=83=90=EC=83=89?= =?UTF-8?q?=20=EC=83=81=EC=84=B8=20API=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orbit/goal/app/MemberGoalService.java | 4 ++ .../response/GoalSearchDetailResponseDto.java | 5 ++ .../goal/app/query/GoalSearchService.java | 51 +++++++++++++++++++ .../query/GoalSearchController.java | 26 ++++++++++ .../orbit/goal/dao/MemberGoalRepository.java | 7 +++ 5 files changed, 93 insertions(+) create mode 100644 src/main/java/com/groom/orbit/goal/app/dto/response/GoalSearchDetailResponseDto.java create mode 100644 src/main/java/com/groom/orbit/goal/app/query/GoalSearchService.java create mode 100644 src/main/java/com/groom/orbit/goal/controller/query/GoalSearchController.java diff --git a/src/main/java/com/groom/orbit/goal/app/MemberGoalService.java b/src/main/java/com/groom/orbit/goal/app/MemberGoalService.java index 3722911..11e44ad 100644 --- a/src/main/java/com/groom/orbit/goal/app/MemberGoalService.java +++ b/src/main/java/com/groom/orbit/goal/app/MemberGoalService.java @@ -286,4 +286,8 @@ public GetMemberGoalResponseDto createOtherGoal(Long memberId, Long memberGoalId copyMemberGoal.getCompletedDate().toLocalDate(), questDtos); } + + public List findAllMemberGoal(Long goalId) { + return memberGoalRepository.findAllWithQuestsByGoalId(goalId); + } } diff --git a/src/main/java/com/groom/orbit/goal/app/dto/response/GoalSearchDetailResponseDto.java b/src/main/java/com/groom/orbit/goal/app/dto/response/GoalSearchDetailResponseDto.java new file mode 100644 index 0000000..0a0d2b3 --- /dev/null +++ b/src/main/java/com/groom/orbit/goal/app/dto/response/GoalSearchDetailResponseDto.java @@ -0,0 +1,5 @@ +package com.groom.orbit.goal.app.dto.response; + +import java.util.List; + +public record GoalSearchDetailResponseDto(String category, String goalName, List quests) {} diff --git a/src/main/java/com/groom/orbit/goal/app/query/GoalSearchService.java b/src/main/java/com/groom/orbit/goal/app/query/GoalSearchService.java new file mode 100644 index 0000000..5d8628a --- /dev/null +++ b/src/main/java/com/groom/orbit/goal/app/query/GoalSearchService.java @@ -0,0 +1,51 @@ +package com.groom.orbit.goal.app.query; + +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.groom.orbit.common.exception.CommonException; +import com.groom.orbit.common.exception.ErrorCode; +import com.groom.orbit.goal.app.MemberGoalService; +import com.groom.orbit.goal.app.dto.response.GoalSearchDetailResponseDto; +import com.groom.orbit.goal.dao.entity.Goal; +import com.groom.orbit.goal.dao.entity.MemberGoal; +import com.groom.orbit.goal.dao.entity.Quest; + +import lombok.RequiredArgsConstructor; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class GoalSearchService { + + private final MemberGoalService memberGoalService; + + public GoalSearchDetailResponseDto findGoal(Long goalId) { + List memberGoals = memberGoalService.findAllMemberGoal(goalId); + Goal goal = findGoal(memberGoals); + List questTitles = + memberGoals.stream() + .map(MemberGoal::getQuests) + .flatMap(Collection::stream) + .collect(Collectors.toSet()) + .stream() + .sorted(Comparator.comparing(Quest::getCreatedAt).reversed()) + .map(Quest::getTitle) + .toList(); + + return new GoalSearchDetailResponseDto( + goal.getCategory().getCategory(), goal.getTitle(), questTitles); + } + + private static Goal findGoal(List memberGoals) { + if (memberGoals.isEmpty()) { + throw new CommonException(ErrorCode.NOT_FOUND_GOAL); + } + return memberGoals.getFirst().getGoal(); + } +} diff --git a/src/main/java/com/groom/orbit/goal/controller/query/GoalSearchController.java b/src/main/java/com/groom/orbit/goal/controller/query/GoalSearchController.java new file mode 100644 index 0000000..ab7c5e2 --- /dev/null +++ b/src/main/java/com/groom/orbit/goal/controller/query/GoalSearchController.java @@ -0,0 +1,26 @@ +package com.groom.orbit.goal.controller.query; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.groom.orbit.common.dto.ResponseDto; +import com.groom.orbit.goal.app.dto.response.GoalSearchDetailResponseDto; +import com.groom.orbit.goal.app.query.GoalSearchService; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/goal/search") +public class GoalSearchController { + + private final GoalSearchService goalSearchService; + + @GetMapping("/{goal_id}") + public ResponseDto getSearchDetail( + @PathVariable("goal_id") Long goalId) { + return ResponseDto.ok(goalSearchService.findGoal(goalId)); + } +} diff --git a/src/main/java/com/groom/orbit/goal/dao/MemberGoalRepository.java b/src/main/java/com/groom/orbit/goal/dao/MemberGoalRepository.java index f8e49bf..4f475dd 100644 --- a/src/main/java/com/groom/orbit/goal/dao/MemberGoalRepository.java +++ b/src/main/java/com/groom/orbit/goal/dao/MemberGoalRepository.java @@ -44,4 +44,11 @@ List findByMemberIdAndIsComplete( List findAllByMemberIdAndIsCompleteFalseAndSequenceGreaterThan( Long memberId, Long sequence); + + @Query( + "select mg from MemberGoal mg" + + " join fetch mg.goal g" + + " join fetch mg.quests q" + + " where g.goalId=:goal_id") + List findAllWithQuestsByGoalId(@Param("goal_id") Long goalId); }