-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/search place by tag1 #16
Changes from 17 commits
f0b51e7
bd92297
d5e61f2
abfb4f8
7f77798
921a1e7
9a7bc2f
42fcea7
c3abf66
8429465
b737711
f761488
56b81b3
81d0203
191bb97
d1c00a2
d0c9a62
c6db02d
e26c46e
04dafa0
5c53d26
fc7fa46
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,6 +35,9 @@ public static <T> boolean isEmpty(final List<T> list) { | |
} | ||
|
||
public static <T> String joiningToString(final List<T> list, final String delimiter) { | ||
if (list.size() < 1) { | ||
return null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. null을 리턴하기보단, 빈 스트링을 주는게 메소드의 의도에 더 맞는 것 같습니다! 메소드명을 보면 반드시 string 타입이 반환될 것 같아서요! |
||
} | ||
return list.stream() | ||
.map(Object::toString) | ||
.collect(Collectors.joining(delimiter)); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.prography.kagongsillok.image.application.exception; | ||
|
||
import java.util.List; | ||
import org.prography.kagongsillok.common.exception.NotFoundException; | ||
import org.prography.kagongsillok.common.utils.CustomListUtils; | ||
|
||
public final class NotFoundImageException extends NotFoundException { | ||
|
||
public NotFoundImageException(final List<Long> imageIds) { | ||
super(String.format("존재하지 않는 이미지 id가 포함되어 있습니다. imageIds = %s", | ||
CustomListUtils.joiningToString(imageIds, ","))); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
package org.prography.kagongsillok.place.application; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import lombok.RequiredArgsConstructor; | ||
import org.prography.kagongsillok.common.utils.CustomListUtils; | ||
import org.prography.kagongsillok.image.application.exception.NotFoundImageException; | ||
import org.prography.kagongsillok.image.domain.Image; | ||
import org.prography.kagongsillok.image.domain.ImageRepository; | ||
import org.prography.kagongsillok.place.application.dto.PlaceCreateCommand; | ||
import org.prography.kagongsillok.place.application.dto.PlaceDto; | ||
import org.prography.kagongsillok.place.application.dto.PlaceLocationAroundSearchCondition; | ||
|
@@ -11,6 +14,9 @@ | |
import org.prography.kagongsillok.place.domain.Location; | ||
import org.prography.kagongsillok.place.domain.Place; | ||
import org.prography.kagongsillok.place.domain.PlaceRepository; | ||
import org.prography.kagongsillok.review.domain.Review; | ||
import org.prography.kagongsillok.review.domain.ReviewRepository; | ||
import org.prography.kagongsillok.review.domain.ReviewTag; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
|
@@ -20,12 +26,15 @@ | |
public class PlaceService { | ||
|
||
private final PlaceRepository placeRepository; | ||
private final ReviewRepository reviewRepository; | ||
private final ImageRepository imageRepository; | ||
|
||
@Transactional | ||
public PlaceDto createPlace(final PlaceCreateCommand placeCreateCommand) { | ||
checkExistImage(placeCreateCommand.getImageIds()); | ||
final Place savedPlace = placeRepository.save(placeCreateCommand.toEntity()); | ||
|
||
return PlaceDto.from(savedPlace); | ||
return PlaceDto.of(savedPlace, getImages(savedPlace)); | ||
} | ||
|
||
public PlaceDto getPlace(final Long id) { | ||
|
@@ -35,7 +44,18 @@ public PlaceDto getPlace(final Long id) { | |
throw new NotFoundPlaceException(id); | ||
} | ||
|
||
return PlaceDto.from(place); | ||
return PlaceDto.of(place, getImages(place)); | ||
} | ||
|
||
public PlaceDto getPlaceWithTags(final Long placeId) { | ||
final Place place = placeRepository.findById(placeId) | ||
.orElseThrow(() -> new NotFoundPlaceException(placeId)); | ||
if (place.getIsDeleted()) { | ||
throw new NotFoundPlaceException(placeId); | ||
} | ||
final List<Review> reviews = reviewRepository.findAllByPlaceId(placeId); | ||
|
||
return PlaceDto.of(place, getImages(place), getReviewTagsRelatedToPlace(reviews)); | ||
} | ||
|
||
public List<PlaceDto> searchPlacesLocationAround(final PlaceLocationAroundSearchCondition searchCondition) { | ||
|
@@ -45,24 +65,26 @@ public List<PlaceDto> searchPlacesLocationAround(final PlaceLocationAroundSearch | |
searchCondition.getLongitudeBound() | ||
); | ||
|
||
return CustomListUtils.mapTo(places, PlaceDto::from); | ||
return getPlaceDtos(places); | ||
} | ||
|
||
public List<PlaceDto> searchPlacesByName(final String name) { | ||
final List<Place> places = placeRepository.findByNameContains(name); | ||
|
||
return CustomListUtils.mapTo(places, PlaceDto::from); | ||
return getPlaceDtos(places); | ||
} | ||
|
||
@Transactional | ||
public PlaceDto updatePlace(final Long id, final PlaceUpdateCommand updateCommand) { | ||
final Place place = placeRepository.findById(id) | ||
.orElseThrow(() -> new NotFoundPlaceException(id)); | ||
|
||
checkExistImage(updateCommand.getImageIds()); | ||
|
||
final Place target = updateCommand.toEntity(); | ||
place.update(target); | ||
|
||
return PlaceDto.from(place); | ||
return PlaceDto.of(place, getImages(place)); | ||
} | ||
|
||
@Transactional | ||
|
@@ -72,4 +94,56 @@ public void deletePlace(final Long id) { | |
|
||
place.delete(); | ||
} | ||
|
||
public List<PlaceDto> searchPlacesByTags(final List<Long> reviewTagIds) { | ||
final List<Review> reviews = reviewRepository.findByReviewTagIds(reviewTagIds); | ||
final List<Long> placeIds = reviews.stream() | ||
.map(review -> review.getPlaceId()) | ||
.collect(Collectors.toSet()) | ||
.stream() | ||
.toList(); | ||
|
||
final List<Place> places = placeRepository.findByIdIn(placeIds); | ||
|
||
return createPlaceDtos(places, reviews); | ||
} | ||
private List<PlaceDto> getPlaceDtos(final List<Place> places) { | ||
final List<Long> placeIds = places.stream() | ||
.map(place -> place.getId()) | ||
.collect(Collectors.toList()); | ||
final List<Review> reviews = reviewRepository.findByPlaceIds(placeIds); | ||
|
||
return createPlaceDtos(places, reviews); | ||
} | ||
|
||
private List<PlaceDto> createPlaceDtos(final List<Place> places, final List<Review> reviews) { | ||
return places.stream() | ||
.map(place -> { | ||
List<Review> relatedReviews = reviews.stream() | ||
.filter(review -> review.getPlaceId().equals(place.getId())) | ||
.collect(Collectors.toList()); | ||
return PlaceDto.of(place, getImages(place), getReviewTagsRelatedToPlace(relatedReviews)); | ||
}) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private List<ReviewTag> getReviewTagsRelatedToPlace(final List<Review> reviews) { | ||
return reviews.stream() | ||
.flatMap(review -> review.getTagMappings() | ||
.getValues() | ||
.stream() | ||
.map(reviewTagMapping -> reviewTagMapping.getReviewTag()) | ||
) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private void checkExistImage(final List<Long> imageIds) { | ||
if (imageRepository.isExistIdIn(imageIds)) { | ||
throw new NotFoundImageException(imageIds); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. imageIds로 조회해서 존재할 경우 예외가 터지는 걸까요? 그렇게 읽히네요. |
||
|
||
private List<Image> getImages(final Place place) { | ||
return imageRepository.findByIdIn(place.getImageIds()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,9 +7,11 @@ | |
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import org.prography.kagongsillok.common.utils.CustomListUtils; | ||
import org.prography.kagongsillok.image.domain.Image; | ||
import org.prography.kagongsillok.place.domain.BusinessHour; | ||
import org.prography.kagongsillok.place.domain.Link; | ||
import org.prography.kagongsillok.place.domain.Place; | ||
import org.prography.kagongsillok.review.domain.ReviewTag; | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
|
@@ -20,10 +22,11 @@ public class PlaceDto { | |
private String address; | ||
private Double latitude; | ||
private Double longitude; | ||
private List<Long> imageIds; | ||
private List<Image> images; | ||
private String phone; | ||
private List<LinkDto> links; | ||
private List<BusinessHourDto> businessHours; | ||
private List<ReviewTag> reviewTags; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dto에서 다른 엔티티를 직접 들고 있네요. 같이 dto로 변환해서 드는게 좋지 않을까요? |
||
|
||
@Builder | ||
public PlaceDto( | ||
|
@@ -32,20 +35,22 @@ public PlaceDto( | |
final String address, | ||
final Double latitude, | ||
final Double longitude, | ||
final List<Long> imageIds, | ||
final List<Image> images, | ||
final String phone, | ||
final List<LinkDto> links, | ||
final List<BusinessHourDto> businessHours | ||
final List<BusinessHourDto> businessHours, | ||
final List<ReviewTag> reviewTags | ||
) { | ||
this.id = id; | ||
this.name = name; | ||
this.address = address; | ||
this.latitude = latitude; | ||
this.longitude = longitude; | ||
this.imageIds = imageIds; | ||
this.images = images; | ||
this.phone = phone; | ||
this.links = links; | ||
this.businessHours = businessHours; | ||
this.reviewTags = reviewTags; | ||
} | ||
|
||
public static PlaceDto from(final Place place) { | ||
|
@@ -55,13 +60,41 @@ public static PlaceDto from(final Place place) { | |
.address(place.getAddress()) | ||
.latitude(place.getLatitude()) | ||
.longitude(place.getLongitude()) | ||
.imageIds(place.getImageIds()) | ||
.phone(place.getPhone()) | ||
.links(CustomListUtils.mapTo(place.getLinks().getValues(), LinkDto::from)) | ||
.businessHours(CustomListUtils.mapTo(place.getBusinessHours().getValues(), BusinessHourDto::from)) | ||
.build(); | ||
} | ||
|
||
public static PlaceDto of(final Place place, final List<Image> images) { | ||
return PlaceDto.builder() | ||
.id(place.getId()) | ||
.name(place.getName()) | ||
.address(place.getAddress()) | ||
.latitude(place.getLatitude()) | ||
.longitude(place.getLongitude()) | ||
.images(images) | ||
.phone(place.getPhone()) | ||
.links(CustomListUtils.mapTo(place.getLinks().getValues(), LinkDto::from)) | ||
.businessHours(CustomListUtils.mapTo(place.getBusinessHours().getValues(), BusinessHourDto::from)) | ||
.build(); | ||
} | ||
|
||
public static PlaceDto of(final Place place,final List<Image> images, final List<ReviewTag> reviewTags) { | ||
return PlaceDto.builder() | ||
.id(place.getId()) | ||
.name(place.getName()) | ||
.address(place.getAddress()) | ||
.latitude(place.getLatitude()) | ||
.longitude(place.getLongitude()) | ||
.images(images) | ||
.phone(place.getPhone()) | ||
.links(CustomListUtils.mapTo(place.getLinks().getValues(), LinkDto::from)) | ||
.businessHours(CustomListUtils.mapTo(place.getBusinessHours().getValues(), BusinessHourDto::from)) | ||
.reviewTags(reviewTags) | ||
.build(); | ||
} | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
public static class LinkDto { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
매직넘버 상수로 추출해서 의미를 표현해주는건 어떨까요?