From d29b9da440d545da76e695a156540171c8d4083d Mon Sep 17 00:00:00 2001 From: eedo_y Date: Tue, 12 Aug 2025 20:05:38 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20feat=20:=20=EC=9D=B8=ED=94=84?= =?UTF-8?q?=EB=9D=BC=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EA=B3=B5=EA=B3=A0=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/in/web/NoticeInfraApi.java | 20 ++++++++--- .../adapter/in/web/dto/FacilityType.java | 11 ++++++ .../in/web/swagger/NoticeInfraApiSpec.java | 14 ++++++++ .../adapter/out/NoticeMongoAdapter.java | 9 +++++ .../application/in/NoticeInfraUseCase.java | 5 ++- .../application/out/notice/NoticePort.java | 5 ++- .../service/NoticeInfraService.java | 32 ++++++++++++----- .../platform/domain/facility/Animal.java | 2 +- .../platform/domain/facility/Facility.java | 13 +++++++ .../platform/domain/facility/Library.java | 2 +- .../server/platform/domain/facility/Park.java | 2 +- .../platform/domain/facility/Sport.java | 2 +- .../platform/domain/facility/Walking.java | 2 +- .../platform/domain/notice/NoticeCount.java | 36 +++++++++++++++++++ 14 files changed, 136 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/pinHouse/server/platform/adapter/in/web/dto/FacilityType.java create mode 100644 src/main/java/com/pinHouse/server/platform/domain/facility/Facility.java create mode 100644 src/main/java/com/pinHouse/server/platform/domain/notice/NoticeCount.java diff --git a/src/main/java/com/pinHouse/server/platform/adapter/in/web/NoticeInfraApi.java b/src/main/java/com/pinHouse/server/platform/adapter/in/web/NoticeInfraApi.java index 0b687b0..98d76ba 100644 --- a/src/main/java/com/pinHouse/server/platform/adapter/in/web/NoticeInfraApi.java +++ b/src/main/java/com/pinHouse/server/platform/adapter/in/web/NoticeInfraApi.java @@ -1,15 +1,16 @@ package com.pinHouse.server.platform.adapter.in.web; import com.pinHouse.server.core.response.response.ApiResponse; +import com.pinHouse.server.platform.adapter.in.web.dto.FacilityType; import com.pinHouse.server.platform.adapter.in.web.dto.response.InfraDTO; +import com.pinHouse.server.platform.adapter.in.web.dto.response.NoticeDTO; import com.pinHouse.server.platform.adapter.in.web.swagger.NoticeInfraApiSpec; import com.pinHouse.server.platform.application.in.NoticeInfraUseCase; +import com.pinHouse.server.platform.domain.notice.Notice; import com.pinHouse.server.platform.domain.notice.NoticeInfra; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import java.util.List; @RestController @RequestMapping("/api/v1/notices/infra") @@ -35,6 +36,17 @@ public ApiResponse showNotice( } /// 원하는 인프라를 바탕으로 많이 존재하는 지역을 설정 + @GetMapping("/type") + public ApiResponse> showNoticeList( + @RequestParam List facilityTypes + ) { + // 1. 시설 타입별로 지역(행정동 등)별 시설 수 집계 + List notices = service.getNoticesByInfraTypesWithAllMinCount(facilityTypes); + // 4. 응답 DTO 구성 + List responses = NoticeDTO.NoticeListResponse.from(notices); + + return ApiResponse.ok(responses); + } } diff --git a/src/main/java/com/pinHouse/server/platform/adapter/in/web/dto/FacilityType.java b/src/main/java/com/pinHouse/server/platform/adapter/in/web/dto/FacilityType.java new file mode 100644 index 0000000..1f4c419 --- /dev/null +++ b/src/main/java/com/pinHouse/server/platform/adapter/in/web/dto/FacilityType.java @@ -0,0 +1,11 @@ +package com.pinHouse.server.platform.adapter.in.web.dto; + +public enum FacilityType { + + LIBRARY, // 도서관 + PARK, // 공원 + ANIMAL, // 동물 관련 시설 + WALKING, // 산책로 + SPORT // 스포츠 시설 + +} diff --git a/src/main/java/com/pinHouse/server/platform/adapter/in/web/swagger/NoticeInfraApiSpec.java b/src/main/java/com/pinHouse/server/platform/adapter/in/web/swagger/NoticeInfraApiSpec.java index c66686a..e3d91e1 100644 --- a/src/main/java/com/pinHouse/server/platform/adapter/in/web/swagger/NoticeInfraApiSpec.java +++ b/src/main/java/com/pinHouse/server/platform/adapter/in/web/swagger/NoticeInfraApiSpec.java @@ -1,12 +1,17 @@ package com.pinHouse.server.platform.adapter.in.web.swagger; import com.pinHouse.server.core.response.response.ApiResponse; +import com.pinHouse.server.platform.adapter.in.web.dto.FacilityType; import com.pinHouse.server.platform.adapter.in.web.dto.response.InfraDTO; +import com.pinHouse.server.platform.adapter.in.web.dto.response.NoticeDTO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; @Tag(name = "공고 주변 인프라 API", description = "인프라를 바탕으로 조회하는 API 입니다.") public interface NoticeInfraApiSpec { @@ -19,4 +24,13 @@ public interface NoticeInfraApiSpec { ApiResponse showNotice( @Parameter(example = "18407") @PathVariable String noticeId); + + @Operation( + summary = "인프라에 따른 공고 조회 API", + description = "해당 인프라가 2개 이상 존재하는 공고를 조회하는 API입니다." + ) + @GetMapping("/type") + ApiResponse> showNoticeList( + @RequestParam List facilityTypes + ); } diff --git a/src/main/java/com/pinHouse/server/platform/adapter/out/NoticeMongoAdapter.java b/src/main/java/com/pinHouse/server/platform/adapter/out/NoticeMongoAdapter.java index c5fc44a..4f317f5 100644 --- a/src/main/java/com/pinHouse/server/platform/adapter/out/NoticeMongoAdapter.java +++ b/src/main/java/com/pinHouse/server/platform/adapter/out/NoticeMongoAdapter.java @@ -10,6 +10,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Component; +import java.util.List; import java.util.Optional; /** @@ -35,4 +36,12 @@ public Optional loadById(String noticeId) { return repository.findByNoticeId(noticeId) .map(NoticeDocument::toDomain); } + + @Override + public List loadAllNotices() { + return repository.findAll().stream() + .map(NoticeDocument::toDomain) + .toList(); + } + } diff --git a/src/main/java/com/pinHouse/server/platform/application/in/NoticeInfraUseCase.java b/src/main/java/com/pinHouse/server/platform/application/in/NoticeInfraUseCase.java index 188a4b3..3bc27a3 100644 --- a/src/main/java/com/pinHouse/server/platform/application/in/NoticeInfraUseCase.java +++ b/src/main/java/com/pinHouse/server/platform/application/in/NoticeInfraUseCase.java @@ -1,8 +1,11 @@ package com.pinHouse.server.platform.application.in; +import com.pinHouse.server.platform.adapter.in.web.dto.FacilityType; import com.pinHouse.server.platform.domain.notice.Notice; import com.pinHouse.server.platform.domain.notice.NoticeInfra; +import java.util.List; + /** * - 공고 주변의 인프라 목록 조회할 인터페이스 */ @@ -13,5 +16,5 @@ public interface NoticeInfraUseCase { NoticeInfra getNoticeInfraById(String noticeId); // 원하는 인프라 바탕으로 많이 존재하는 공고 조회 - Notice getNoticeByInfra(); + List getNoticesByInfraTypesWithAllMinCount(List facilityTypes); } diff --git a/src/main/java/com/pinHouse/server/platform/application/out/notice/NoticePort.java b/src/main/java/com/pinHouse/server/platform/application/out/notice/NoticePort.java index aa9b953..f2f32e3 100644 --- a/src/main/java/com/pinHouse/server/platform/application/out/notice/NoticePort.java +++ b/src/main/java/com/pinHouse/server/platform/application/out/notice/NoticePort.java @@ -4,7 +4,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import java.util.Optional; +import java.util.*; /** * DB에 넣는 포트를 정의한 인터페이스입니다. @@ -19,4 +19,7 @@ public interface NoticePort { /// 상세 조회 Optional loadById(String id); + /// 모든 공고 가져오기 + List loadAllNotices(); + } diff --git a/src/main/java/com/pinHouse/server/platform/application/service/NoticeInfraService.java b/src/main/java/com/pinHouse/server/platform/application/service/NoticeInfraService.java index 7d63218..0410bc2 100644 --- a/src/main/java/com/pinHouse/server/platform/application/service/NoticeInfraService.java +++ b/src/main/java/com/pinHouse/server/platform/application/service/NoticeInfraService.java @@ -1,6 +1,7 @@ package com.pinHouse.server.platform.application.service; import com.pinHouse.server.core.response.response.ErrorCode; +import com.pinHouse.server.platform.adapter.in.web.dto.FacilityType; import com.pinHouse.server.platform.application.in.NoticeInfraUseCase; import com.pinHouse.server.platform.application.out.facility.FacilityPort; import com.pinHouse.server.platform.application.out.notice.NoticePort; @@ -78,17 +79,32 @@ public NoticeInfra getNoticeInfraById(String noticeId) { return NoticeInfra.of(notice, libraries, animals, sports, walkings, parks); } - /// - @Override - public Notice getNoticeByInfra() { - return null; - } - // ================= // 인프라 바탕으로 공고 조회 // ================= - - + @Override + public List getNoticesByInfraTypesWithAllMinCount(List facilityTypes) { + List allNotices = noticePort.loadAllNotices(); + + return allNotices.stream() + .filter(notice -> { + double lng = notice.getLocation().getLongitude(); + double lat = notice.getLocation().getLatitude(); + + // 모든 종류가 2개 이상이어야만 true 반환 + return facilityTypes.stream().allMatch(facilityType -> { + List facilityList = switch (facilityType) { + case LIBRARY -> facilityPort.loadLibrariesNearBy(lng, lat, radiusInRadians); + case PARK -> facilityPort.loadParksNearBy(lng, lat, radiusInRadians); + case ANIMAL -> facilityPort.loadAnimalsNearBy(lng, lat, radiusInRadians); + case WALKING -> facilityPort.loadWalkingsNearBy(lng, lat, radiusInRadians); + case SPORT -> facilityPort.loadSportsNearBy(lng, lat, radiusInRadians); + }; + return facilityList.size() >= 2; + }); + }) + .toList(); + } // ================= diff --git a/src/main/java/com/pinHouse/server/platform/domain/facility/Animal.java b/src/main/java/com/pinHouse/server/platform/domain/facility/Animal.java index d6fccdf..9cc8eea 100644 --- a/src/main/java/com/pinHouse/server/platform/domain/facility/Animal.java +++ b/src/main/java/com/pinHouse/server/platform/domain/facility/Animal.java @@ -10,7 +10,7 @@ @AllArgsConstructor @NoArgsConstructor @Builder -public class Animal { +public class Animal implements Facility{ /// 아이디 private String id; diff --git a/src/main/java/com/pinHouse/server/platform/domain/facility/Facility.java b/src/main/java/com/pinHouse/server/platform/domain/facility/Facility.java new file mode 100644 index 0000000..5346e8f --- /dev/null +++ b/src/main/java/com/pinHouse/server/platform/domain/facility/Facility.java @@ -0,0 +1,13 @@ +package com.pinHouse.server.platform.domain.facility; + +import com.pinHouse.server.platform.domain.location.Location; + +public interface Facility { + + /** + * 시설의 위치 정보를 반환합니다. + * @return 시설 위치 객체 + */ + Location getLocation(); + +} diff --git a/src/main/java/com/pinHouse/server/platform/domain/facility/Library.java b/src/main/java/com/pinHouse/server/platform/domain/facility/Library.java index 0d7f1fb..5909da5 100644 --- a/src/main/java/com/pinHouse/server/platform/domain/facility/Library.java +++ b/src/main/java/com/pinHouse/server/platform/domain/facility/Library.java @@ -10,7 +10,7 @@ @AllArgsConstructor @NoArgsConstructor @Builder -public class Library { +public class Library implements Facility{ private String id; private Integer code; diff --git a/src/main/java/com/pinHouse/server/platform/domain/facility/Park.java b/src/main/java/com/pinHouse/server/platform/domain/facility/Park.java index e0abdb0..689c82b 100644 --- a/src/main/java/com/pinHouse/server/platform/domain/facility/Park.java +++ b/src/main/java/com/pinHouse/server/platform/domain/facility/Park.java @@ -8,7 +8,7 @@ @Getter @AllArgsConstructor @Builder -public class Park { +public class Park implements Facility{ /// 아이디 private String id; diff --git a/src/main/java/com/pinHouse/server/platform/domain/facility/Sport.java b/src/main/java/com/pinHouse/server/platform/domain/facility/Sport.java index ce3a1e9..882111a 100644 --- a/src/main/java/com/pinHouse/server/platform/domain/facility/Sport.java +++ b/src/main/java/com/pinHouse/server/platform/domain/facility/Sport.java @@ -10,7 +10,7 @@ @AllArgsConstructor @NoArgsConstructor @Builder -public class Sport { +public class Sport implements Facility{ private String id; diff --git a/src/main/java/com/pinHouse/server/platform/domain/facility/Walking.java b/src/main/java/com/pinHouse/server/platform/domain/facility/Walking.java index 108c8e4..553febe 100644 --- a/src/main/java/com/pinHouse/server/platform/domain/facility/Walking.java +++ b/src/main/java/com/pinHouse/server/platform/domain/facility/Walking.java @@ -10,7 +10,7 @@ @AllArgsConstructor @NoArgsConstructor @Builder -public class Walking { +public class Walking implements Facility{ private String id; diff --git a/src/main/java/com/pinHouse/server/platform/domain/notice/NoticeCount.java b/src/main/java/com/pinHouse/server/platform/domain/notice/NoticeCount.java new file mode 100644 index 0000000..9b868f0 --- /dev/null +++ b/src/main/java/com/pinHouse/server/platform/domain/notice/NoticeCount.java @@ -0,0 +1,36 @@ +package com.pinHouse.server.platform.domain.notice; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class NoticeCount { + + private String noticeId; + + private int libraryCount; + + private int animalCount; + + private int parkCount; + + private int sportCount; + + private int walkCount; + + /// 정적 팩토리 메서드 + public NoticeCount of(String noticeId, int libraryCount, int animalCount, int parkCount, int sportCount) { + return NoticeCount.builder() + .noticeId(noticeId) + .libraryCount(libraryCount) + .animalCount(animalCount) + .parkCount(parkCount) + .sportCount(sportCount) + .build(); + } +} From c184bd50fd39775e2cb3c0046e4469472c96b6c0 Mon Sep 17 00:00:00 2001 From: eedo_y Date: Tue, 12 Aug 2025 20:11:16 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=92=A1=20style=20:=20=EC=8A=A4?= =?UTF-8?q?=EC=9B=A8=EA=B1=B0=20=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../platform/adapter/in/web/DepositApi.java | 3 ++- .../platform/adapter/in/web/DistanceApi.java | 3 ++- .../in/web/swagger/DepositApiSpec.java | 26 +++++++++++++++++++ .../in/web/swagger/DistanceApiSpec.java | 24 +++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/pinHouse/server/platform/adapter/in/web/swagger/DepositApiSpec.java create mode 100644 src/main/java/com/pinHouse/server/platform/adapter/in/web/swagger/DistanceApiSpec.java diff --git a/src/main/java/com/pinHouse/server/platform/adapter/in/web/DepositApi.java b/src/main/java/com/pinHouse/server/platform/adapter/in/web/DepositApi.java index baf0234..565e92e 100644 --- a/src/main/java/com/pinHouse/server/platform/adapter/in/web/DepositApi.java +++ b/src/main/java/com/pinHouse/server/platform/adapter/in/web/DepositApi.java @@ -2,6 +2,7 @@ import com.pinHouse.server.core.response.response.ApiResponse; import com.pinHouse.server.platform.adapter.in.web.dto.response.NoticeSupplyDTO; +import com.pinHouse.server.platform.adapter.in.web.swagger.DepositApiSpec; import com.pinHouse.server.platform.application.in.NoticeUseCase; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -12,7 +13,7 @@ @RestController @RequestMapping("/api/v1/notices/deposit") @RequiredArgsConstructor -public class DepositApi { +public class DepositApi implements DepositApiSpec { private final NoticeUseCase noticeService; diff --git a/src/main/java/com/pinHouse/server/platform/adapter/in/web/DistanceApi.java b/src/main/java/com/pinHouse/server/platform/adapter/in/web/DistanceApi.java index d37b278..aeec857 100644 --- a/src/main/java/com/pinHouse/server/platform/adapter/in/web/DistanceApi.java +++ b/src/main/java/com/pinHouse/server/platform/adapter/in/web/DistanceApi.java @@ -1,5 +1,6 @@ package com.pinHouse.server.platform.adapter.in.web; +import com.pinHouse.server.platform.adapter.in.web.swagger.DistanceApiSpec; import com.pinHouse.server.platform.application.out.distance.DistancePort; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -9,7 +10,7 @@ @RestController @RequestMapping("/api/v1/distance") @RequiredArgsConstructor -public class DistanceApi { +public class DistanceApi implements DistanceApiSpec { private final DistancePort distancePort; diff --git a/src/main/java/com/pinHouse/server/platform/adapter/in/web/swagger/DepositApiSpec.java b/src/main/java/com/pinHouse/server/platform/adapter/in/web/swagger/DepositApiSpec.java new file mode 100644 index 0000000..4e6bc9e --- /dev/null +++ b/src/main/java/com/pinHouse/server/platform/adapter/in/web/swagger/DepositApiSpec.java @@ -0,0 +1,26 @@ +package com.pinHouse.server.platform.adapter.in.web.swagger; + +import com.pinHouse.server.core.response.response.ApiResponse; +import com.pinHouse.server.platform.adapter.in.web.dto.response.NoticeSupplyDTO; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@Tag(name = "예산 시뮬레이터 API", description = "보증금/최대전환월세를 계산하는 API입니다.") +public interface DepositApiSpec { + + @PutMapping("/{noticeId}") + ApiResponse update( + + @Parameter(example = "18384", description = "공고 ID") + @PathVariable String noticeId, + + @Parameter(example = "26A", description = "주거 타입") + @RequestParam String housingType, + + @Parameter(example = "0.001", description = "변환율") + @RequestParam double percentage); + +} diff --git a/src/main/java/com/pinHouse/server/platform/adapter/in/web/swagger/DistanceApiSpec.java b/src/main/java/com/pinHouse/server/platform/adapter/in/web/swagger/DistanceApiSpec.java new file mode 100644 index 0000000..23adee8 --- /dev/null +++ b/src/main/java/com/pinHouse/server/platform/adapter/in/web/swagger/DistanceApiSpec.java @@ -0,0 +1,24 @@ +package com.pinHouse.server.platform.adapter.in.web.swagger; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import java.io.UnsupportedEncodingException; + +@Tag(name = "거리 시뮬레이터 API", description = "원하는 주소를 바탕으로 대중교통 시뮬레이터를 하는 API입니다.") +public interface DistanceApiSpec { + + @Operation( + summary = "거리 시뮬레이터 API", + description = "출발 좌표와 도착 좌표를 통해 계산을 진행합니다.") + @GetMapping() + String getDistance( + @RequestParam double startY, + @RequestParam double startX, + @RequestParam double endY, + @RequestParam double endX + ) throws UnsupportedEncodingException; + +}