diff --git a/src/main/java/com/tripmate/api/domain/spot/SpotType.java b/src/main/java/com/tripmate/api/domain/spot/SpotType.java index 1b3d427..47f8b4b 100644 --- a/src/main/java/com/tripmate/api/domain/spot/SpotType.java +++ b/src/main/java/com/tripmate/api/domain/spot/SpotType.java @@ -1,5 +1,6 @@ package com.tripmate.api.domain.spot; +import com.tripmate.integration.tourapi.domain.SpotContentType; import com.tripmate.integration.tourapi.domain.SpotMediumCategory; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -10,29 +11,71 @@ @RequiredArgsConstructor public enum SpotType { - EXPERIENCE("체험", "12", EnumSet.of(SpotMediumCategory.A0203, SpotMediumCategory.A0102)), - CULTURE_AND_ART("문화예술", "14", EnumSet.of(SpotMediumCategory.A0206)), - FESTIVAL_AND_PERFORMANCE("축제∙공연", "15", EnumSet.of(SpotMediumCategory.A0207, SpotMediumCategory.A0208)), - NATURE_AND_REST("자연∙휴양", "12", EnumSet.of( - SpotMediumCategory.A0101, SpotMediumCategory.A0102, SpotMediumCategory.A0202 - )), - TRIP_ITINERARY("여행코스", "25", EnumSet.of( - SpotMediumCategory.C0112, SpotMediumCategory.C0113, SpotMediumCategory.C0114, - SpotMediumCategory.C0115, SpotMediumCategory.C0116, SpotMediumCategory.C0117 - )), - HISTORY("역사", "12", EnumSet.of(SpotMediumCategory.A0201, SpotMediumCategory.A0205)), - LEISURE_SPORTS("레포츠", "28", EnumSet.of( - SpotMediumCategory.A0301, SpotMediumCategory.A0302, SpotMediumCategory.A0303, - SpotMediumCategory.A0304, SpotMediumCategory.A0305 - )), - ACCOMMODATION("숙박", "32", EnumSet.of(SpotMediumCategory.B0201)), - SHOPPING("쇼핑", "38", EnumSet.of(SpotMediumCategory.A0401)), - RESTAURANT_AND_CAFE("맛집∙카페", "39", EnumSet.of(SpotMediumCategory.A0502)), - UNKNOWN("알수없음", "00", EnumSet.noneOf(SpotMediumCategory.class)); + EXPERIENCE( + "체험", + SpotContentType.TOURIST_ATTRACTIVENESS, + EnumSet.of(SpotMediumCategory.A0203, SpotMediumCategory.A0102) + ), + CULTURE_AND_ART( + "문화예술", + SpotContentType.CULTURAL_FACILITY, + EnumSet.of(SpotMediumCategory.A0206) + ), + FESTIVAL_AND_PERFORMANCE( + "축제∙공연", + SpotContentType.FESTIVAL_AND_PERFORMANCE, + EnumSet.of(SpotMediumCategory.A0207, SpotMediumCategory.A0208) + ), + NATURE_AND_REST( + "자연∙휴양", + SpotContentType.TOURIST_ATTRACTIVENESS, + EnumSet.of(SpotMediumCategory.A0101, SpotMediumCategory.A0102, SpotMediumCategory.A0202) + ), + TRIP_ITINERARY( + "여행코스", + SpotContentType.TRIP_ITINERARY, + EnumSet.of( + SpotMediumCategory.C0112, SpotMediumCategory.C0113, SpotMediumCategory.C0114, + SpotMediumCategory.C0115, SpotMediumCategory.C0116, SpotMediumCategory.C0117 + ) + ), + HISTORY( + "역사", + SpotContentType.TOURIST_ATTRACTIVENESS, + EnumSet.of(SpotMediumCategory.A0201, SpotMediumCategory.A0205) + ), + LEISURE_SPORTS( + "레포츠", + SpotContentType.LEISURE_SPORTS, + EnumSet.of( + SpotMediumCategory.A0301, SpotMediumCategory.A0302, SpotMediumCategory.A0303, + SpotMediumCategory.A0304, SpotMediumCategory.A0305 + ) + ), + ACCOMMODATION( + "숙박", + SpotContentType.ACCOMMODATION, + EnumSet.of(SpotMediumCategory.B0201) + ), + SHOPPING( + "쇼핑", + SpotContentType.SHOPPING, + EnumSet.of(SpotMediumCategory.A0401) + ), + RESTAURANT_AND_CAFE( + "맛집∙카페", + SpotContentType.FOOD, + EnumSet.of(SpotMediumCategory.A0502) + ), + UNKNOWN( + "알수없음", + null, + EnumSet.noneOf(SpotMediumCategory.class) + ); private final String typeName; - private final String tourApiContentTypeId; + private final SpotContentType tourApiContentType; private final EnumSet tourApiCategorySet; diff --git a/src/main/java/com/tripmate/api/dto/spot/LocationBasedSpotInfo.java b/src/main/java/com/tripmate/api/dto/spot/LocationBasedSpotInfo.java index f8e389c..f8a505f 100644 --- a/src/main/java/com/tripmate/api/dto/spot/LocationBasedSpotInfo.java +++ b/src/main/java/com/tripmate/api/dto/spot/LocationBasedSpotInfo.java @@ -6,6 +6,7 @@ import com.tripmate.api.domain.spot.SpotType; import com.tripmate.integration.tourapi.domain.SpotMediumCategory; import com.tripmate.integration.tourapi.dto.response.LocationBasedSpotItem; +import com.tripmate.integration.tourapi.dto.response.SpotCommonInfo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; @@ -39,27 +40,27 @@ public record LocationBasedSpotInfo( boolean companionYn ) { - public static LocationBasedSpotInfo fromLocationBasedSpotItem(LocationBasedSpotItem from) { - SpotMediumCategory mediumCategory = from.cat2(); + public static LocationBasedSpotInfo toLocationBasedSpotInfo(LocationBasedSpotItem from1, SpotCommonInfo from2) { + SpotMediumCategory mediumCategory = from1.cat2(); SpotType spotType = SpotType.fromTourApiCategory(mediumCategory); return LocationBasedSpotInfo.builder() - .spotId(from.contentId()) - .title(from.title()) + .spotId(from1.contentId()) + .title(from1.title()) // TODO: 세부 사항 주기 - .description("Tripmate API에서 지원 예정 내용입니다.") - .distance(from.dist()) - .thumbnailUrl(from.firstImage2()) + .description(from2.overview()) + .distance(from1.dist()) + .thumbnailUrl(from1.firstImage()) .location(new Location( - from.mapY(), - from.mapX(), - new Address(from.addr1(), from.addr2()) + from1.mapY(), + from1.mapX(), + new Address(from1.addr1(), from1.addr2()) )) .spotType(spotType) .category(new SpotCategory( - from.cat1(), + from1.cat1(), mediumCategory.getCategoryName(), - from.cat3().getCategoryName() + from1.cat3().getCategoryName() )) // TODO: 동행 여부 확인 필요 .companionYn(false) diff --git a/src/main/java/com/tripmate/api/service/LocationBasedSpotSearchService.java b/src/main/java/com/tripmate/api/service/LocationBasedSpotSearchService.java index acc3461..a87427a 100644 --- a/src/main/java/com/tripmate/api/service/LocationBasedSpotSearchService.java +++ b/src/main/java/com/tripmate/api/service/LocationBasedSpotSearchService.java @@ -1,8 +1,11 @@ package com.tripmate.api.service; +import com.tripmate.api.domain.spot.SpotType; import com.tripmate.api.dto.request.LocationBasedSpotSearchRequest; import com.tripmate.api.dto.spot.LocationBasedSpotInfo; +import com.tripmate.integration.tourapi.domain.SpotContentType; import com.tripmate.integration.tourapi.dto.response.LocationBasedSpotApiResponse; +import com.tripmate.integration.tourapi.dto.response.SpotCommonInfo; import com.tripmate.integration.tourapi.service.TourApiService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -16,14 +19,23 @@ public class LocationBasedSpotSearchService { private final TourApiService tourApiService; public List searchLocationBasedSpots(LocationBasedSpotSearchRequest request) { + SpotType spotType = request.spotType(); + SpotContentType tourApiContentType = (spotType != null) ? spotType.getTourApiContentType() : null; + LocationBasedSpotApiResponse response = tourApiService.findSpotsByLocation( request.latitude(), request.longitude(), - request.range() + request.range(), + tourApiContentType ); return response.spotItems().stream() - .map(LocationBasedSpotInfo::fromLocationBasedSpotItem) + .parallel() + .map(item -> { + SpotCommonInfo commonInfo = tourApiService.getSpotDetailInfo(item.contentId()); + return LocationBasedSpotInfo.toLocationBasedSpotInfo(item, commonInfo); + }) + .filter(item -> spotType == null || item.spotType().equals(spotType)) .toList(); } } diff --git a/src/main/java/com/tripmate/integration/tourapi/domain/SpotContentType.java b/src/main/java/com/tripmate/integration/tourapi/domain/SpotContentType.java new file mode 100644 index 0000000..8142086 --- /dev/null +++ b/src/main/java/com/tripmate/integration/tourapi/domain/SpotContentType.java @@ -0,0 +1,22 @@ +package com.tripmate.integration.tourapi.domain; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum SpotContentType { + + TOURIST_ATTRACTIVENESS("12", "관광지"), + CULTURAL_FACILITY("14", "문화시설"), + FESTIVAL_AND_PERFORMANCE("15", "축제/공연/행사"), + TRIP_ITINERARY("25", "여행코스"), + LEISURE_SPORTS("28", "레포츠"), + ACCOMMODATION("32", "숙박"), + SHOPPING("38", "쇼핑"), + FOOD("39", "음식"); + + private final String contentId; + + private final String name; +} diff --git a/src/main/java/com/tripmate/integration/tourapi/domain/SpotMediumCategory.java b/src/main/java/com/tripmate/integration/tourapi/domain/SpotMediumCategory.java index 0c51b06..e34965d 100644 --- a/src/main/java/com/tripmate/integration/tourapi/domain/SpotMediumCategory.java +++ b/src/main/java/com/tripmate/integration/tourapi/domain/SpotMediumCategory.java @@ -30,7 +30,7 @@ public enum SpotMediumCategory { B0201("숙박시설"), A0401("쇼핑"), A0502("음식"), - UNKNOWN("알려지지 않은 여행지"); + UNKNOWN("기타"); private final String categoryName; diff --git a/src/main/java/com/tripmate/integration/tourapi/service/TourApiService.java b/src/main/java/com/tripmate/integration/tourapi/service/TourApiService.java index 0234a3d..c470258 100644 --- a/src/main/java/com/tripmate/integration/tourapi/service/TourApiService.java +++ b/src/main/java/com/tripmate/integration/tourapi/service/TourApiService.java @@ -1,6 +1,7 @@ package com.tripmate.integration.tourapi.service; import com.tripmate.integration.tourapi.TourApiRestClient; +import com.tripmate.integration.tourapi.domain.SpotContentType; import com.tripmate.integration.tourapi.dto.request.TourApiRequestPath; import com.tripmate.integration.tourapi.dto.response.LocationBasedSpotApiResponse; import com.tripmate.integration.tourapi.dto.response.SpotCommonInfo; @@ -10,13 +11,26 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import java.util.Objects; + @RequiredArgsConstructor public class TourApiService { private final TourApiRestClient tourApiRestClient; public LocationBasedSpotApiResponse findSpotsByLocation(String latitude, String longitude, String range) { + return findSpotsByLocation(latitude, longitude, range, null); + } + + public LocationBasedSpotApiResponse findSpotsByLocation( + String latitude, String longitude, String range, SpotContentType spotContentType + ) { MultiValueMap queryParams = new LinkedMultiValueMap<>(); + + if (spotContentType != null) { + queryParams.add("contentTypeId", spotContentType.getContentId()); + } + queryParams.add("mapX", longitude); queryParams.add("mapY", latitude); queryParams.add("radius", range); @@ -47,6 +61,6 @@ public SpotCommonInfo getSpotDetailInfo(Long spotId) { queryParams ); - return response.getBody().spotItems().getFirst(); + return Objects.requireNonNull(response.getBody()).spotItems().getFirst(); } }