From a97bed7c9c65b6a65a4e6ce01e46b4e119da78a7 Mon Sep 17 00:00:00 2001 From: zzuhannn Date: Fri, 14 Nov 2025 20:23:32 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20AI=20=EC=B6=94=EC=B2=9C=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=EB=B0=98=ED=99=98=EA=B0=92=EC=97=90=20url?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/AIRecommendationService.java | 41 +++++++++++++++++++ .../web/dto/AIRecommendationRes.java | 8 ++++ 2 files changed, 49 insertions(+) diff --git a/src/main/java/com/api/mov/domain/recommendation/service/AIRecommendationService.java b/src/main/java/com/api/mov/domain/recommendation/service/AIRecommendationService.java index c568758..a54478b 100644 --- a/src/main/java/com/api/mov/domain/recommendation/service/AIRecommendationService.java +++ b/src/main/java/com/api/mov/domain/recommendation/service/AIRecommendationService.java @@ -1,6 +1,9 @@ package com.api.mov.domain.recommendation.service; +import com.api.mov.domain.pass.entity.Pass; +import com.api.mov.domain.pass.repository.PassRepository; import com.api.mov.domain.recommendation.web.dto.AIRecommendationListRes; +import com.api.mov.domain.recommendation.web.dto.AIRecommendationRes; import com.api.mov.domain.recommendation.web.dto.AISurveyRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -11,12 +14,17 @@ import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + @Slf4j @Service @RequiredArgsConstructor public class AIRecommendationService { private final RestTemplate restTemplate; + private final PassRepository passRepository; @Value("${fastapi.url:http://localhost:8000}") private String fastApiUrl; @@ -40,6 +48,11 @@ public AIRecommendationListRes getRecommendations(AISurveyRequest surveyRequest) log.info("FastAPI 추천 결과 수신: {} 개", response != null ? response.getTotalCount() : 0); + // Pass 데이터 조회해서 imageUrl 추가 + if (response != null && response.getRecommendations() != null) { + enrichWithImageUrls(response.getRecommendations()); + } + return response; } catch (Exception e) { @@ -47,4 +60,32 @@ public AIRecommendationListRes getRecommendations(AISurveyRequest surveyRequest) throw new RuntimeException("AI 추천 서비스 호출 실패: " + e.getMessage()); } } + + /** + * AI 추천 결과에 Pass의 imageUrl 추가 + */ + private void enrichWithImageUrls(List recommendations) { + // Pass ID 목록 추출 + List passIds = recommendations.stream() + .map(AIRecommendationRes::getPassId) + .collect(Collectors.toList()); + + // Pass 데이터 조회 + List passes = passRepository.findAllById(passIds); + + // Pass ID -> imageUrl 매핑 + Map imageUrlMap = passes.stream() + .collect(Collectors.toMap( + Pass::getId, + pass -> pass.getImageUrl() != null ? pass.getImageUrl() : "" + )); + + // 각 추천 결과에 imageUrl 설정 + for (AIRecommendationRes recommendation : recommendations) { + String imageUrl = imageUrlMap.getOrDefault(recommendation.getPassId(), ""); + recommendation.setImageUrl(imageUrl); + } + + log.info("추천 결과에 이미지 URL 추가 완료: {} 개", recommendations.size()); + } } diff --git a/src/main/java/com/api/mov/domain/recommendation/web/dto/AIRecommendationRes.java b/src/main/java/com/api/mov/domain/recommendation/web/dto/AIRecommendationRes.java index 3e69460..fe20f9a 100644 --- a/src/main/java/com/api/mov/domain/recommendation/web/dto/AIRecommendationRes.java +++ b/src/main/java/com/api/mov/domain/recommendation/web/dto/AIRecommendationRes.java @@ -11,6 +11,11 @@ @NoArgsConstructor @AllArgsConstructor public class AIRecommendationRes { + + // imageUrl setter (enrichment용) + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } @JsonProperty("pass_id") private Long passId; @@ -23,4 +28,7 @@ public class AIRecommendationRes { @JsonProperty("predicted_score") private Double predictedScore; + + @JsonProperty("image_url") + private String imageUrl; }