From 11071ca2e97be95dc6b103cfe25cd6015c04d2dd Mon Sep 17 00:00:00 2001 From: Donghun Won Date: Tue, 13 Jan 2026 16:36:25 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20=ED=8C=8C=ED=8B=B0=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=ED=95=AD=EC=83=81=20=EA=B1=B0=EB=A6=AC=EC=88=9C?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95=20+=20=EB=8F=99?= =?UTF-8?q?=EB=84=A4=20=EA=B8=B0=EC=A4=80=EC=9C=BC=EB=A1=9C=20=ED=8C=8C?= =?UTF-8?q?=ED=8B=B0=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../party/controller/PartyController.java | 35 +++++++++---------- .../dto/response/PartyDetailResponse.java | 1 + .../tinybite/domain/party/entity/Party.java | 3 ++ .../party/repository/PartyRepository.java | 4 +++ .../domain/party/service/PartyService.java | 35 +++++++++++-------- 5 files changed, 45 insertions(+), 33 deletions(-) diff --git a/src/main/java/ita/tinybite/domain/party/controller/PartyController.java b/src/main/java/ita/tinybite/domain/party/controller/PartyController.java index 9454125..4bbeeaa 100644 --- a/src/main/java/ita/tinybite/domain/party/controller/PartyController.java +++ b/src/main/java/ita/tinybite/domain/party/controller/PartyController.java @@ -380,25 +380,22 @@ public ResponseEntity getPartyList( ) { Double lat = null; Double lon = null; - // 거리순 정렬 시 위치 정보 검증 - if (sortType == PartySortType.DISTANCE) { - if (userLat == null || userLon == null) { - throw new IllegalArgumentException("거리순 정렬을 위해서는 현재 위치 정보가 필요합니다."); - } - - try { - lat = Double.parseDouble(userLat); - lon = Double.parseDouble(userLon); - } catch (NumberFormatException e) { - throw new IllegalArgumentException( - String.format("위치 정보 형식이 올바르지 않습니다. userLat: %s, userLon: %s", userLat, userLon) - ); - } - - // 위도/경도 범위 검증 - if (lat < -90 || lat > 90 || lon < -180 || lon > 180) { - throw new IllegalArgumentException("위도/경도 값이 유효한 범위를 벗어났습니다."); - } + if (userLat == null || userLon == null) { + throw new IllegalArgumentException("거리순 정렬을 위해서는 현재 위치 정보가 필요합니다."); + } + + try { + lat = Double.parseDouble(userLat); + lon = Double.parseDouble(userLon); + } catch (NumberFormatException e) { + throw new IllegalArgumentException( + String.format("위치 정보 형식이 올바르지 않습니다. userLat: %s, userLon: %s", userLat, userLon) + ); + } + + // 위도/경도 범위 검증 + if (lat < -90 || lat > 90 || lon < -180 || lon > 180) { + throw new IllegalArgumentException("위도/경도 값이 유효한 범위를 벗어났습니다."); } PartyListRequest request = PartyListRequest.builder() diff --git a/src/main/java/ita/tinybite/domain/party/dto/response/PartyDetailResponse.java b/src/main/java/ita/tinybite/domain/party/dto/response/PartyDetailResponse.java index 5c70009..9ce72ad 100644 --- a/src/main/java/ita/tinybite/domain/party/dto/response/PartyDetailResponse.java +++ b/src/main/java/ita/tinybite/domain/party/dto/response/PartyDetailResponse.java @@ -16,6 +16,7 @@ public class PartyDetailResponse { private String title; private PartyCategory category; private String timeAgo; + private String town; // 파티장 정보 private HostInfo host; diff --git a/src/main/java/ita/tinybite/domain/party/entity/Party.java b/src/main/java/ita/tinybite/domain/party/entity/Party.java index a6b5e37..39625c9 100644 --- a/src/main/java/ita/tinybite/domain/party/entity/Party.java +++ b/src/main/java/ita/tinybite/domain/party/entity/Party.java @@ -52,6 +52,9 @@ public class Party { @Column(length = 500) private String link; // 링크 (예: 배달앱 링크) + @Column(length = 30) + private String town; + @Embedded @Column private PickupLocation pickupLocation; diff --git a/src/main/java/ita/tinybite/domain/party/repository/PartyRepository.java b/src/main/java/ita/tinybite/domain/party/repository/PartyRepository.java index fc92205..29bccde 100644 --- a/src/main/java/ita/tinybite/domain/party/repository/PartyRepository.java +++ b/src/main/java/ita/tinybite/domain/party/repository/PartyRepository.java @@ -22,4 +22,8 @@ public interface PartyRepository extends JpaRepository { List findByPickupLocation_PlaceAndCategory(String place, PartyCategory category); List findByHostUserIdAndStatus(Long userId, PartyStatus partyStatus); + + List findByTown(String location); + + List findByTownAndCategory(String location, PartyCategory category); } diff --git a/src/main/java/ita/tinybite/domain/party/service/PartyService.java b/src/main/java/ita/tinybite/domain/party/service/PartyService.java index b627e45..d9821e4 100644 --- a/src/main/java/ita/tinybite/domain/party/service/PartyService.java +++ b/src/main/java/ita/tinybite/domain/party/service/PartyService.java @@ -70,6 +70,8 @@ public Long createParty(Long userId, PartyCreateRequest request) { User user = userRepository.findById(userId) .orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다")); + String myTown = getMyTown(request.getPickupLocation().getPickupLatitude(), request.getPickupLocation().getPickupLongitude()); + // 카테고리별 유효성 검증 validateProductLink(request.getCategory(), request.getProductLink()); @@ -78,6 +80,7 @@ public Long createParty(Long userId, PartyCreateRequest request) { .category(request.getCategory()) .price(request.getTotalPrice()) .maxParticipants(request.getMaxParticipants()) + .town(myTown) .pickupLocation(PickupLocation.builder() .place(request.getPickupLocation().getPlace()) .pickupLatitude(request.getPickupLocation().getPickupLatitude()) @@ -140,13 +143,17 @@ public PartyListResponse getPartyList(Long userId, PartyListRequest request) { int page = request.getPage() != null ? request.getPage() : 0; int size = request.getSize() != null ? request.getSize() : 20; + String myTown = getMyTown(request.getUserLat(),request.getUserLon()); + // 동네 기준으로 파티 조회 - List parties = fetchPartiesByLocation(user, request); + List parties = fetchPartiesByTown(user, request, myTown); // PartyCardResponse로 변환 List cardResponses = parties.stream() .map(party -> { - if (request.getSortType() == PartySortType.DISTANCE) { + // 위치 정보가 있으면 항상 거리 계산 + if (request.getUserLat() != null && request.getUserLon() != null + && party.getPickupLocation() != null) { double distance = DistanceCalculator.calculateDistance( request.getUserLat(), request.getUserLon(), @@ -155,21 +162,22 @@ public PartyListResponse getPartyList(Long userId, PartyListRequest request) { ); return convertToCardResponseWithDistance(party, distance); } - return convertToCardResponse(party,party.getCreatedAt()); + return convertToCardResponse(party, party.getCreatedAt()); }) .toList(); + // 진행 중 파티 정렬 List activeParties = cardResponses.stream() .filter(p -> !p.getIsClosed()) .sorted(getComparator(request.getSortType())) - .collect(Collectors.toList()); + .toList(); // 마감된 파티 정렬 List closedParties = cardResponses.stream() .filter(PartyCardResponse::getIsClosed) .sorted(getComparator(request.getSortType())) - .collect(Collectors.toList()); + .toList(); // 진행 중 + 마감된 파티 합치기 (진행 중이 먼저) List allParties = new ArrayList<>(); @@ -380,17 +388,12 @@ private PartyDetailResponse convertToDetailResponse(Party party, double distance int currentCount = party.getCurrentParticipants(); int pricePerPerson = party.getPrice() / party.getMaxParticipants(); - // 이미지 파싱 -// List images = new ArrayList<>(); -// if (party.getImages() != null && !party.getImages().isEmpty()) { -// images = List.of(party.getImages()); -// } - return PartyDetailResponse.builder() .partyId(party.getId()) .title(party.getTitle()) .category(party.getCategory()) .timeAgo(party.getTimeAgo()) + .town(party.getTown()) .host(HostInfo.builder() .userId(party.getHost().getUserId()) .nickname(party.getHost().getNickname()) @@ -805,7 +808,7 @@ private String formatDistanceIfExists(Double distance) { } //카테고리에 따라 파티 조회 - private List fetchPartiesByLocation(User user, PartyListRequest request) { + private List fetchPartiesByTown(User user, PartyListRequest request,String myTown) { if (user == null || user.getLocation() == null) { return List.of(); } @@ -814,9 +817,9 @@ private List fetchPartiesByLocation(User user, PartyListRequest request) PartyCategory category = request.getCategory(); if (category == PartyCategory.ALL) { - return partyRepository.findByPickupLocation_Place(location); + return partyRepository.findByTown(location); } else { - return partyRepository.findByPickupLocation_PlaceAndCategory(location, category); + return partyRepository.findByTownAndCategory(location, category); } } @@ -839,5 +842,9 @@ private PartyCardResponse convertToCardResponseWithDistance( response.addDistanceKm(distance); return response; } + + private String getMyTown(Double pickupLatitude, Double pickupLongitude) { + return locationService.getLocation(Double.toString(pickupLatitude), Double.toString(pickupLongitude)); + } }