From 4774ba50651163ea9a6f4fd3482c3a206612b511 Mon Sep 17 00:00:00 2001 From: vectorch Date: Wed, 15 Nov 2023 15:28:25 +0900 Subject: [PATCH] =?UTF-8?q?feature:=20=ED=80=98=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EC=B2=9C=20API=EB=A5=BC=20=EC=9E=84=EC=8B=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/RecommendQuestsService.java | 41 +++++++++++++++++++ .../quest/presentation/QuestQueryApi.java | 15 ++++++- .../quest/query/QuestRecommendDao.java | 16 ++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/main/java/daybyquest/quest/application/RecommendQuestsService.java create mode 100644 src/main/java/daybyquest/quest/query/QuestRecommendDao.java diff --git a/src/main/java/daybyquest/quest/application/RecommendQuestsService.java b/src/main/java/daybyquest/quest/application/RecommendQuestsService.java new file mode 100644 index 0000000..c7a4745 --- /dev/null +++ b/src/main/java/daybyquest/quest/application/RecommendQuestsService.java @@ -0,0 +1,41 @@ +package daybyquest.quest.application; + +import daybyquest.quest.dto.response.MultipleQuestsResponse; +import daybyquest.quest.dto.response.QuestResponse; +import daybyquest.quest.query.QuestDao; +import daybyquest.quest.query.QuestData; +import daybyquest.quest.query.QuestRecommendDao; +import daybyquest.user.domain.User; +import daybyquest.user.domain.Users; +import java.util.List; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class RecommendQuestsService { + + private static final int MAX_RECOMMENDATION_COUNT = 5; + + private final Users users; + + private final QuestRecommendDao recommendDao; + + private final QuestDao questDao; + + public RecommendQuestsService(final Users users, final QuestRecommendDao recommendDao, + final QuestDao questDao) { + this.users = users; + this.recommendDao = recommendDao; + this.questDao = questDao; + } + + @Transactional(readOnly = true) + public MultipleQuestsResponse invoke(final Long loginId) { + final User user = users.getById(loginId); + final List ids = recommendDao.findTopNNormalQuestIdsByInterestIn(MAX_RECOMMENDATION_COUNT, + user.getInterests()); + final List questData = questDao.findAllByIdIn(loginId, ids); + final List responses = questData.stream().map(QuestResponse::of).toList(); + return new MultipleQuestsResponse(responses); + } +} diff --git a/src/main/java/daybyquest/quest/presentation/QuestQueryApi.java b/src/main/java/daybyquest/quest/presentation/QuestQueryApi.java index 3c42f8f..08c1353 100644 --- a/src/main/java/daybyquest/quest/presentation/QuestQueryApi.java +++ b/src/main/java/daybyquest/quest/presentation/QuestQueryApi.java @@ -4,6 +4,8 @@ import daybyquest.auth.domain.AccessUser; import daybyquest.quest.application.GetQuestByIdService; import daybyquest.quest.application.GetQuestImagesService; +import daybyquest.quest.application.RecommendQuestsService; +import daybyquest.quest.dto.response.MultipleQuestsResponse; import daybyquest.quest.dto.response.QuestImagesResponse; import daybyquest.quest.dto.response.QuestResponse; import org.springframework.http.ResponseEntity; @@ -18,10 +20,14 @@ public class QuestQueryApi { private final GetQuestImagesService getQuestImagesService; + private final RecommendQuestsService recommendQuestsService; + public QuestQueryApi(final GetQuestByIdService getQuestByIdService, - final GetQuestImagesService getQuestImagesService) { + final GetQuestImagesService getQuestImagesService, + final RecommendQuestsService recommendQuestsService) { this.getQuestByIdService = getQuestByIdService; this.getQuestImagesService = getQuestImagesService; + this.recommendQuestsService = recommendQuestsService; } @GetMapping("/quest/{questId}") @@ -37,4 +43,11 @@ public ResponseEntity getQuestImages(@PathVariable final Lo final QuestImagesResponse response = getQuestImagesService.invoke(questId); return ResponseEntity.ok(response); } + + @GetMapping("/quest/recommendation") + @Authorization + public ResponseEntity recommendQuests(final AccessUser accessUser) { + final MultipleQuestsResponse response = recommendQuestsService.invoke(accessUser.getId()); + return ResponseEntity.ok(response); + } } diff --git a/src/main/java/daybyquest/quest/query/QuestRecommendDao.java b/src/main/java/daybyquest/quest/query/QuestRecommendDao.java new file mode 100644 index 0000000..cb92ef0 --- /dev/null +++ b/src/main/java/daybyquest/quest/query/QuestRecommendDao.java @@ -0,0 +1,16 @@ +package daybyquest.quest.query; + +import daybyquest.quest.domain.Quest; +import java.util.Collection; +import java.util.List; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.Repository; + +public interface QuestRecommendDao extends Repository { + + @Query(value = "select q.id from quest q where q.category='NORMAL' and q.interest_name in :interests " + + "and q.id >= FLOOR(1 + RAND() * (select MAX(quest.id) from quest)) " + + "ORDER BY q.id limit :topN", + nativeQuery = true) + List findTopNNormalQuestIdsByInterestIn(final int topN, final Collection interests); +}