Fix : 수정
This commit is contained in:
parent
4f173d2982
commit
a13ca2e4be
@ -1,41 +1,20 @@
|
||||
package com.ktds.hi.recommend.biz.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 추천 히스토리 도메인 클래스
|
||||
* 사용자의 추천 기록을 담는 도메인 객체
|
||||
*/
|
||||
@Getter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class RecommendHistory {
|
||||
|
||||
private Long id;
|
||||
private Long memberId;
|
||||
private List<Long> recommendedStoreIds;
|
||||
private RecommendType recommendType;
|
||||
private String criteria;
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
/**
|
||||
* 추천 기준 업데이트
|
||||
*/
|
||||
public RecommendHistory updateCriteria(String newCriteria) {
|
||||
return RecommendHistory.builder()
|
||||
.id(this.id)
|
||||
.memberId(this.memberId)
|
||||
.recommendedStoreIds(this.recommendedStoreIds)
|
||||
.recommendType(this.recommendType)
|
||||
.criteria(newCriteria)
|
||||
.createdAt(this.createdAt)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
private Long storeId;
|
||||
private String recommendType;
|
||||
private Double score;
|
||||
private String reason;
|
||||
private LocalDateTime recommendedAt;
|
||||
private Boolean clicked;
|
||||
private Boolean visited;
|
||||
}
|
||||
@ -1,69 +1,24 @@
|
||||
package com.ktds.hi.recommend.biz.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 추천 매장 도메인 클래스
|
||||
* 추천된 매장 정보를 담는 도메인 객체
|
||||
*/
|
||||
@Getter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class RecommendStore {
|
||||
|
||||
private Long storeId;
|
||||
private String storeName;
|
||||
private String address;
|
||||
private String category;
|
||||
private List<String> tags;
|
||||
private Double latitude;
|
||||
private Double longitude;
|
||||
private Double rating;
|
||||
private Integer reviewCount;
|
||||
private Double distance;
|
||||
private Double recommendScore;
|
||||
private RecommendType recommendType;
|
||||
private List<String> tags;
|
||||
private String recommendReason;
|
||||
|
||||
/**
|
||||
* 추천 점수 업데이트
|
||||
*/
|
||||
public RecommendStore updateRecommendScore(Double newScore) {
|
||||
return RecommendStore.builder()
|
||||
.storeId(this.storeId)
|
||||
.storeName(this.storeName)
|
||||
.address(this.address)
|
||||
.category(this.category)
|
||||
.tags(this.tags)
|
||||
.rating(this.rating)
|
||||
.reviewCount(this.reviewCount)
|
||||
.distance(this.distance)
|
||||
.recommendScore(newScore)
|
||||
.recommendType(this.recommendType)
|
||||
.recommendReason(this.recommendReason)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 추천 이유 업데이트
|
||||
*/
|
||||
public RecommendStore updateRecommendReason(String newReason) {
|
||||
return RecommendStore.builder()
|
||||
.storeId(this.storeId)
|
||||
.storeName(this.storeName)
|
||||
.address(this.address)
|
||||
.category(this.category)
|
||||
.tags(this.tags)
|
||||
.rating(this.rating)
|
||||
.reviewCount(this.reviewCount)
|
||||
.distance(this.distance)
|
||||
.recommendScore(this.recommendScore)
|
||||
.recommendType(this.recommendType)
|
||||
.recommendReason(newReason)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
private Double recommendScore;
|
||||
private Double distance;
|
||||
private String priceRange;
|
||||
}
|
||||
@ -1,52 +1,20 @@
|
||||
package com.ktds.hi.recommend.biz.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 취향 프로필 도메인 클래스
|
||||
* 사용자의 취향 분석 결과를 담는 도메인 객체
|
||||
*/
|
||||
@Getter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TasteProfile {
|
||||
|
||||
private Long id;
|
||||
private Long memberId;
|
||||
private List<TasteCategory> preferredCategories;
|
||||
private Map<String, Double> categoryScores;
|
||||
private List<String> preferredTags;
|
||||
private Map<String, Object> behaviorPatterns;
|
||||
private Double pricePreference;
|
||||
private Double distancePreference;
|
||||
private List<String> cuisinePreferences;
|
||||
private String priceRange;
|
||||
private Integer distancePreference;
|
||||
private List<String> tasteTags;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
/**
|
||||
* 취향 프로필 업데이트
|
||||
*/
|
||||
public TasteProfile updateProfile(List<TasteCategory> categories, Map<String, Double> scores,
|
||||
List<String> tags, Map<String, Object> patterns,
|
||||
Double pricePreference, Double distancePreference) {
|
||||
return TasteProfile.builder()
|
||||
.id(this.id)
|
||||
.memberId(this.memberId)
|
||||
.preferredCategories(categories)
|
||||
.categoryScores(scores)
|
||||
.preferredTags(tags)
|
||||
.behaviorPatterns(patterns)
|
||||
.pricePreference(pricePreference)
|
||||
.distancePreference(distancePreference)
|
||||
.createdAt(this.createdAt)
|
||||
.updatedAt(LocalDateTime.now())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,28 +1,18 @@
|
||||
package com.ktds.hi.recommend.biz.usecase.out;
|
||||
|
||||
import com.ktds.hi.recommend.biz.domain.RecommendStore;
|
||||
import com.ktds.hi.recommend.biz.domain.TasteProfile;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* AI 추천 리포지토리 인터페이스
|
||||
* AI 기반 추천 기능을 정의
|
||||
*/
|
||||
public interface AiRecommendRepository {
|
||||
|
||||
/**
|
||||
* AI 기반 매장 추천
|
||||
*/
|
||||
|
||||
List<RecommendStore> recommendStoresByAI(Long memberId, Map<String, Object> preferences);
|
||||
|
||||
/**
|
||||
* 유사 사용자 기반 추천
|
||||
*/
|
||||
List<RecommendStore> recommendStoresBySimilarUsers(Long memberId);
|
||||
|
||||
/**
|
||||
* 협업 필터링 추천
|
||||
*/
|
||||
List<RecommendStore> recommendStoresByCollaborativeFiltering(Long memberId);
|
||||
}
|
||||
|
||||
// 추가 필요한 메서드들
|
||||
List<RecommendStore> filterByPreferences(List<RecommendStore> stores, TasteProfile tasteProfile, String tags);
|
||||
String getStoreSummary(Long storeId);
|
||||
}
|
||||
@ -5,29 +5,12 @@ import com.ktds.hi.recommend.biz.domain.RecommendStore;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 위치 기반 서비스 리포지토리 인터페이스
|
||||
* 위치 정보 처리 기능을 정의
|
||||
*/
|
||||
public interface LocationRepository {
|
||||
|
||||
/**
|
||||
* 위치 정보 저장
|
||||
*/
|
||||
|
||||
Location saveLocation(Location location);
|
||||
|
||||
/**
|
||||
* 반경 내 매장 조회
|
||||
*/
|
||||
List<RecommendStore> findStoresWithinRadius(Double latitude, Double longitude, Integer radius);
|
||||
|
||||
/**
|
||||
* 거리 계산
|
||||
*/
|
||||
Double calculateDistance(Double lat1, Double lon1, Double lat2, Double lon2);
|
||||
|
||||
/**
|
||||
* 주소를 좌표로 변환
|
||||
*/
|
||||
Location geocodeAddress(String address);
|
||||
}
|
||||
|
||||
// 수정된 메서드명 (Controller에서 호출하는 것과 일치)
|
||||
List<RecommendStore> findStoresWithinDistance(Double latitude, Double longitude, Integer radius);
|
||||
}
|
||||
@ -1,34 +1,23 @@
|
||||
package com.ktds.hi.recommend.biz.usecase.out;
|
||||
|
||||
import com.ktds.hi.recommend.biz.domain.RecommendHistory;
|
||||
import com.ktds.hi.recommend.biz.domain.RecommendStore;
|
||||
import com.ktds.hi.recommend.biz.domain.TasteProfile;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 추천 리포지토리 인터페이스
|
||||
* 추천 관련 데이터 영속성 기능을 정의
|
||||
*/
|
||||
public interface RecommendRepository {
|
||||
|
||||
/**
|
||||
* 추천 히스토리 저장
|
||||
*/
|
||||
|
||||
// 기존 메서드들
|
||||
RecommendHistory saveRecommendHistory(RecommendHistory history);
|
||||
|
||||
/**
|
||||
* 회원 ID로 추천 히스토리 조회
|
||||
*/
|
||||
List<RecommendHistory> findRecommendHistoriesByMemberId(Long memberId);
|
||||
|
||||
/**
|
||||
* 취향 프로필 저장
|
||||
*/
|
||||
TasteProfile saveTasteProfile(TasteProfile profile);
|
||||
|
||||
/**
|
||||
* 회원 ID로 취향 프로필 조회
|
||||
*/
|
||||
Optional<TasteProfile> findTasteProfileByMemberId(Long memberId);
|
||||
}
|
||||
|
||||
// 추가로 필요한 메서드들
|
||||
Optional<RecommendStore> findStoreById(Long storeId);
|
||||
List<RecommendStore> findPopularStores(String category, Integer limit);
|
||||
void logStoreClick(Long memberId, Long storeId);
|
||||
void logRecommendation(Long memberId, List<Long> storeIds, String context);
|
||||
}
|
||||
@ -6,29 +6,10 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 사용자 선호도 리포지토리 인터페이스
|
||||
* 사용자 취향 데이터 처리 기능을 정의
|
||||
*/
|
||||
public interface UserPreferenceRepository {
|
||||
|
||||
/**
|
||||
* 회원 취향 정보 조회
|
||||
*/
|
||||
|
||||
Optional<TasteProfile> getMemberPreferences(Long memberId);
|
||||
|
||||
/**
|
||||
* 회원의 리뷰 기반 취향 분석
|
||||
*/
|
||||
Map<String, Object> analyzePreferencesFromReviews(Long memberId);
|
||||
|
||||
/**
|
||||
* 유사한 취향의 사용자 조회
|
||||
*/
|
||||
List<Long> findSimilarTasteMembers(Long memberId);
|
||||
|
||||
/**
|
||||
* 취향 프로필 업데이트
|
||||
*/
|
||||
TasteProfile updateTasteProfile(Long memberId, Map<String, Object> analysisData);
|
||||
}
|
||||
}
|
||||
@ -1,47 +1,29 @@
|
||||
package com.ktds.hi.recommend.infra.dto.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.*;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 매장 추천 요청 DTO
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@Schema(description = "매장 추천 요청")
|
||||
public class RecommendStoreRequest {
|
||||
|
||||
@NotNull(message = "위도는 필수입니다")
|
||||
@DecimalMin(value = "-90.0", message = "위도는 -90도 이상이어야 합니다")
|
||||
@DecimalMax(value = "90.0", message = "위도는 90도 이하여야 합니다")
|
||||
@Schema(description = "위도", example = "37.5665")
|
||||
@NotNull
|
||||
@Schema(description = "위도", example = "37.5665", required = true)
|
||||
private Double latitude;
|
||||
|
||||
@NotNull(message = "경도는 필수입니다")
|
||||
@DecimalMin(value = "-180.0", message = "경도는 -180도 이상이어야 합니다")
|
||||
@DecimalMax(value = "180.0", message = "경도는 180도 이하여야 합니다")
|
||||
@Schema(description = "경도", example = "126.9780")
|
||||
@NotNull
|
||||
@Schema(description = "경도", example = "126.9780", required = true)
|
||||
private Double longitude;
|
||||
|
||||
@Min(value = 100, message = "반경은 최소 100m 이상이어야 합니다")
|
||||
@Max(value = 50000, message = "반경은 최대 50km 이하여야 합니다")
|
||||
@Schema(description = "검색 반경 (미터)", example = "5000")
|
||||
private Integer radius = 5000;
|
||||
@Schema(description = "반경(미터)", example = "3000", defaultValue = "3000")
|
||||
private Integer radius = 3000;
|
||||
|
||||
@Schema(description = "카테고리 필터", example = "한식")
|
||||
@Schema(description = "선택된 태그들 (콤마 구분)", example = "매운맛,혼밥")
|
||||
private String tags;
|
||||
|
||||
@Schema(description = "카테고리", example = "한식")
|
||||
private String category;
|
||||
|
||||
@Schema(description = "취향 태그 목록", example = "[\"매운맛\", \"혼밥\"]")
|
||||
private List<String> tags;
|
||||
|
||||
@Min(value = 1, message = "최소 1개 이상의 결과가 필요합니다")
|
||||
@Max(value = 50, message = "최대 50개까지 조회 가능합니다")
|
||||
@Schema(description = "결과 개수", example = "10")
|
||||
private Integer limit = 10;
|
||||
}
|
||||
@ -6,9 +6,6 @@ import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 매장 상세 정보 응답 DTO
|
||||
*/
|
||||
@Getter
|
||||
@Builder
|
||||
@Schema(description = "매장 상세 정보 응답")
|
||||
@ -29,54 +26,15 @@ public class StoreDetailResponse {
|
||||
@Schema(description = "평점", example = "4.5")
|
||||
private Double rating;
|
||||
|
||||
@Schema(description = "리뷰 수", example = "256")
|
||||
private Integer reviewCount;
|
||||
|
||||
@Schema(description = "거리(미터)", example = "500")
|
||||
private Integer distance;
|
||||
|
||||
@Schema(description = "태그 목록", example = "[\"맛집\", \"혼밥\", \"가성비\"]")
|
||||
private List<String> tags;
|
||||
|
||||
@Schema(description = "매장 이미지 URL 목록")
|
||||
private List<String> images;
|
||||
|
||||
@Schema(description = "매장 설명")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "개인화된 추천 이유", example = "당신이 좋아하는 '매운맛' 특성을 가진 매장입니다")
|
||||
private String personalizedReason;
|
||||
|
||||
@Schema(description = "AI 요약", example = "고객들이 매운맛과 친절한 서비스를 칭찬하는 매장입니다")
|
||||
private String aiSummary;
|
||||
|
||||
@Schema(description = "운영 시간")
|
||||
private String operatingHours;
|
||||
|
||||
@Schema(description = "전화번호")
|
||||
private String phoneNumber;
|
||||
|
||||
@Schema(description = "메뉴 정보")
|
||||
private List<MenuInfo> menuList;
|
||||
|
||||
/**
|
||||
* 메뉴 정보 내부 클래스
|
||||
*/
|
||||
@Getter
|
||||
@Builder
|
||||
@Schema(description = "메뉴 정보")
|
||||
public static class MenuInfo {
|
||||
|
||||
@Schema(description = "메뉴명", example = "김치찌개")
|
||||
private String menuName;
|
||||
|
||||
@Schema(description = "가격", example = "8000")
|
||||
private Integer price;
|
||||
|
||||
@Schema(description = "메뉴 설명", example = "매콤한 김치찌개")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "인기 메뉴 여부", example = "true")
|
||||
private Boolean isPopular;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user