From 5f3bffa6549b7f4bdf1cd0a94128c4172bda1c20 Mon Sep 17 00:00:00 2001 From: yoonho Date: Mon, 5 Jan 2026 01:35:31 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[#15]=20chore:=20.gitkeep=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/earseo/sight/controller/.gitkeep | 0 src/main/java/com/earseo/sight/dto/request/.gitkeep | 0 src/main/java/com/earseo/sight/dto/response/.gitkeep | 0 src/main/java/com/earseo/sight/entity/.gitkeep | 0 src/main/java/com/earseo/sight/repository/.gitkeep | 0 src/main/java/com/earseo/sight/service/.gitkeep | 0 6 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/main/java/com/earseo/sight/controller/.gitkeep delete mode 100644 src/main/java/com/earseo/sight/dto/request/.gitkeep delete mode 100644 src/main/java/com/earseo/sight/dto/response/.gitkeep delete mode 100644 src/main/java/com/earseo/sight/entity/.gitkeep delete mode 100644 src/main/java/com/earseo/sight/repository/.gitkeep delete mode 100644 src/main/java/com/earseo/sight/service/.gitkeep diff --git a/src/main/java/com/earseo/sight/controller/.gitkeep b/src/main/java/com/earseo/sight/controller/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/com/earseo/sight/dto/request/.gitkeep b/src/main/java/com/earseo/sight/dto/request/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/com/earseo/sight/dto/response/.gitkeep b/src/main/java/com/earseo/sight/dto/response/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/com/earseo/sight/entity/.gitkeep b/src/main/java/com/earseo/sight/entity/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/com/earseo/sight/repository/.gitkeep b/src/main/java/com/earseo/sight/repository/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/com/earseo/sight/service/.gitkeep b/src/main/java/com/earseo/sight/service/.gitkeep deleted file mode 100644 index e69de29..0000000 From c2127975a2205e89a6373da1e7e0565bd5964102 Mon Sep 17 00:00:00 2001 From: yoonho Date: Mon, 5 Jan 2026 01:48:49 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[#15]=20feat:=20=EC=9D=91=EB=8B=B5=20DTO=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20-=20theme,=20subtheme=20enum=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20-=20=EC=A7=80=EB=8F=84=EC=83=81=20=EA=B4=80?= =?UTF-8?q?=EA=B4=91=EC=A7=80=20=EC=A1=B0=ED=9A=8C=20theme=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80=20-=20=EC=9D=91=EB=8B=B5=20DTO?= =?UTF-8?q?=EC=97=90=EC=84=9C=20theme,=20subtheme=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=EB=90=98=EA=B2=8C=20code=20=ED=98=95?= =?UTF-8?q?=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B0=98=ED=99=98=ED=95=98?= =?UTF-8?q?=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sight/dto/internal/SightMetaResponse.java | 5 ++- .../sight/dto/projection/SightMapItemDto.java | 3 +- .../dto/response/CurationSightResponse.java | 7 ++-- .../dto/response/SearchSightResponse.java | 7 ++-- .../dto/response/SightDetailInfoResponse.java | 14 ++++--- .../sight/dto/response/SightInfoResponse.java | 4 ++ .../java/com/earseo/sight/entity/Sight.java | 6 ++- .../com/earseo/sight/entity/SubTheme.java | 42 +++++++++++++++++++ .../java/com/earseo/sight/entity/Theme.java | 19 +++++++++ .../sight/repository/SightRepository.java | 4 +- .../com/earseo/sight/service/InitService.java | 6 ++- .../earseo/sight/service/SightService.java | 3 ++ 12 files changed, 99 insertions(+), 21 deletions(-) create mode 100644 src/main/java/com/earseo/sight/entity/SubTheme.java create mode 100644 src/main/java/com/earseo/sight/entity/Theme.java diff --git a/src/main/java/com/earseo/sight/dto/internal/SightMetaResponse.java b/src/main/java/com/earseo/sight/dto/internal/SightMetaResponse.java index a93fd5c..fe2a55f 100644 --- a/src/main/java/com/earseo/sight/dto/internal/SightMetaResponse.java +++ b/src/main/java/com/earseo/sight/dto/internal/SightMetaResponse.java @@ -1,6 +1,7 @@ package com.earseo.sight.dto.internal; import com.earseo.sight.dto.projection.SightMetaDto; +import com.earseo.sight.entity.Theme; public record SightMetaResponse( String id, @@ -10,7 +11,7 @@ public record SightMetaResponse( Double latitude, Double longitude, String docentUrl, - String theme + Theme theme ) { public static SightMetaResponse toDto(SightMetaDto dto) { return new SightMetaResponse( @@ -21,7 +22,7 @@ public static SightMetaResponse toDto(SightMetaDto dto) { dto.mapY(), dto.mapX(), dto.docentUrl(), - dto.cat1() + Theme.valueOf(dto.cat1()) ); } } diff --git a/src/main/java/com/earseo/sight/dto/projection/SightMapItemDto.java b/src/main/java/com/earseo/sight/dto/projection/SightMapItemDto.java index 836d6a9..560b353 100644 --- a/src/main/java/com/earseo/sight/dto/projection/SightMapItemDto.java +++ b/src/main/java/com/earseo/sight/dto/projection/SightMapItemDto.java @@ -4,6 +4,7 @@ public record SightMapItemDto( String contentId, String title, Double mapX, - Double mapY + Double mapY, + String cat1 ) { } diff --git a/src/main/java/com/earseo/sight/dto/response/CurationSightResponse.java b/src/main/java/com/earseo/sight/dto/response/CurationSightResponse.java index 6316bb4..393ebe7 100644 --- a/src/main/java/com/earseo/sight/dto/response/CurationSightResponse.java +++ b/src/main/java/com/earseo/sight/dto/response/CurationSightResponse.java @@ -1,6 +1,7 @@ package com.earseo.sight.dto.response; import com.earseo.sight.dto.projection.CurationSightItemDto; +import com.earseo.sight.entity.SubTheme; import io.swagger.v3.oas.annotations.media.Schema; public record CurationSightResponse( @@ -10,8 +11,8 @@ public record CurationSightResponse( @Schema(description = "관광지 이름", example = "경복궁") String title, - @Schema(description = "관광지 테마 (예: 문화시설, 자연관광지 등)", example = "인문") - String theme, + @Schema(description = "관광지 하위 테마 (코드)", example = "CU01") + SubTheme subTheme, @Schema(description = "현재 위치로부터의 직선 거리 (미터)", example = "1234.56") Double distance, @@ -23,7 +24,7 @@ public static CurationSightResponse toDto(CurationSightItemDto dto) { return new CurationSightResponse( dto.contentId(), dto.title(), - dto.cat2(), + SubTheme.valueOf(dto.cat2()), dto.distance(), dto.addr3() ); diff --git a/src/main/java/com/earseo/sight/dto/response/SearchSightResponse.java b/src/main/java/com/earseo/sight/dto/response/SearchSightResponse.java index b589516..a44d0c8 100644 --- a/src/main/java/com/earseo/sight/dto/response/SearchSightResponse.java +++ b/src/main/java/com/earseo/sight/dto/response/SearchSightResponse.java @@ -1,6 +1,7 @@ package com.earseo.sight.dto.response; import com.earseo.sight.dto.projection.SearchSightItemDto; +import com.earseo.sight.entity.SubTheme; import io.swagger.v3.oas.annotations.media.Schema; public record SearchSightResponse( @@ -10,8 +11,8 @@ public record SearchSightResponse( @Schema(description = "관광지 이름", example = "경복궁") String title, - @Schema(description = "관광지 중분류", example = "체험관광지") - String detailTheme, + @Schema(description = "관광지 하위 분류 (코드)", example = "체험관광지") + SubTheme subTheme, @Schema(description = "주소 요약 (구/동 단위)", example = "서울 종로구") String address, @@ -29,7 +30,7 @@ public static SearchSightResponse toDto(SearchSightItemDto dto){ return new SearchSightResponse( dto.contentId(), dto.title(), - dto.cat2(), + SubTheme.valueOf(dto.cat2()), dto.addr3(), dto.mapX(), dto.mapY(), diff --git a/src/main/java/com/earseo/sight/dto/response/SightDetailInfoResponse.java b/src/main/java/com/earseo/sight/dto/response/SightDetailInfoResponse.java index 9bb5e0a..2b952fd 100644 --- a/src/main/java/com/earseo/sight/dto/response/SightDetailInfoResponse.java +++ b/src/main/java/com/earseo/sight/dto/response/SightDetailInfoResponse.java @@ -1,6 +1,8 @@ package com.earseo.sight.dto.response; import com.earseo.sight.dto.projection.SightDetailItemDto; +import com.earseo.sight.entity.SubTheme; +import com.earseo.sight.entity.Theme; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; @@ -9,11 +11,11 @@ public record SightDetailInfoResponse( @Schema(description = "관광지 고유 ID", example = "126508") String id, - @Schema(description = "관광지 대분류", example = "인문(문화/예술/역사)") - String theme, + @Schema(description = "관광지 분류 (코드)", example = "CU") + Theme theme, - @Schema(description = "관광지 중분류", example = "체험관광지") - String detailTheme, + @Schema(description = "관광지 하위 분류 (코드)", example = "CU01") + SubTheme subTheme, @Schema(description = "관광지 개요/설명", example = "조선시대 왕궁으로 500년 역사를 간직하고 있습니다") String outl, @@ -66,8 +68,8 @@ public record SightDetailInfoResponse( public static SightDetailInfoResponse toDto(SightDetailItemDto dto, List curationList) { return new SightDetailInfoResponse( dto.contentId(), - dto.cat1(), - dto.cat2(), + Theme.valueOf(dto.cat1()), + SubTheme.valueOf(dto.cat2()), dto.outl(), dto.title(), dto.addr1(), diff --git a/src/main/java/com/earseo/sight/dto/response/SightInfoResponse.java b/src/main/java/com/earseo/sight/dto/response/SightInfoResponse.java index bde1769..d01063f 100644 --- a/src/main/java/com/earseo/sight/dto/response/SightInfoResponse.java +++ b/src/main/java/com/earseo/sight/dto/response/SightInfoResponse.java @@ -1,5 +1,6 @@ package com.earseo.sight.dto.response; +import com.earseo.sight.entity.Theme; import io.swagger.v3.oas.annotations.media.Schema; public record SightInfoResponse( @@ -15,6 +16,9 @@ public record SightInfoResponse( @Schema(description = "위도 (Latitude, Y좌표)", example = "37.5796") Double latitude, + @Schema(description = "관광지 테마(코드)", example = "CU") + Theme theme, + @Schema(description = "이야기 스팟 조회용 GeoHash", example = "wydm6dqkm") String geoHash ) { diff --git a/src/main/java/com/earseo/sight/entity/Sight.java b/src/main/java/com/earseo/sight/entity/Sight.java index 58411aa..19af697 100644 --- a/src/main/java/com/earseo/sight/entity/Sight.java +++ b/src/main/java/com/earseo/sight/entity/Sight.java @@ -23,11 +23,13 @@ public class Sight { @Column(name = "content_type_id") private String contentTypeId; + @Enumerated(EnumType.STRING) @Column(name = "cat1") - private String cat1; + private Theme cat1; + @Enumerated(EnumType.STRING) @Column(name = "cat2") - private String cat2; + private SubTheme cat2; @Column(name = "cat3") private String cat3; diff --git a/src/main/java/com/earseo/sight/entity/SubTheme.java b/src/main/java/com/earseo/sight/entity/SubTheme.java new file mode 100644 index 0000000..6d10cb9 --- /dev/null +++ b/src/main/java/com/earseo/sight/entity/SubTheme.java @@ -0,0 +1,42 @@ +package com.earseo.sight.entity; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum SubTheme { + //자연 + NA01("자연관광지", "Natural Sites", Theme.NA), + NA02("관광자원", "Natural Resources", Theme.NA), + + //문화 + CU01("휴양관광지", "Recreational Sites", Theme.CU), + CU02("체험관광지", "Experience Programs", Theme.CU), + CU03("산업관광지", "Industrial Sites", Theme.CU), + CU04("문화시설", "Cultural Facilities", Theme.CU), + + //예술 + AR01("축제", "Festivals", Theme.AR), + AR02("공연/행사", "Events/Performances", Theme.AR), + + //역사 + HI01("역사관광지", "Historical Sites", Theme.HI), + HI02("건축/조형물", "Architectural Sights", Theme.HI), + + //레포츠 + LS01("레포츠소개", "Introduction", Theme.LS), + LS02("육상 레포츠", "Leisure/Sports (Land)", Theme.LS), + LS03("수상 레포츠", "Leisure/Sports (Water)", Theme.LS), + LS04("항공 레포츠", "Leisure/Sports (Sky)", Theme.LS), + LS05("복합 레포츠", "Leisure/Sports (Others)", Theme.LS), + + //쇼핑 + SH01("쇼핑", "Shopping", Theme.SH), + ; + + private final String koName; + private final String enName; + private final Theme theme; + +} diff --git a/src/main/java/com/earseo/sight/entity/Theme.java b/src/main/java/com/earseo/sight/entity/Theme.java new file mode 100644 index 0000000..272af26 --- /dev/null +++ b/src/main/java/com/earseo/sight/entity/Theme.java @@ -0,0 +1,19 @@ +package com.earseo.sight.entity; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum Theme { + NA("자연", "Nature"), + CU("문화", "Culture"), + AR("예술", "Art"), + HI("역사", "History"), + LS("레포츠", "Leisure/Sports"), + SH("쇼핑", "Shopping"), + ; + + private final String koName; + private final String enName; +} diff --git a/src/main/java/com/earseo/sight/repository/SightRepository.java b/src/main/java/com/earseo/sight/repository/SightRepository.java index 57ba163..6fc5651 100644 --- a/src/main/java/com/earseo/sight/repository/SightRepository.java +++ b/src/main/java/com/earseo/sight/repository/SightRepository.java @@ -11,7 +11,7 @@ public interface SightRepository extends JpaRepository { @Query(value = """ - SELECT s.content_id, s.title, s.map_x, s.map_y + SELECT s.content_id, s.title, s.map_x, s.map_y, s.cat1 FROM sight s WHERE ST_Intersects( s.geom, @@ -26,7 +26,7 @@ List findByRectangle( ); @Query(value = """ - SELECT s.content_id, s.title, s.map_x, s.map_y + SELECT s.content_id, s.title, s.map_x, s.map_y, s.cat1 FROM sight s WHERE ST_DWithin( s.geom::geography, diff --git a/src/main/java/com/earseo/sight/service/InitService.java b/src/main/java/com/earseo/sight/service/InitService.java index d4e07a6..1ed63cc 100644 --- a/src/main/java/com/earseo/sight/service/InitService.java +++ b/src/main/java/com/earseo/sight/service/InitService.java @@ -4,6 +4,8 @@ import com.earseo.sight.dto.etl.SightItemDto; import com.earseo.sight.entity.Docent; import com.earseo.sight.entity.Sight; +import com.earseo.sight.entity.SubTheme; +import com.earseo.sight.entity.Theme; import com.earseo.sight.repository.DocentRepository; import com.earseo.sight.repository.SightRepository; import com.fasterxml.jackson.core.type.TypeReference; @@ -91,8 +93,8 @@ private Sight convertSight(SightItemDto dto) { return Sight.builder(). contentId(dto.contentId()) .contentTypeId(dto.contentTypeId()) - .cat1(dto.cat1()) - .cat2(dto.cat2()) + .cat1(Theme.valueOf(dto.cat1())) + .cat2(SubTheme.valueOf(dto.cat2())) .cat3(dto.cat3()) .ocat1(dto.ocat1()) .ocat2(dto.ocat2()) diff --git a/src/main/java/com/earseo/sight/service/SightService.java b/src/main/java/com/earseo/sight/service/SightService.java index 5d2b7c2..ed30ab9 100644 --- a/src/main/java/com/earseo/sight/service/SightService.java +++ b/src/main/java/com/earseo/sight/service/SightService.java @@ -9,6 +9,7 @@ import com.earseo.sight.dto.response.*; import com.earseo.sight.entity.Curation; import com.earseo.sight.entity.Docent; +import com.earseo.sight.entity.Theme; import com.earseo.sight.repository.CurationRepository; import com.earseo.sight.repository.DocentRepository; import com.earseo.sight.repository.SightRepository; @@ -39,6 +40,7 @@ public SightMapInfoList getMapRectangle(Double minLongitude, Double minLatitude, item.title(), item.mapX(), item.mapY(), + Theme.valueOf(item.cat1()), getGeoHash(item.mapX(), item.mapY())) ).toList(); @@ -55,6 +57,7 @@ public SightMapInfoList getMapCircle(Double meters, Double longitude, Double lat item.title(), item.mapX(), item.mapY(), + Theme.valueOf(item.cat1()), getGeoHash(item.mapX(), item.mapY())) ).toList();