From a7635869f6eb9dbe136ee4ff243f5ce5de356d83 Mon Sep 17 00:00:00 2001 From: sinkyoungdeok Date: Mon, 27 May 2024 04:53:24 +0900 Subject: [PATCH] =?UTF-8?q?[KAN-101]=20chat=20gpt=20=EA=B8=B0=EB=B0=98=20?= =?UTF-8?q?=EC=9D=8C=EC=8B=9D=EC=A0=90=20=EC=B6=94=EC=B2=9C=20(=EC=98=A4?= =?UTF-8?q?=EB=8A=98=EC=9D=98=ED=94=BD=20API)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../be/common/redis/RedisRepository.kt | 19 ++++++++++ .../service/RecommendRestaurantService.kt | 36 +++++++++++++++++++ .../RecommendRestaurantController.kt | 8 +++-- 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/com/restaurant/be/restaurant/domain/service/RecommendRestaurantService.kt diff --git a/src/main/kotlin/com/restaurant/be/common/redis/RedisRepository.kt b/src/main/kotlin/com/restaurant/be/common/redis/RedisRepository.kt index e2929d5..0561959 100644 --- a/src/main/kotlin/com/restaurant/be/common/redis/RedisRepository.kt +++ b/src/main/kotlin/com/restaurant/be/common/redis/RedisRepository.kt @@ -11,10 +11,29 @@ class RedisRepository( companion object { private const val SEARCH_PREFIX = "SR:" // 검색어를 저장할 때 사용할 키 접두사 private const val MAX_HISTORY = 5 // 저장할 최대 검색어 수 + private const val RECOMMENDATION_PREFIX = "RECOMMENDATION:" } val REFRESH_PREFIX: String = "RT:" + // 사용자별 추천 식당을 조회하는 메서드 + fun getRecommendation(userId: Long): List { + val values = redisTemplate.opsForValue() + val key = "$RECOMMENDATION_PREFIX$userId" + val recommendations = values.get(key) + if (recommendations != null) { + return recommendations.split(",").map { it.toLong() } + } + + val defaultKey = RECOMMENDATION_PREFIX + "0" + val defaultRecommendations = values.get(defaultKey) + if (defaultRecommendations != null) { + return defaultRecommendations.split(",").map { it.toLong() } + } + + return emptyList() + } + // 사용자별 검색어를 추가하는 메서드 fun addSearchQuery(userId: Long, query: String) { val key = "$SEARCH_PREFIX$userId" // 사용자별 고유 키 생성 diff --git a/src/main/kotlin/com/restaurant/be/restaurant/domain/service/RecommendRestaurantService.kt b/src/main/kotlin/com/restaurant/be/restaurant/domain/service/RecommendRestaurantService.kt new file mode 100644 index 0000000..cb19780 --- /dev/null +++ b/src/main/kotlin/com/restaurant/be/restaurant/domain/service/RecommendRestaurantService.kt @@ -0,0 +1,36 @@ +package com.restaurant.be.restaurant.domain.service + +import com.restaurant.be.common.exception.NotFoundUserException +import com.restaurant.be.common.redis.RedisRepository +import com.restaurant.be.restaurant.presentation.controller.dto.RecommendRestaurantResponse +import com.restaurant.be.restaurant.repository.RestaurantRepository +import com.restaurant.be.user.repository.UserRepository +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +class RecommendRestaurantService( + private val redisRepository: RedisRepository, + private val restaurantRepository: RestaurantRepository, + private val userRepository: UserRepository +) { + + @Transactional(readOnly = true) + fun recommendRestaurants(email: String): RecommendRestaurantResponse { + val userId = userRepository.findByEmail(email)?.id ?: throw NotFoundUserException() + + val restaurantIds = redisRepository.getRecommendation(userId) + + val restaurantDtos = restaurantRepository.findDtoByIds(restaurantIds, userId) + + val randomRestaurantDtos = if (restaurantDtos.size > 5) { + restaurantDtos.shuffled().take(5) + } else { + restaurantDtos + } + + return RecommendRestaurantResponse( + restaurants = randomRestaurantDtos.map { it.toDto() } + ) + } +} diff --git a/src/main/kotlin/com/restaurant/be/restaurant/presentation/controller/RecommendRestaurantController.kt b/src/main/kotlin/com/restaurant/be/restaurant/presentation/controller/RecommendRestaurantController.kt index efc7659..845b5bc 100644 --- a/src/main/kotlin/com/restaurant/be/restaurant/presentation/controller/RecommendRestaurantController.kt +++ b/src/main/kotlin/com/restaurant/be/restaurant/presentation/controller/RecommendRestaurantController.kt @@ -1,6 +1,7 @@ package com.restaurant.be.restaurant.presentation.controller import com.restaurant.be.common.response.CommonResponse +import com.restaurant.be.restaurant.domain.service.RecommendRestaurantService import com.restaurant.be.restaurant.presentation.controller.dto.RecommendRestaurantResponse import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation @@ -16,7 +17,9 @@ import java.security.Principal @Api(tags = ["02. Restaurant Info"], description = "음식점 서비스") @RestController @RequestMapping("/v1/restaurants") -class RecommendRestaurantController { +class RecommendRestaurantController( + private val recommendRestaurantService: RecommendRestaurantService +) { @GetMapping("recommend") @PreAuthorize("hasRole('USER')") @@ -29,6 +32,7 @@ class RecommendRestaurantController { fun getRecommendRestaurants( principal: Principal ): CommonResponse { - return CommonResponse.success() + val response = recommendRestaurantService.recommendRestaurants(principal.name) + return CommonResponse.success(response) } }