diff --git a/src/main/java/com/earseo/sight/controller/SightController.java b/src/main/java/com/earseo/sight/controller/SightController.java index 1b52f49..316dc67 100644 --- a/src/main/java/com/earseo/sight/controller/SightController.java +++ b/src/main/java/com/earseo/sight/controller/SightController.java @@ -588,10 +588,13 @@ public ResponseEntity> searchTitle( @RequestParam(defaultValue = "10") @Min(value = 1, message = "제한 개수는 1 이상이어야 합니다") @Max(value = 100, message = "제한 개수는 100 이하여야 합니다") - Integer limit + Integer limit, + + @RequestHeader(value = "X-USER-ID", required = false) + Long memberId ) { return ResponseEntity.ok(BaseResponse.ok( - sightService.searchSight(keyword, longitude, latitude, minLongitude, minLatitude, maxLongitude, maxLatitude, limit, "ko") + sightService.searchSight(keyword, longitude, latitude, minLongitude, minLatitude, maxLongitude, maxLatitude, limit, "ko", memberId) )); } } diff --git a/src/main/java/com/earseo/sight/dto/projection/SearchSightItemDto.java b/src/main/java/com/earseo/sight/dto/projection/SearchSightItemDto.java index b7a0a2d..28db0eb 100644 --- a/src/main/java/com/earseo/sight/dto/projection/SearchSightItemDto.java +++ b/src/main/java/com/earseo/sight/dto/projection/SearchSightItemDto.java @@ -7,6 +7,7 @@ public record SearchSightItemDto( String addr3, Double mapX, Double mapY, - Double distance + Double distance, + boolean isBookmark ) { } diff --git a/src/main/java/com/earseo/sight/dto/response/LocationType.java b/src/main/java/com/earseo/sight/dto/response/LocationType.java new file mode 100644 index 0000000..70a81d3 --- /dev/null +++ b/src/main/java/com/earseo/sight/dto/response/LocationType.java @@ -0,0 +1,6 @@ +package com.earseo.sight.dto.response; + +public enum LocationType { + SIGHT, + BOOKMARK +} 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 0f45877..b2c084f 100644 --- a/src/main/java/com/earseo/sight/dto/response/SearchSightResponse.java +++ b/src/main/java/com/earseo/sight/dto/response/SearchSightResponse.java @@ -24,7 +24,9 @@ public record SearchSightResponse( Double latitude, @Schema(description = "현재 위치로부터의 직선 거리 (미터)", example = "1234.56") - Double distance + Double distance, + + LocationType locationType ) { public static SearchSightResponse toDto(SearchSightItemDto dto){ return new SearchSightResponse( @@ -34,7 +36,8 @@ public static SearchSightResponse toDto(SearchSightItemDto dto){ dto.addr3(), dto.mapX(), dto.mapY(), - dto.distance() + dto.distance(), + dto.isBookmark() ? LocationType.BOOKMARK : LocationType.SIGHT ); } } diff --git a/src/main/java/com/earseo/sight/repository/EnSightRepository.java b/src/main/java/com/earseo/sight/repository/EnSightRepository.java index 68bd057..8a404b2 100644 --- a/src/main/java/com/earseo/sight/repository/EnSightRepository.java +++ b/src/main/java/com/earseo/sight/repository/EnSightRepository.java @@ -98,15 +98,23 @@ List findByCurationId( ST_Distance( s.geom::geography, ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326)::geography - ) as distance + ) as distance, + CASE WHEN :memberId IS NOT NULL AND sb.id IS NOT NULL + THEN true + ELSE false + END as is_bookmark FROM en_sight s + LEFT JOIN sight_bookmark sb + ON sb.content_id = s.content_id + AND sb.member_id = :memberId WHERE ST_Intersects( s.geom, ST_MakeEnvelope(:minLongitude, :minLatitude, :maxLongitude, :maxLatitude, 4326) - ) AND - :keyword IS NULL OR - :keyword = '' OR - s.title ILIKE '%' || :keyword || '%' + ) AND ( + :keyword IS NULL OR + :keyword = '' OR + s.title ILIKE '%' || :keyword || '%' + ) ORDER BY distance LIMIT :limit """, nativeQuery = true) @@ -118,6 +126,7 @@ List findByKeywordAndRectangle( @Param("minLatitude") Double minLatitude, @Param("maxLongitude") Double maxLongitude, @Param("maxLatitude") Double maxLatitude, - @Param("limit") Integer limit + @Param("limit") Integer limit, + @Param("memberId") Long memberId ); } diff --git a/src/main/java/com/earseo/sight/repository/KoSightRepository.java b/src/main/java/com/earseo/sight/repository/KoSightRepository.java index 57d71ec..081dac7 100644 --- a/src/main/java/com/earseo/sight/repository/KoSightRepository.java +++ b/src/main/java/com/earseo/sight/repository/KoSightRepository.java @@ -98,15 +98,23 @@ List findByCurationId( ST_Distance( s.geom::geography, ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326)::geography - ) as distance + ) as distance, + CASE WHEN :memberId IS NOT NULL AND sb.id IS NOT NULL + THEN true + ELSE false + END as is_bookmark FROM ko_sight s + LEFT JOIN sight_bookmark sb + ON sb.content_id = s.content_id + AND sb.member_id = :memberId WHERE ST_Intersects( s.geom, ST_MakeEnvelope(:minLongitude, :minLatitude, :maxLongitude, :maxLatitude, 4326) - ) AND - :keyword IS NULL OR - :keyword = '' OR - s.title ILIKE '%' || :keyword || '%' + ) AND ( + :keyword IS NULL OR + :keyword = '' OR + s.title ILIKE '%' || :keyword || '%' + ) ORDER BY distance LIMIT :limit """, nativeQuery = true) @@ -118,6 +126,7 @@ List findByKeywordAndRectangle( @Param("minLatitude") Double minLatitude, @Param("maxLongitude") Double maxLongitude, @Param("maxLatitude") Double maxLatitude, - @Param("limit") Integer limit + @Param("limit") Integer limit, + @Param("memberId") Long memberId ); } diff --git a/src/main/java/com/earseo/sight/service/SightService.java b/src/main/java/com/earseo/sight/service/SightService.java index 107a59a..54f7809 100644 --- a/src/main/java/com/earseo/sight/service/SightService.java +++ b/src/main/java/com/earseo/sight/service/SightService.java @@ -115,16 +115,16 @@ public DocentResponse getDocent(String sightId) { public SearchSightList searchSight( String keyword, Double longitude, Double latitude, Double minLongitude, Double minLatitude, - Double maxLongitude, Double maxLatitude, Integer limit, String lang) { + Double maxLongitude, Double maxLatitude, Integer limit, String lang, Long memberId) { if (minLongitude >= maxLongitude || minLatitude >= maxLatitude) { throw new BaseException(SightError.INVALID_COORDINATE_RANGE); } List sights; if (lang.equals("en")) { - sights = enSightRepository.findByKeywordAndRectangle(keyword, longitude, latitude, minLongitude, minLatitude, maxLongitude, maxLatitude, limit); + sights = enSightRepository.findByKeywordAndRectangle(keyword, longitude, latitude, minLongitude, minLatitude, maxLongitude, maxLatitude, limit, memberId); } else { - sights = koSightRepository.findByKeywordAndRectangle(keyword, longitude, latitude, minLongitude, minLatitude, maxLongitude, maxLatitude, limit); + sights = koSightRepository.findByKeywordAndRectangle(keyword, longitude, latitude, minLongitude, minLatitude, maxLongitude, maxLatitude, limit, memberId); } List sightResponses = sights.stream() .map(SearchSightResponse::toDto)