From bf65ff58fbccf072706d00e8687b395dcaf06b7f Mon Sep 17 00:00:00 2001 From: yujin Date: Fri, 16 Feb 2024 12:11:27 +0900 Subject: [PATCH 1/6] =?UTF-8?q?Feat:=20`=EC=8A=A4=EB=A7=88=ED=8A=B8=20?= =?UTF-8?q?=EC=84=9C=EC=9A=B8=EB=A7=B5`=20=EC=BD=98=ED=85=90=EC=B8=A0=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20DB=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ecolink/core/CoreApplication.java | 2 + .../map/controller/StoreMapController.java | 36 +++++ .../java/com/ecolink/core/map/domain/Map.java | 35 +++++ .../ecolink/core/map/domain/MapContent.java | 113 ++++++++++++++ .../core/map/dto/ContentDetailDto.java | 138 ++++++++++++++++++ .../ecolink/core/map/dto/ContentItemDto.java | 31 ++++ .../core/map/dto/ContentListDetailDto.java | 23 +++ .../ecolink/core/map/dto/ContentListDto.java | 23 +++ .../repository/ContentDetailRepository.java | 9 ++ .../map/repository/ContentListRepository.java | 10 ++ .../map/service/ContentDetailService.java | 89 +++++++++++ .../core/map/service/ContentListService.java | 68 +++++++++ .../core/map/util/ContentDetailFetcher.java | 54 +++++++ .../core/map/util/ContentListFetcher.java | 41 ++++++ src/main/resources/application-swagger.yml | 1 + 15 files changed, 673 insertions(+) create mode 100644 src/main/java/com/ecolink/core/map/controller/StoreMapController.java create mode 100644 src/main/java/com/ecolink/core/map/domain/Map.java create mode 100644 src/main/java/com/ecolink/core/map/domain/MapContent.java create mode 100644 src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java create mode 100644 src/main/java/com/ecolink/core/map/dto/ContentItemDto.java create mode 100644 src/main/java/com/ecolink/core/map/dto/ContentListDetailDto.java create mode 100644 src/main/java/com/ecolink/core/map/dto/ContentListDto.java create mode 100644 src/main/java/com/ecolink/core/map/repository/ContentDetailRepository.java create mode 100644 src/main/java/com/ecolink/core/map/repository/ContentListRepository.java create mode 100644 src/main/java/com/ecolink/core/map/service/ContentDetailService.java create mode 100644 src/main/java/com/ecolink/core/map/service/ContentListService.java create mode 100644 src/main/java/com/ecolink/core/map/util/ContentDetailFetcher.java create mode 100644 src/main/java/com/ecolink/core/map/util/ContentListFetcher.java diff --git a/src/main/java/com/ecolink/core/CoreApplication.java b/src/main/java/com/ecolink/core/CoreApplication.java index db0cd4a3..7c66fdf0 100644 --- a/src/main/java/com/ecolink/core/CoreApplication.java +++ b/src/main/java/com/ecolink/core/CoreApplication.java @@ -1,8 +1,10 @@ package com.ecolink.core; import org.springframework.boot.SpringApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.boot.autoconfigure.SpringBootApplication; +@EnableFeignClients @SpringBootApplication public class CoreApplication { diff --git a/src/main/java/com/ecolink/core/map/controller/StoreMapController.java b/src/main/java/com/ecolink/core/map/controller/StoreMapController.java new file mode 100644 index 00000000..a1986abf --- /dev/null +++ b/src/main/java/com/ecolink/core/map/controller/StoreMapController.java @@ -0,0 +1,36 @@ +package com.ecolink.core.map.controller; + +import com.ecolink.core.map.util.ContentDetailFetcher; +import com.ecolink.core.map.util.ContentListFetcher; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +@RestController +public class StoreMapController { + + private final ContentListFetcher contentListFetcher; + private final ContentDetailFetcher contentDetailFetcher; + public StoreMapController(ContentListFetcher contentListFetcher, ContentDetailFetcher contentDetailFetcher) { + this.contentListFetcher = contentListFetcher; + this.contentDetailFetcher = contentDetailFetcher; + } + + @Tag(name = "${swagger.map-data}") + @Operation(summary = "스마트서울맵 데이터 조회 API", description = "테마 내 모든 콘텐츠 리스트 API") + @GetMapping("/list") + public void getContentsListAll() { + contentListFetcher.fetchDataAndStore(); + + } + + @Tag(name = "${swagger.map-data}") + @Operation(summary = "스마트서울맵 데이터 조회 API", description = "테마 내 모든 콘텐츠 상세 정보 API") + @GetMapping("/data") + public void getContentsDetailAll() { + contentDetailFetcher.fetchAndStoreContentDetail(); + } + +} diff --git a/src/main/java/com/ecolink/core/map/domain/Map.java b/src/main/java/com/ecolink/core/map/domain/Map.java new file mode 100644 index 00000000..b5a66dea --- /dev/null +++ b/src/main/java/com/ecolink/core/map/domain/Map.java @@ -0,0 +1,35 @@ +package com.ecolink.core.map.domain; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import jakarta.persistence.*; + +import java.time.LocalDateTime; + +@Getter +@Setter +@NoArgsConstructor +@Entity +public class Map { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String mapThemeId; + private String mapContentId; + private String mapSubCategoryId; + private String mapContentStatus; + private LocalDateTime updateDate; + private LocalDateTime registrationDate; + + public Map(String mapThemeId, String mapContentId, String mapSubCategoryId, String mapContentStatus, LocalDateTime updateDate, LocalDateTime registrationDate) { + this.mapThemeId = mapThemeId; + this.mapContentId = mapContentId; + this.mapSubCategoryId = mapSubCategoryId; + this.mapContentStatus = mapContentStatus; + this.updateDate = updateDate; + this.registrationDate = registrationDate; + } +} \ No newline at end of file diff --git a/src/main/java/com/ecolink/core/map/domain/MapContent.java b/src/main/java/com/ecolink/core/map/domain/MapContent.java new file mode 100644 index 00000000..fab7a593 --- /dev/null +++ b/src/main/java/com/ecolink/core/map/domain/MapContent.java @@ -0,0 +1,113 @@ +package com.ecolink.core.map.domain; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import jakarta.persistence.*; + +@Getter +@Setter +@NoArgsConstructor +@Entity +public class MapContent { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String cotValue03; + private String cotValue04; + private String cotValue05; + private String cotValue06; + private String cotValue07; + private String cotAddrFullNew; + private String cotAddrFullOld; + private String cotTelNo; + private String cotRegDate; + private String cotUpdateDate; + private String cotThemeId; + private String cotContsId; + private String cotGuName; + private String cotDongName; + private String cotSanName; + private String cotMasterNo; + private String cotSlaveNo; + private String cotExtraName; + private String cotNationBaseArea; + private String cotNationPointNumber; + private String cotCoordData; + private String cotCoordType; + private String cotCoordX; + private String cotCoordY; + private String cotContsStat; + private String cotWriter; + private String cotThemeSubId; + private String cotExtraData01; + private String cotExtraData02; + private String cotMovieUrl; + private String cotVoiceUrl; + private String cotContsDetail; + private String cotImgMainUrl; + private String cotImgMainUrl2; + private String cotImgMainUrl3; + private String cotImgMainUrl4; + private String cotImgMainUrl5; + private String cotCoordStyle; + private String cotLinePattern; + private String cotLineWeight; + private String cotLineColor; + + public MapContent(String cotValue03, String cotValue04, String cotValue05, String cotValue06, String cotValue07, + String cotAddrFullNew, String cotAddrFullOld, String cotTelNo, String cotRegDate, String cotUpdateDate, + String cotThemeId, String cotContsId, String cotGuName, String cotDongName, String cotSanName, + String cotMasterNo, String cotSlaveNo, String cotExtraName, String cotNationBaseArea, + String cotNationPointNumber, String cotCoordData, String cotCoordType, String cotCoordX, + String cotCoordY, String cotContsStat, String cotWriter, String cotThemeSubId, String cotExtraData01, + String cotExtraData02, String cotMovieUrl, String cotVoiceUrl, String cotContsDetail, + String cotImgMainUrl, String cotImgMainUrl2, String cotImgMainUrl3, String cotImgMainUrl4, + String cotImgMainUrl5, String cotCoordStyle, String cotLinePattern, String cotLineWeight, + String cotLineColor) { + this.cotValue03 = cotValue03; + this.cotValue04 = cotValue04; + this.cotValue05 = cotValue05; + this.cotValue06 = cotValue06; + this.cotValue07 = cotValue07; + this.cotAddrFullNew = cotAddrFullNew; + this.cotAddrFullOld = cotAddrFullOld; + this.cotTelNo = cotTelNo; + this.cotRegDate = cotRegDate; + this.cotUpdateDate = cotUpdateDate; + this.cotThemeId = cotThemeId; + this.cotContsId = cotContsId; + this.cotGuName = cotGuName; + this.cotDongName = cotDongName; + this.cotSanName = cotSanName; + this.cotMasterNo = cotMasterNo; + this.cotSlaveNo = cotSlaveNo; + this.cotExtraName = cotExtraName; + this.cotNationBaseArea = cotNationBaseArea; + this.cotNationPointNumber = cotNationPointNumber; + this.cotCoordData = cotCoordData; + this.cotCoordType = cotCoordType; + this.cotCoordX = cotCoordX; + this.cotCoordY = cotCoordY; + this.cotContsStat = cotContsStat; + this.cotWriter = cotWriter; + this.cotThemeSubId = cotThemeSubId; + this.cotExtraData01 = cotExtraData01; + this.cotExtraData02 = cotExtraData02; + this.cotMovieUrl = cotMovieUrl; + this.cotVoiceUrl = cotVoiceUrl; + this.cotContsDetail = cotContsDetail; + this.cotImgMainUrl = cotImgMainUrl; + this.cotImgMainUrl2 = cotImgMainUrl2; + this.cotImgMainUrl3 = cotImgMainUrl3; + this.cotImgMainUrl4 = cotImgMainUrl4; + this.cotImgMainUrl5 = cotImgMainUrl5; + this.cotCoordStyle = cotCoordStyle; + this.cotLinePattern = cotLinePattern; + this.cotLineWeight = cotLineWeight; + this.cotLineColor = cotLineColor; + } + +} \ No newline at end of file diff --git a/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java b/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java new file mode 100644 index 00000000..d05b9baa --- /dev/null +++ b/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java @@ -0,0 +1,138 @@ +package com.ecolink.core.map.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@Getter +@Setter +@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class) +public class ContentDetailDto { + + @Schema(description = "운영시간", example = "매일 11:00-21:30/ 비건 베이커리만 화 휴무") + private String cotValue03; + + @Schema(description = "취급품목(메뉴)", example = "제로웨이스트 제품, 비건 식품, 리필 세제류, 비건베이커리") + private String cotValue04; + + @Schema(description = "인스타그램", example = "http://www.instagram.com/zerowaste_jigu") + private String cotValue05; + + @Schema(description = "제로페이", example = "가능") + private String cotValue06; + + @Schema(description = "인터넷 쇼핑몰", example = "https://smartstore.naver.com/peaceontable") + private String cotValue07; + + @Schema(description = "매장 주소 (새 주소)", example = "서울특별시 마포구 성미산로 155") + private String cotAddrFullNew; + + @Schema(description = "매장 주소 (구 주소)", example = "서울특별시 마포구 연남동 240-23") + private String cotAddrFullOld; + + @Schema(description = "전화번호", example = "070-7721-5748") + private String cotTelNo; + + @Schema(description = "등록일", example = "2023-10-31 10:04:59") + private String cotRegDate; + + @Schema(description = "업데이트 일", example = "2023-10-31 13:02:54") + private String cotUpdateDate; + + @Schema(description = "테마 ID", example = "11103395") + private String cotThemeId; + + @Schema(description = "콘텐츠 ID", example = "zerowaste_0004") + private String cotContsId; + + @Schema(description = "구명", example = "마포구") + private String cotGuName; + + @Schema(description = "동명", example = "") + private String cotDongName; + + @Schema(description = "산지 명", example = "") + private String cotSanName; + + @Schema(description = "주 번지", example = "") + private String cotMasterNo; + + @Schema(description = "부 번지", example = "") + private String cotSlaveNo; + + @Schema(description = "나머지 주소", example = "") + private String cotExtraName; + + @Schema(description = "국가 기초 구역", example = "03958") + private String cotNationBaseArea; + + @Schema(description = "국가 지점 번호", example = "다사49085184") + private String cotNationPointNumber; + + @Schema(description = "좌표 정보 (GeoJson)") + private String cotCoordData; + + @Schema(description = "콘텐츠 좌표 타입", example = "1") + private String cotCoordType; + + @Schema(description = "X 좌표", example = "126.923533416") + private String cotCoordX; + + @Schema(description = "Y 좌표", example = "37.564525958") + private String cotCoordY; + + @Schema(description = "사용 유무", example = "1") + private String cotContsStat; + + @Schema(description = "등록자/수정자", example = "motif77") + private String cotWriter; + + @Schema(description = "콘텐츠 서브카테고리", example = "4") + private String cotThemeSubId; + + @Schema(description = "기타 정보 1", example = "") + private String cotExtraData01; + + @Schema(description = "링크 URL", example = "https://www.jigushop.co.kr/") + private String cotExtraData02; + + @Schema(description = "동영상 URL", example = "") + private String cotMovieUrl; + + @Schema(description = "음성파일 URL", example = "") + private String cotVoiceUrl; + + @Schema(description = "콘텐츠 상세", example = "콘텐츠 상세 내용") + private String cotContsDetail; + + @Schema(description = "이미지 URL1") + private String cotImgMainUrl; + + @Schema(description = "이미지 URL2") + private String cotImgMainUrl2; + + @Schema(description = "이미지 URL3") + private String cotImgMainUrl3; + + @Schema(description = "이미지 URL4") + private String cotImgMainUrl4; + + @Schema(description = "이미지 URL5") + private String cotImgMainUrl5; + + @Schema(description = "코디네이트 스타일") + private String cotCoordStyle; + + @Schema(description = "라인 패턴", example = "L") + private String cotLinePattern; + + @Schema(description = "라인 무게", example = "4") + private String cotLineWeight; + + @Schema(description = "라인 색상", example = "#0000FF") + private String cotLineColor; + +} diff --git a/src/main/java/com/ecolink/core/map/dto/ContentItemDto.java b/src/main/java/com/ecolink/core/map/dto/ContentItemDto.java new file mode 100644 index 00000000..ad06f9e3 --- /dev/null +++ b/src/main/java/com/ecolink/core/map/dto/ContentItemDto.java @@ -0,0 +1,31 @@ +package com.ecolink.core.map.dto; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class) +public class ContentItemDto { + @Schema(description = "등록일", example = "2023-10-31 10:04:58.0") + private String cotRegDate; + + @Schema(description = "콘텐츠 테마 서브 ID", example = "4") + private String cotThemeSubId; + + @Schema(description = "업데이트 일", example = "2023-10-31 13:12:19.0") + private String cotUpdateDate; + + @Schema(description = "콘텐츠 테마 ID", example = "11103395") + private String cotThemeId; + + @Schema(description = "콘텐츠 ID", example = "zerowaste_0005") + private String cotContsId; + + @Schema(description = "콘텐츠 상태", example = "0") + private String cotContsStat; +} diff --git a/src/main/java/com/ecolink/core/map/dto/ContentListDetailDto.java b/src/main/java/com/ecolink/core/map/dto/ContentListDetailDto.java new file mode 100644 index 00000000..261fc889 --- /dev/null +++ b/src/main/java/com/ecolink/core/map/dto/ContentListDetailDto.java @@ -0,0 +1,23 @@ +package com.ecolink.core.map.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@Getter +@Setter +@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class) +public class ContentListDetailDto { + @Schema(description = "성공 오류 응답 코드", example = "0") + private String retCode; + + @Schema(description = "데이터 양", example = "99") + private int dataCount; + + @Schema(description = "콘텐츠 상세 정보") + private List body; +} \ No newline at end of file diff --git a/src/main/java/com/ecolink/core/map/dto/ContentListDto.java b/src/main/java/com/ecolink/core/map/dto/ContentListDto.java new file mode 100644 index 00000000..afb18c61 --- /dev/null +++ b/src/main/java/com/ecolink/core/map/dto/ContentListDto.java @@ -0,0 +1,23 @@ +package com.ecolink.core.map.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@Getter +@Setter +@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class) +public class ContentListDto { + @Schema(description = "성공 오류 응답 코드", example = "0") + private String retCode; + + @Schema(description = "데이터 양", example = "99") + private int dataCount; + + @Schema(description = "콘텐츠 리스트") + private List body; +} \ No newline at end of file diff --git a/src/main/java/com/ecolink/core/map/repository/ContentDetailRepository.java b/src/main/java/com/ecolink/core/map/repository/ContentDetailRepository.java new file mode 100644 index 00000000..8492ddcb --- /dev/null +++ b/src/main/java/com/ecolink/core/map/repository/ContentDetailRepository.java @@ -0,0 +1,9 @@ +package com.ecolink.core.map.repository; + +import com.ecolink.core.map.domain.MapContent; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ContentDetailRepository extends JpaRepository { +} diff --git a/src/main/java/com/ecolink/core/map/repository/ContentListRepository.java b/src/main/java/com/ecolink/core/map/repository/ContentListRepository.java new file mode 100644 index 00000000..3827147f --- /dev/null +++ b/src/main/java/com/ecolink/core/map/repository/ContentListRepository.java @@ -0,0 +1,10 @@ +package com.ecolink.core.map.repository; + +import com.ecolink.core.map.domain.Map; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ContentListRepository extends JpaRepository { + +} \ No newline at end of file diff --git a/src/main/java/com/ecolink/core/map/service/ContentDetailService.java b/src/main/java/com/ecolink/core/map/service/ContentDetailService.java new file mode 100644 index 00000000..e516b5d0 --- /dev/null +++ b/src/main/java/com/ecolink/core/map/service/ContentDetailService.java @@ -0,0 +1,89 @@ +package com.ecolink.core.map.service; + +import java.util.List; + +import com.ecolink.core.map.domain.MapContent; +import com.ecolink.core.map.dto.ContentDetailDto; +import com.ecolink.core.map.dto.ContentListDetailDto; +import com.ecolink.core.map.repository.ContentDetailRepository; +import com.ecolink.core.geo.service.GeometryService; +import com.ecolink.core.store.dto.request.MapQueryRequest; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class ContentDetailService { + + private final ContentDetailRepository contentDetailRepository; + private final ObjectMapper objectMapper; + private final GeometryService geometryService; + + public ContentDetailService(ContentDetailRepository contentDetailRepository, ObjectMapper objectMapper, GeometryService geometryService) { + this.contentDetailRepository = contentDetailRepository; + this.objectMapper = objectMapper; + this.geometryService = geometryService; + } + + public void saveContentDetail(String responseData) { + try { + ContentListDetailDto responseDTO = objectMapper.readValue(responseData, ContentListDetailDto.class); + List contentDetailList = responseDTO.getBody(); + + for (ContentDetailDto contentDetail : contentDetailList) { + MapContent mapContent = mapDetailToMapEntity(contentDetail); + contentDetailRepository.save(mapContent); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private MapContent mapDetailToMapEntity(ContentDetailDto contentDetailDto) { + MapContent mapContent = new MapContent(); + mapContent.setCotValue03(contentDetailDto.getCotValue03()); + mapContent.setCotValue04(contentDetailDto.getCotValue04()); + mapContent.setCotValue05(contentDetailDto.getCotValue05()); + mapContent.setCotValue06(contentDetailDto.getCotValue06()); + mapContent.setCotValue07(contentDetailDto.getCotValue07()); + mapContent.setCotAddrFullNew(contentDetailDto.getCotAddrFullNew()); + mapContent.setCotAddrFullOld(contentDetailDto.getCotAddrFullOld()); + mapContent.setCotTelNo(contentDetailDto.getCotTelNo()); + mapContent.setCotRegDate(contentDetailDto.getCotRegDate()); + mapContent.setCotUpdateDate(contentDetailDto.getCotUpdateDate()); + mapContent.setCotThemeId(contentDetailDto.getCotThemeId()); + mapContent.setCotContsId(contentDetailDto.getCotContsId()); + mapContent.setCotGuName(contentDetailDto.getCotGuName()); + mapContent.setCotDongName(contentDetailDto.getCotDongName()); + mapContent.setCotSanName(contentDetailDto.getCotSanName()); + mapContent.setCotMasterNo(contentDetailDto.getCotMasterNo()); + mapContent.setCotSlaveNo(contentDetailDto.getCotSlaveNo()); + mapContent.setCotExtraName(contentDetailDto.getCotExtraName()); + mapContent.setCotNationBaseArea(contentDetailDto.getCotNationBaseArea()); + mapContent.setCotNationPointNumber(contentDetailDto.getCotNationPointNumber()); + mapContent.setCotCoordData(contentDetailDto.getCotCoordData()); + mapContent.setCotCoordType(contentDetailDto.getCotCoordType()); + mapContent.setCotCoordX(contentDetailDto.getCotCoordX()); + mapContent.setCotCoordY(contentDetailDto.getCotCoordY()); + mapContent.setCotContsStat(contentDetailDto.getCotContsStat()); + mapContent.setCotWriter(contentDetailDto.getCotWriter()); + mapContent.setCotThemeSubId(contentDetailDto.getCotThemeSubId()); + mapContent.setCotExtraData01(contentDetailDto.getCotExtraData01()); + mapContent.setCotExtraData02(contentDetailDto.getCotExtraData02()); + mapContent.setCotMovieUrl(contentDetailDto.getCotMovieUrl()); + mapContent.setCotVoiceUrl(contentDetailDto.getCotVoiceUrl()); + mapContent.setCotContsDetail(contentDetailDto.getCotContsDetail()); + mapContent.setCotImgMainUrl(contentDetailDto.getCotImgMainUrl()); + mapContent.setCotImgMainUrl2(contentDetailDto.getCotImgMainUrl2()); + mapContent.setCotImgMainUrl3(contentDetailDto.getCotImgMainUrl3()); + mapContent.setCotImgMainUrl4(contentDetailDto.getCotImgMainUrl4()); + mapContent.setCotImgMainUrl5(contentDetailDto.getCotImgMainUrl5()); + mapContent.setCotCoordStyle(contentDetailDto.getCotCoordStyle()); + mapContent.setCotLinePattern(contentDetailDto.getCotLinePattern()); + mapContent.setCotLineWeight(contentDetailDto.getCotLineWeight()); + mapContent.setCotLineColor(contentDetailDto.getCotLineColor()); + + return mapContent; + } +} diff --git a/src/main/java/com/ecolink/core/map/service/ContentListService.java b/src/main/java/com/ecolink/core/map/service/ContentListService.java new file mode 100644 index 00000000..b8b803a8 --- /dev/null +++ b/src/main/java/com/ecolink/core/map/service/ContentListService.java @@ -0,0 +1,68 @@ +package com.ecolink.core.map.service; + +import com.ecolink.core.map.domain.Map; +import com.ecolink.core.map.dto.ContentItemDto; +import com.ecolink.core.map.dto.ContentListDto; +import com.ecolink.core.map.repository.ContentListRepository; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@Service +@Transactional +public class ContentListService { + + private final ContentListRepository contentListRepository; + private final ObjectMapper objectMapper; + + @Autowired + public ContentListService(ContentListRepository contentListRepository, ObjectMapper objectMapper) { + this.contentListRepository = contentListRepository; + this.objectMapper = objectMapper; + } + + public void saveContentsListAll(String responseData) { + try { + ContentListDto responseDTO = objectMapper.readValue(responseData, ContentListDto.class); + List contentList = responseDTO.getBody(); + + for (ContentItemDto contentItem : contentList) { + Map map = mapContentToMapEntity(contentItem); + contentListRepository.save(map); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public List getContentIds() { + List maps = contentListRepository.findAll(); + List contentIds = new ArrayList<>(); + for (Map map : maps) { + contentIds.add(map.getMapContentId()); + } + return contentIds; + } + + private Map mapContentToMapEntity(ContentItemDto contentItem) { + Map map = new Map(); + map.setMapThemeId(contentItem.getCotThemeId()); + map.setMapContentId(contentItem.getCotContsId()); + map.setMapSubCategoryId(contentItem.getCotThemeSubId()); + map.setMapContentStatus(contentItem.getCotContsStat()); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"); + LocalDateTime updateDate = LocalDateTime.parse(contentItem.getCotUpdateDate(), formatter); + LocalDateTime regDate = LocalDateTime.parse(contentItem.getCotRegDate(), formatter); + + map.setUpdateDate(updateDate); + map.setRegistrationDate(regDate); + return map; + } +} \ No newline at end of file diff --git a/src/main/java/com/ecolink/core/map/util/ContentDetailFetcher.java b/src/main/java/com/ecolink/core/map/util/ContentDetailFetcher.java new file mode 100644 index 00000000..5d3a3baa --- /dev/null +++ b/src/main/java/com/ecolink/core/map/util/ContentDetailFetcher.java @@ -0,0 +1,54 @@ +package com.ecolink.core.map.util; + +import java.util.List; + +import com.ecolink.core.map.service.ContentDetailService; +import com.ecolink.core.map.service.ContentListService; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class ContentDetailFetcher { + + private final ContentDetailService contentDetailService; + private final ContentListService contentListService; + + @Autowired + public ContentDetailFetcher(ContentDetailService contentDetailService, ContentListService contentListService) { + this.contentDetailService = contentDetailService; + this.contentListService = contentListService; + } + + public void fetchAndStoreContentDetail() { + List contentIds = contentListService.getContentIds(); + + HttpClient httpClient = HttpClients.createDefault(); + for (String contentId : contentIds) { + String url = + "https://map.seoul.go.kr/smgis/apps/poi.do?cmd=getNewContentsDetail&key=90d9ef047980430297ec7fa3a8377710&theme_id=11103395&conts_id=" + + contentId; + HttpGet httpGet = new HttpGet(url); + + try { + HttpResponse response = httpClient.execute(httpGet); + int statusCode = response.getStatusLine().getStatusCode(); + + if (statusCode == 200) { + String responseData = EntityUtils.toString(response.getEntity()); + + contentDetailService.saveContentDetail(responseData); + } else { + System.err.println( + "Failed to fetch data for content id: " + contentId + ", Status Code: " + statusCode); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/ecolink/core/map/util/ContentListFetcher.java b/src/main/java/com/ecolink/core/map/util/ContentListFetcher.java new file mode 100644 index 00000000..6f01df41 --- /dev/null +++ b/src/main/java/com/ecolink/core/map/util/ContentListFetcher.java @@ -0,0 +1,41 @@ +package com.ecolink.core.map.util; + +import com.ecolink.core.map.service.ContentListService; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class ContentListFetcher { + + private final ContentListService contentListService; + + @Autowired + public ContentListFetcher(ContentListService contentListService) { + this.contentListService = contentListService; + } + + public void fetchDataAndStore() { + HttpClient httpClient = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet("https://map.seoul.go.kr/smgis/apps/theme.do?cmd=getContentsListAll&key=90d9ef047980430297ec7fa3a8377710&theme_id=11103395"); + + try { + HttpResponse response = httpClient.execute(httpGet); + int statusCode = response.getStatusLine().getStatusCode(); + + if (statusCode == 200) { + String responseData = EntityUtils.toString(response.getEntity()); + + contentListService.saveContentsListAll(responseData); + } else { + System.err.println("Failed to fetch data, Status Code: " + statusCode); + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/resources/application-swagger.yml b/src/main/resources/application-swagger.yml index 60f9eabe..e5364322 100644 --- a/src/main/resources/application-swagger.yml +++ b/src/main/resources/application-swagger.yml @@ -11,3 +11,4 @@ swagger: map: '09. 맵 페이지' tag: '10. 태그' home: '11. 홈 화면 페이지' + map-data: '12. 서울맵 데이터' From 8fd88c776f7d8df73809eb8bb227b35042c98242 Mon Sep 17 00:00:00 2001 From: yujin Date: Fri, 16 Feb 2024 12:35:47 +0900 Subject: [PATCH 2/6] =?UTF-8?q?Refactor:=20`ContentDetailService`=20?= =?UTF-8?q?=EB=AF=B8=EC=82=AC=EC=9A=A9=20=ED=95=84=EB=93=9C=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 --- .../com/ecolink/core/map/service/ContentDetailService.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/com/ecolink/core/map/service/ContentDetailService.java b/src/main/java/com/ecolink/core/map/service/ContentDetailService.java index e516b5d0..c707e0f3 100644 --- a/src/main/java/com/ecolink/core/map/service/ContentDetailService.java +++ b/src/main/java/com/ecolink/core/map/service/ContentDetailService.java @@ -6,8 +6,6 @@ import com.ecolink.core.map.dto.ContentDetailDto; import com.ecolink.core.map.dto.ContentListDetailDto; import com.ecolink.core.map.repository.ContentDetailRepository; -import com.ecolink.core.geo.service.GeometryService; -import com.ecolink.core.store.dto.request.MapQueryRequest; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -18,12 +16,10 @@ public class ContentDetailService { private final ContentDetailRepository contentDetailRepository; private final ObjectMapper objectMapper; - private final GeometryService geometryService; - public ContentDetailService(ContentDetailRepository contentDetailRepository, ObjectMapper objectMapper, GeometryService geometryService) { + public ContentDetailService(ContentDetailRepository contentDetailRepository, ObjectMapper objectMapper) { this.contentDetailRepository = contentDetailRepository; this.objectMapper = objectMapper; - this.geometryService = geometryService; } public void saveContentDetail(String responseData) { From bf6892a3bf47508e7339e2fb1bfc2b1f4657e603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=92=80=EA=B7=B8/=EC=9D=B4=EC=A4=80=ED=91=9C?= <85255237+wnsvy607@users.noreply.github.com> Date: Fri, 16 Feb 2024 15:24:35 +0900 Subject: [PATCH 3/6] =?UTF-8?q?Fix:=20COT=5FCOORD=5FDATA=20=EB=A7=A4?= =?UTF-8?q?=ED=95=91=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ecolink/core/map/domain/MapContent.java | 16 ++- .../core/map/dto/ContentDetailDto.java | 14 ++- .../map/service/ContentDetailService.java | 118 ++++++++++-------- 3 files changed, 86 insertions(+), 62 deletions(-) diff --git a/src/main/java/com/ecolink/core/map/domain/MapContent.java b/src/main/java/com/ecolink/core/map/domain/MapContent.java index fab7a593..593ff933 100644 --- a/src/main/java/com/ecolink/core/map/domain/MapContent.java +++ b/src/main/java/com/ecolink/core/map/domain/MapContent.java @@ -1,10 +1,17 @@ package com.ecolink.core.map.domain; +import org.locationtech.jts.geom.Point; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import jakarta.persistence.*; +import lombok.ToString; +@ToString @Getter @Setter @NoArgsConstructor @@ -35,7 +42,7 @@ public class MapContent { private String cotExtraName; private String cotNationBaseArea; private String cotNationPointNumber; - private String cotCoordData; + private Point cotCoordData; private String cotCoordType; private String cotCoordX; private String cotCoordY; @@ -61,7 +68,7 @@ public MapContent(String cotValue03, String cotValue04, String cotValue05, Strin String cotAddrFullNew, String cotAddrFullOld, String cotTelNo, String cotRegDate, String cotUpdateDate, String cotThemeId, String cotContsId, String cotGuName, String cotDongName, String cotSanName, String cotMasterNo, String cotSlaveNo, String cotExtraName, String cotNationBaseArea, - String cotNationPointNumber, String cotCoordData, String cotCoordType, String cotCoordX, + String cotNationPointNumber, String cotCoordType, String cotCoordX, String cotCoordY, String cotContsStat, String cotWriter, String cotThemeSubId, String cotExtraData01, String cotExtraData02, String cotMovieUrl, String cotVoiceUrl, String cotContsDetail, String cotImgMainUrl, String cotImgMainUrl2, String cotImgMainUrl3, String cotImgMainUrl4, @@ -87,7 +94,6 @@ public MapContent(String cotValue03, String cotValue04, String cotValue05, Strin this.cotExtraName = cotExtraName; this.cotNationBaseArea = cotNationBaseArea; this.cotNationPointNumber = cotNationPointNumber; - this.cotCoordData = cotCoordData; this.cotCoordType = cotCoordType; this.cotCoordX = cotCoordX; this.cotCoordY = cotCoordY; @@ -110,4 +116,4 @@ public MapContent(String cotValue03, String cotValue04, String cotValue05, Strin this.cotLineColor = cotLineColor; } -} \ No newline at end of file +} diff --git a/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java b/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java index d05b9baa..a01ce4bb 100644 --- a/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java +++ b/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java @@ -1,15 +1,19 @@ package com.ecolink.core.map.dto; +import java.math.BigDecimal; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; +import lombok.ToString; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; - +@ToString @Getter @Setter -@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class) +@JsonIgnoreProperties(ignoreUnknown = true) public class ContentDetailDto { @Schema(description = "운영시간", example = "매일 11:00-21:30/ 비건 베이커리만 화 휴무") @@ -73,7 +77,7 @@ public class ContentDetailDto { private String cotNationPointNumber; @Schema(description = "좌표 정보 (GeoJson)") - private String cotCoordData; + private List cotCoordData; @Schema(description = "콘텐츠 좌표 타입", example = "1") private String cotCoordType; diff --git a/src/main/java/com/ecolink/core/map/service/ContentDetailService.java b/src/main/java/com/ecolink/core/map/service/ContentDetailService.java index c707e0f3..3bd8d869 100644 --- a/src/main/java/com/ecolink/core/map/service/ContentDetailService.java +++ b/src/main/java/com/ecolink/core/map/service/ContentDetailService.java @@ -1,34 +1,46 @@ package com.ecolink.core.map.service; +import java.math.BigDecimal; import java.util.List; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.ecolink.core.geo.service.GeometryService; import com.ecolink.core.map.domain.MapContent; import com.ecolink.core.map.dto.ContentDetailDto; -import com.ecolink.core.map.dto.ContentListDetailDto; import com.ecolink.core.map.repository.ContentDetailRepository; +import com.ecolink.core.store.dto.request.MapQueryRequest; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; + +import lombok.extern.slf4j.Slf4j; +@Slf4j @Service @Transactional public class ContentDetailService { private final ContentDetailRepository contentDetailRepository; - private final ObjectMapper objectMapper; + private final ObjectMapper mapper; + private final GeometryService geometryService; - public ContentDetailService(ContentDetailRepository contentDetailRepository, ObjectMapper objectMapper) { + public ContentDetailService(ContentDetailRepository contentDetailRepository, GeometryService geometryService) { this.contentDetailRepository = contentDetailRepository; - this.objectMapper = objectMapper; + this.geometryService = geometryService; + this.mapper = new ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_SNAKE_CASE); } public void saveContentDetail(String responseData) { try { - ContentListDetailDto responseDTO = objectMapper.readValue(responseData, ContentListDetailDto.class); - List contentDetailList = responseDTO.getBody(); + JsonNode jsonNode = mapper.readValue(responseData, JsonNode.class); + JsonNode body = jsonNode.get("body"); - for (ContentDetailDto contentDetail : contentDetailList) { - MapContent mapContent = mapDetailToMapEntity(contentDetail); + for (JsonNode contents : body) { + log.info("data: {}", contents); + ContentDetailDto dto = mapper.treeToValue(contents, ContentDetailDto.class); + MapContent mapContent = mapDetailToMapEntity(dto); contentDetailRepository.save(mapContent); } } catch (Exception e) { @@ -36,49 +48,51 @@ public void saveContentDetail(String responseData) { } } - private MapContent mapDetailToMapEntity(ContentDetailDto contentDetailDto) { + private MapContent mapDetailToMapEntity(ContentDetailDto dto) { MapContent mapContent = new MapContent(); - mapContent.setCotValue03(contentDetailDto.getCotValue03()); - mapContent.setCotValue04(contentDetailDto.getCotValue04()); - mapContent.setCotValue05(contentDetailDto.getCotValue05()); - mapContent.setCotValue06(contentDetailDto.getCotValue06()); - mapContent.setCotValue07(contentDetailDto.getCotValue07()); - mapContent.setCotAddrFullNew(contentDetailDto.getCotAddrFullNew()); - mapContent.setCotAddrFullOld(contentDetailDto.getCotAddrFullOld()); - mapContent.setCotTelNo(contentDetailDto.getCotTelNo()); - mapContent.setCotRegDate(contentDetailDto.getCotRegDate()); - mapContent.setCotUpdateDate(contentDetailDto.getCotUpdateDate()); - mapContent.setCotThemeId(contentDetailDto.getCotThemeId()); - mapContent.setCotContsId(contentDetailDto.getCotContsId()); - mapContent.setCotGuName(contentDetailDto.getCotGuName()); - mapContent.setCotDongName(contentDetailDto.getCotDongName()); - mapContent.setCotSanName(contentDetailDto.getCotSanName()); - mapContent.setCotMasterNo(contentDetailDto.getCotMasterNo()); - mapContent.setCotSlaveNo(contentDetailDto.getCotSlaveNo()); - mapContent.setCotExtraName(contentDetailDto.getCotExtraName()); - mapContent.setCotNationBaseArea(contentDetailDto.getCotNationBaseArea()); - mapContent.setCotNationPointNumber(contentDetailDto.getCotNationPointNumber()); - mapContent.setCotCoordData(contentDetailDto.getCotCoordData()); - mapContent.setCotCoordType(contentDetailDto.getCotCoordType()); - mapContent.setCotCoordX(contentDetailDto.getCotCoordX()); - mapContent.setCotCoordY(contentDetailDto.getCotCoordY()); - mapContent.setCotContsStat(contentDetailDto.getCotContsStat()); - mapContent.setCotWriter(contentDetailDto.getCotWriter()); - mapContent.setCotThemeSubId(contentDetailDto.getCotThemeSubId()); - mapContent.setCotExtraData01(contentDetailDto.getCotExtraData01()); - mapContent.setCotExtraData02(contentDetailDto.getCotExtraData02()); - mapContent.setCotMovieUrl(contentDetailDto.getCotMovieUrl()); - mapContent.setCotVoiceUrl(contentDetailDto.getCotVoiceUrl()); - mapContent.setCotContsDetail(contentDetailDto.getCotContsDetail()); - mapContent.setCotImgMainUrl(contentDetailDto.getCotImgMainUrl()); - mapContent.setCotImgMainUrl2(contentDetailDto.getCotImgMainUrl2()); - mapContent.setCotImgMainUrl3(contentDetailDto.getCotImgMainUrl3()); - mapContent.setCotImgMainUrl4(contentDetailDto.getCotImgMainUrl4()); - mapContent.setCotImgMainUrl5(contentDetailDto.getCotImgMainUrl5()); - mapContent.setCotCoordStyle(contentDetailDto.getCotCoordStyle()); - mapContent.setCotLinePattern(contentDetailDto.getCotLinePattern()); - mapContent.setCotLineWeight(contentDetailDto.getCotLineWeight()); - mapContent.setCotLineColor(contentDetailDto.getCotLineColor()); + mapContent.setCotValue03(dto.getCotValue03()); + mapContent.setCotValue04(dto.getCotValue04()); + mapContent.setCotValue05(dto.getCotValue05()); + mapContent.setCotValue06(dto.getCotValue06()); + mapContent.setCotValue07(dto.getCotValue07()); + mapContent.setCotAddrFullNew(dto.getCotAddrFullNew()); + mapContent.setCotAddrFullOld(dto.getCotAddrFullOld()); + mapContent.setCotTelNo(dto.getCotTelNo()); + mapContent.setCotRegDate(dto.getCotRegDate()); + mapContent.setCotUpdateDate(dto.getCotUpdateDate()); + mapContent.setCotThemeId(dto.getCotThemeId()); + mapContent.setCotContsId(dto.getCotContsId()); + mapContent.setCotGuName(dto.getCotGuName()); + mapContent.setCotDongName(dto.getCotDongName()); + mapContent.setCotSanName(dto.getCotSanName()); + mapContent.setCotMasterNo(dto.getCotMasterNo()); + mapContent.setCotSlaveNo(dto.getCotSlaveNo()); + mapContent.setCotExtraName(dto.getCotExtraName()); + mapContent.setCotNationBaseArea(dto.getCotNationBaseArea()); + mapContent.setCotNationPointNumber(dto.getCotNationPointNumber()); + List data = dto.getCotCoordData(); + mapContent.setCotCoordData( + geometryService.getPoint(new MapQueryRequest(data.get(0).doubleValue(), data.get(1).doubleValue()))); + mapContent.setCotCoordType(dto.getCotCoordType()); + mapContent.setCotCoordX(dto.getCotCoordX()); + mapContent.setCotCoordY(dto.getCotCoordY()); + mapContent.setCotContsStat(dto.getCotContsStat()); + mapContent.setCotWriter(dto.getCotWriter()); + mapContent.setCotThemeSubId(dto.getCotThemeSubId()); + mapContent.setCotExtraData01(dto.getCotExtraData01()); + mapContent.setCotExtraData02(dto.getCotExtraData02()); + mapContent.setCotMovieUrl(dto.getCotMovieUrl()); + mapContent.setCotVoiceUrl(dto.getCotVoiceUrl()); + mapContent.setCotContsDetail(dto.getCotContsDetail()); + mapContent.setCotImgMainUrl(dto.getCotImgMainUrl()); + mapContent.setCotImgMainUrl2(dto.getCotImgMainUrl2()); + mapContent.setCotImgMainUrl3(dto.getCotImgMainUrl3()); + mapContent.setCotImgMainUrl4(dto.getCotImgMainUrl4()); + mapContent.setCotImgMainUrl5(dto.getCotImgMainUrl5()); + mapContent.setCotCoordStyle(dto.getCotCoordStyle()); + mapContent.setCotLinePattern(dto.getCotLinePattern()); + mapContent.setCotLineWeight(dto.getCotLineWeight()); + mapContent.setCotLineColor(dto.getCotLineColor()); return mapContent; } From bd14b9e7dc5c5a5e67a3d72cd59a0713fd7e800c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=92=80=EA=B7=B8/=EC=9D=B4=EC=A4=80=ED=91=9C?= <85255237+wnsvy607@users.noreply.github.com> Date: Sat, 17 Feb 2024 09:04:14 +0900 Subject: [PATCH 4/6] =?UTF-8?q?Feat:=20=EC=A2=8C=ED=91=9C=20=EA=B0=92?= =?UTF-8?q?=EC=9D=B4=20null=20=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=20=ED=95=B8?= =?UTF-8?q?=EB=93=A4=EB=A7=81,=20URI=20=EC=9D=B8=EC=BD=94=EB=94=A9=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/map/service/ContentDetailService.java | 14 ++++---------- .../core/map/util/ContentDetailFetcher.java | 17 ++++++++++------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/ecolink/core/map/service/ContentDetailService.java b/src/main/java/com/ecolink/core/map/service/ContentDetailService.java index 3bd8d869..5744900c 100644 --- a/src/main/java/com/ecolink/core/map/service/ContentDetailService.java +++ b/src/main/java/com/ecolink/core/map/service/ContentDetailService.java @@ -1,8 +1,5 @@ package com.ecolink.core.map.service; -import java.math.BigDecimal; -import java.util.List; - import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -15,9 +12,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import lombok.extern.slf4j.Slf4j; - -@Slf4j @Service @Transactional public class ContentDetailService { @@ -38,7 +32,6 @@ public void saveContentDetail(String responseData) { JsonNode body = jsonNode.get("body"); for (JsonNode contents : body) { - log.info("data: {}", contents); ContentDetailDto dto = mapper.treeToValue(contents, ContentDetailDto.class); MapContent mapContent = mapDetailToMapEntity(dto); contentDetailRepository.save(mapContent); @@ -70,9 +63,10 @@ private MapContent mapDetailToMapEntity(ContentDetailDto dto) { mapContent.setCotExtraName(dto.getCotExtraName()); mapContent.setCotNationBaseArea(dto.getCotNationBaseArea()); mapContent.setCotNationPointNumber(dto.getCotNationPointNumber()); - List data = dto.getCotCoordData(); - mapContent.setCotCoordData( - geometryService.getPoint(new MapQueryRequest(data.get(0).doubleValue(), data.get(1).doubleValue()))); + if (!dto.getCotCoordX().isEmpty() && !dto.getCotCoordY().isEmpty()) + mapContent.setCotCoordData( + geometryService.getPoint( + new MapQueryRequest(Double.valueOf(dto.getCotCoordX()), Double.valueOf(dto.getCotCoordY())))); mapContent.setCotCoordType(dto.getCotCoordType()); mapContent.setCotCoordX(dto.getCotCoordX()); mapContent.setCotCoordY(dto.getCotCoordY()); diff --git a/src/main/java/com/ecolink/core/map/util/ContentDetailFetcher.java b/src/main/java/com/ecolink/core/map/util/ContentDetailFetcher.java index 5d3a3baa..1339ac57 100644 --- a/src/main/java/com/ecolink/core/map/util/ContentDetailFetcher.java +++ b/src/main/java/com/ecolink/core/map/util/ContentDetailFetcher.java @@ -1,9 +1,8 @@ package com.ecolink.core.map.util; +import java.net.URI; import java.util.List; -import com.ecolink.core.map.service.ContentDetailService; -import com.ecolink.core.map.service.ContentListService; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; @@ -12,6 +11,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import com.ecolink.core.map.service.ContentDetailService; +import com.ecolink.core.map.service.ContentListService; + @Component public class ContentDetailFetcher { @@ -29,12 +31,13 @@ public void fetchAndStoreContentDetail() { HttpClient httpClient = HttpClients.createDefault(); for (String contentId : contentIds) { - String url = - "https://map.seoul.go.kr/smgis/apps/poi.do?cmd=getNewContentsDetail&key=90d9ef047980430297ec7fa3a8377710&theme_id=11103395&conts_id=" - + contentId; - HttpGet httpGet = new HttpGet(url); try { + URI uri = + new URI("https", + "//map.seoul.go.kr/smgis/apps/poi.do?cmd=getNewContentsDetail&key=90d9ef047980430297ec7fa3a8377710&theme_id=11103395&conts_id=" + + contentId, null); + HttpGet httpGet = new HttpGet(uri); HttpResponse response = httpClient.execute(httpGet); int statusCode = response.getStatusLine().getStatusCode(); @@ -51,4 +54,4 @@ public void fetchAndStoreContentDetail() { } } } -} \ No newline at end of file +} From 55df0fe59e8b45bc26d2d36baba29e0a963a3d3f Mon Sep 17 00:00:00 2001 From: yujin Date: Sat, 17 Feb 2024 10:16:35 +0900 Subject: [PATCH 5/6] =?UTF-8?q?Refactor:=20COT=5FCONTS=5FNAME=20=EC=83=81?= =?UTF-8?q?=EC=A0=90=EC=9D=B4=EB=A6=84=20=ED=95=84=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ecolink/core/map/domain/MapContent.java | 4 +++- src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java | 3 +++ .../com/ecolink/core/map/service/ContentDetailService.java | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/ecolink/core/map/domain/MapContent.java b/src/main/java/com/ecolink/core/map/domain/MapContent.java index 593ff933..812db064 100644 --- a/src/main/java/com/ecolink/core/map/domain/MapContent.java +++ b/src/main/java/com/ecolink/core/map/domain/MapContent.java @@ -22,6 +22,7 @@ public class MapContent { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + private String cotContsName; private String cotValue03; private String cotValue04; private String cotValue05; @@ -64,7 +65,7 @@ public class MapContent { private String cotLineWeight; private String cotLineColor; - public MapContent(String cotValue03, String cotValue04, String cotValue05, String cotValue06, String cotValue07, + public MapContent(String cotContsName, String cotValue03, String cotValue04, String cotValue05, String cotValue06, String cotValue07, String cotAddrFullNew, String cotAddrFullOld, String cotTelNo, String cotRegDate, String cotUpdateDate, String cotThemeId, String cotContsId, String cotGuName, String cotDongName, String cotSanName, String cotMasterNo, String cotSlaveNo, String cotExtraName, String cotNationBaseArea, @@ -74,6 +75,7 @@ public MapContent(String cotValue03, String cotValue04, String cotValue05, Strin String cotImgMainUrl, String cotImgMainUrl2, String cotImgMainUrl3, String cotImgMainUrl4, String cotImgMainUrl5, String cotCoordStyle, String cotLinePattern, String cotLineWeight, String cotLineColor) { + this.cotContsName = cotContsName; this.cotValue03 = cotValue03; this.cotValue04 = cotValue04; this.cotValue05 = cotValue05; diff --git a/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java b/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java index a01ce4bb..350311e5 100644 --- a/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java +++ b/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java @@ -16,6 +16,9 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class ContentDetailDto { + @Schema(description = "상점이름", example = "호랑이상점") + private String cotContsName; + @Schema(description = "운영시간", example = "매일 11:00-21:30/ 비건 베이커리만 화 휴무") private String cotValue03; diff --git a/src/main/java/com/ecolink/core/map/service/ContentDetailService.java b/src/main/java/com/ecolink/core/map/service/ContentDetailService.java index 5744900c..d86df028 100644 --- a/src/main/java/com/ecolink/core/map/service/ContentDetailService.java +++ b/src/main/java/com/ecolink/core/map/service/ContentDetailService.java @@ -43,6 +43,7 @@ public void saveContentDetail(String responseData) { private MapContent mapDetailToMapEntity(ContentDetailDto dto) { MapContent mapContent = new MapContent(); + mapContent.setCotContsName(dto.getCotContsName()); mapContent.setCotValue03(dto.getCotValue03()); mapContent.setCotValue04(dto.getCotValue04()); mapContent.setCotValue05(dto.getCotValue05()); From edebdcbbd8ef78ba74802df012c512c5bb156321 Mon Sep 17 00:00:00 2001 From: yujin Date: Sun, 18 Feb 2024 00:53:33 +0900 Subject: [PATCH 6/6] =?UTF-8?q?Feat:=20`Store`=20=EC=83=81=EC=A0=90=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ecolink/core/common/constant/Address.java | 7 ++ .../map/controller/StoreMapController.java | 15 +++- .../core/map/dto/ContentDetailDto.java | 14 ++-- .../map/service/ContentDetailService.java | 15 ++-- .../core/map/util/StoreDetailFetcher.java | 57 +++++++++++++++ .../com/ecolink/core/store/domain/Store.java | 15 +++- .../core/store/service/StoreMapService.java | 72 +++++++++++++++++++ 7 files changed, 178 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/ecolink/core/map/util/StoreDetailFetcher.java create mode 100644 src/main/java/com/ecolink/core/store/service/StoreMapService.java diff --git a/src/main/java/com/ecolink/core/common/constant/Address.java b/src/main/java/com/ecolink/core/common/constant/Address.java index 54a75609..213bb332 100644 --- a/src/main/java/com/ecolink/core/common/constant/Address.java +++ b/src/main/java/com/ecolink/core/common/constant/Address.java @@ -35,4 +35,11 @@ public class Address { @Schema(description = "지번 주소", example = "흑석동 54-149 1층") private String lotNumber; + public Address(String province, String city, String roadName, String lotNumber) { + this.province = province; + this.city = city; + this.roadName = roadName; + this.lotNumber = lotNumber; + } + } diff --git a/src/main/java/com/ecolink/core/map/controller/StoreMapController.java b/src/main/java/com/ecolink/core/map/controller/StoreMapController.java index a1986abf..9211652e 100644 --- a/src/main/java/com/ecolink/core/map/controller/StoreMapController.java +++ b/src/main/java/com/ecolink/core/map/controller/StoreMapController.java @@ -2,20 +2,26 @@ import com.ecolink.core.map.util.ContentDetailFetcher; import com.ecolink.core.map.util.ContentListFetcher; +import com.ecolink.core.map.util.StoreDetailFetcher; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; + @RestController public class StoreMapController { private final ContentListFetcher contentListFetcher; private final ContentDetailFetcher contentDetailFetcher; - public StoreMapController(ContentListFetcher contentListFetcher, ContentDetailFetcher contentDetailFetcher) { + private final StoreDetailFetcher storeDetailFetcher; + + public StoreMapController(ContentListFetcher contentListFetcher, ContentDetailFetcher contentDetailFetcher, + StoreDetailFetcher storeDetailFetcher) { this.contentListFetcher = contentListFetcher; this.contentDetailFetcher = contentDetailFetcher; + this.storeDetailFetcher = storeDetailFetcher; } @Tag(name = "${swagger.map-data}") @@ -33,4 +39,11 @@ public void getContentsDetailAll() { contentDetailFetcher.fetchAndStoreContentDetail(); } + @Tag(name = "${swagger.map-data}") + @Operation(summary = "상점 데이터 등록 API", description = "상점 상세 데이터 조회 및 등록 API") + @GetMapping("/store") + public void getStoreDetailAll() { + storeDetailFetcher.fetchAndStoreInfoDetail(); + } + } diff --git a/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java b/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java index 350311e5..ec1d172c 100644 --- a/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java +++ b/src/main/java/com/ecolink/core/map/dto/ContentDetailDto.java @@ -20,19 +20,19 @@ public class ContentDetailDto { private String cotContsName; @Schema(description = "운영시간", example = "매일 11:00-21:30/ 비건 베이커리만 화 휴무") - private String cotValue03; + private String cotValue_03; @Schema(description = "취급품목(메뉴)", example = "제로웨이스트 제품, 비건 식품, 리필 세제류, 비건베이커리") - private String cotValue04; + private String cotValue_04; @Schema(description = "인스타그램", example = "http://www.instagram.com/zerowaste_jigu") - private String cotValue05; + private String cotValue_05; @Schema(description = "제로페이", example = "가능") - private String cotValue06; + private String cotValue_06; @Schema(description = "인터넷 쇼핑몰", example = "https://smartstore.naver.com/peaceontable") - private String cotValue07; + private String cotValue_07; @Schema(description = "매장 주소 (새 주소)", example = "서울특별시 마포구 성미산로 155") private String cotAddrFullNew; @@ -101,10 +101,10 @@ public class ContentDetailDto { private String cotThemeSubId; @Schema(description = "기타 정보 1", example = "") - private String cotExtraData01; + private String cotExtraData_01; @Schema(description = "링크 URL", example = "https://www.jigushop.co.kr/") - private String cotExtraData02; + private String cotExtraData_02; @Schema(description = "동영상 URL", example = "") private String cotMovieUrl; diff --git a/src/main/java/com/ecolink/core/map/service/ContentDetailService.java b/src/main/java/com/ecolink/core/map/service/ContentDetailService.java index d86df028..e1d9ca88 100644 --- a/src/main/java/com/ecolink/core/map/service/ContentDetailService.java +++ b/src/main/java/com/ecolink/core/map/service/ContentDetailService.java @@ -44,11 +44,11 @@ public void saveContentDetail(String responseData) { private MapContent mapDetailToMapEntity(ContentDetailDto dto) { MapContent mapContent = new MapContent(); mapContent.setCotContsName(dto.getCotContsName()); - mapContent.setCotValue03(dto.getCotValue03()); - mapContent.setCotValue04(dto.getCotValue04()); - mapContent.setCotValue05(dto.getCotValue05()); - mapContent.setCotValue06(dto.getCotValue06()); - mapContent.setCotValue07(dto.getCotValue07()); + mapContent.setCotValue03(dto.getCotValue_03()); + mapContent.setCotValue04(dto.getCotValue_04()); + mapContent.setCotValue05(dto.getCotValue_05()); + mapContent.setCotValue06(dto.getCotValue_06()); + mapContent.setCotValue07(dto.getCotValue_07()); mapContent.setCotAddrFullNew(dto.getCotAddrFullNew()); mapContent.setCotAddrFullOld(dto.getCotAddrFullOld()); mapContent.setCotTelNo(dto.getCotTelNo()); @@ -74,8 +74,8 @@ private MapContent mapDetailToMapEntity(ContentDetailDto dto) { mapContent.setCotContsStat(dto.getCotContsStat()); mapContent.setCotWriter(dto.getCotWriter()); mapContent.setCotThemeSubId(dto.getCotThemeSubId()); - mapContent.setCotExtraData01(dto.getCotExtraData01()); - mapContent.setCotExtraData02(dto.getCotExtraData02()); + mapContent.setCotExtraData01(dto.getCotExtraData_01()); + mapContent.setCotExtraData02(dto.getCotExtraData_02()); mapContent.setCotMovieUrl(dto.getCotMovieUrl()); mapContent.setCotVoiceUrl(dto.getCotVoiceUrl()); mapContent.setCotContsDetail(dto.getCotContsDetail()); @@ -91,4 +91,5 @@ private MapContent mapDetailToMapEntity(ContentDetailDto dto) { return mapContent; } + } diff --git a/src/main/java/com/ecolink/core/map/util/StoreDetailFetcher.java b/src/main/java/com/ecolink/core/map/util/StoreDetailFetcher.java new file mode 100644 index 00000000..ecc1f67e --- /dev/null +++ b/src/main/java/com/ecolink/core/map/util/StoreDetailFetcher.java @@ -0,0 +1,57 @@ +package com.ecolink.core.map.util; + +import java.net.URI; +import java.util.List; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.ecolink.core.map.service.ContentListService; +import com.ecolink.core.store.service.StoreMapService; + +@Component +public class StoreDetailFetcher { + + private final StoreMapService storeMapService; + private final ContentListService contentListService; + + @Autowired + public StoreDetailFetcher(StoreMapService storeMapService, ContentListService contentListService) { + this.storeMapService = storeMapService; + this.contentListService = contentListService; + } + + public void fetchAndStoreInfoDetail() { + List contentIds = contentListService.getContentIds(); + + HttpClient httpClient = HttpClients.createDefault(); + for (String contentId : contentIds) { + + try { + URI uri = + new URI("https", + "//map.seoul.go.kr/smgis/apps/poi.do?cmd=getNewContentsDetail&key=90d9ef047980430297ec7fa3a8377710&theme_id=11103395&conts_id=" + + contentId, null); + HttpGet httpGet = new HttpGet(uri); + HttpResponse response = httpClient.execute(httpGet); + int statusCode = response.getStatusLine().getStatusCode(); + + if (statusCode == 200) { + String responseData = EntityUtils.toString(response.getEntity()); + + storeMapService.saveStoreDetail(responseData); + } else { + System.err.println( + "Failed to fetch data for content id: " + contentId + ", Status Code: " + statusCode); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/com/ecolink/core/store/domain/Store.java b/src/main/java/com/ecolink/core/store/domain/Store.java index 63103bc7..138b6125 100644 --- a/src/main/java/com/ecolink/core/store/domain/Store.java +++ b/src/main/java/com/ecolink/core/store/domain/Store.java @@ -26,12 +26,13 @@ import jakarta.persistence.Table; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; -import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; @Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Setter +@NoArgsConstructor @Entity @Table(name = "store", indexes = @Index(name = "idx_store_name", columnList = "name")) public class Store extends BaseTimeEntity { @@ -124,4 +125,14 @@ public void addProductCnt() { this.productCnt++; } + public Store(String name, Address address, String contact, String homepageUrl, String description, + String instagramUrl) { + this.name = name; + this.address = address; + this.contact = contact; + this.homepageUrl = homepageUrl; + this.description = description; + this.instagramUrl = instagramUrl; + } + } diff --git a/src/main/java/com/ecolink/core/store/service/StoreMapService.java b/src/main/java/com/ecolink/core/store/service/StoreMapService.java new file mode 100644 index 00000000..7508827b --- /dev/null +++ b/src/main/java/com/ecolink/core/store/service/StoreMapService.java @@ -0,0 +1,72 @@ +package com.ecolink.core.store.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.ecolink.core.common.constant.Address; +import com.ecolink.core.geo.service.GeometryService; +import com.ecolink.core.map.dto.ContentDetailDto; +import com.ecolink.core.store.domain.Store; +import com.ecolink.core.store.dto.request.MapQueryRequest; +import com.ecolink.core.store.repository.StoreRepository; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; + +@Service +@Transactional +public class StoreMapService { + + private final StoreRepository storeRepository; + private final ObjectMapper mapper; + private final GeometryService geometryService; + + public StoreMapService(StoreRepository storeRepository, GeometryService geometryService) { + this.storeRepository = storeRepository; + this.geometryService = geometryService; + this.mapper = new ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_SNAKE_CASE); + } + + public void saveStoreDetail(String responseData) { + try { + JsonNode jsonNode = mapper.readValue(responseData, JsonNode.class); + JsonNode body = jsonNode.get("body"); + + for (JsonNode contents : body) { + ContentDetailDto dto = mapper.treeToValue(contents, ContentDetailDto.class); + Store store = mapDetailToMapEntity(dto); + storeRepository.save(store); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private Store mapDetailToMapEntity(ContentDetailDto dto) { + Store store = new Store(); + store.setName(dto.getCotContsName()); + store.setContact(dto.getCotTelNo()); + store.setHomepageUrl(dto.getCotExtraData_02()); + store.setDescription(dto.getCotValue_04()); + store.setInstagramUrl(dto.getCotValue_05()); + store.setAddress( + new Address("서울특별시", + dto.getCotGuName() == null || dto.getCotGuName().isBlank() ? "구정보 없음" : dto.getCotGuName(), + parse(dto.getCotAddrFullNew()), parse(dto.getCotAddrFullOld()))); + if (!dto.getCotCoordX().isEmpty() && !dto.getCotCoordY().isEmpty()) + store.setCoordinates( + geometryService.getPoint( + new MapQueryRequest(Double.valueOf(dto.getCotCoordX()), Double.valueOf(dto.getCotCoordY())))); + return store; + } + + private String parse(String fullAddress) { + String[] split = fullAddress.split(" ", 3); + if (fullAddress == null || fullAddress.isBlank() || split.length <= 2 || split[2].isBlank()) { + System.out.println("split = " + fullAddress); + return "파싱 불가능"; + } + return split[2]; + } + +}