From 27ee367807d2d4a8a4197530b838a0e523dd768c Mon Sep 17 00:00:00 2001 From: woals2840 Date: Sun, 18 May 2025 03:27:55 +0900 Subject: [PATCH 1/5] =?UTF-8?q?[feat/#12]=20=ED=95=84=ED=84=B0=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Conflicts: # src/main/java/com/sopkathon/domain/subway/service/SubwayService.java --- .../place/controller/PlaceController.java | 21 +++++++++++ .../place/dto/GetPlaceListResponse.java | 11 ++++++ .../domain/place/dto/GetPlaceResponse.java | 26 ++++++++++++++ .../domain/place/entity/Category.java | 6 +++- .../domain/place/entity/PlaceEntity.java | 12 +++---- .../place/repository/PlaceRepository.java | 6 ++++ .../domain/place/service/PlaceService.java | 36 +++++++++++++++++++ .../controller/SimilarPlaceController.java | 8 ----- .../entity/SimilarPlaceEntity.java | 25 ------------- .../repository/SimilarPlaceRepository.java | 9 ----- .../service/SimilarPlaceService.java | 7 ---- .../subway/repository/SubwayRepository.java | 1 + .../domain/subway/service/SubwayService.java | 1 + 13 files changed, 111 insertions(+), 58 deletions(-) create mode 100644 src/main/java/com/sopkathon/domain/place/dto/GetPlaceListResponse.java create mode 100644 src/main/java/com/sopkathon/domain/place/dto/GetPlaceResponse.java delete mode 100644 src/main/java/com/sopkathon/domain/similarPlace/controller/SimilarPlaceController.java delete mode 100644 src/main/java/com/sopkathon/domain/similarPlace/entity/SimilarPlaceEntity.java delete mode 100644 src/main/java/com/sopkathon/domain/similarPlace/repository/SimilarPlaceRepository.java delete mode 100644 src/main/java/com/sopkathon/domain/similarPlace/service/SimilarPlaceService.java diff --git a/src/main/java/com/sopkathon/domain/place/controller/PlaceController.java b/src/main/java/com/sopkathon/domain/place/controller/PlaceController.java index fbd00f5..6d2825d 100644 --- a/src/main/java/com/sopkathon/domain/place/controller/PlaceController.java +++ b/src/main/java/com/sopkathon/domain/place/controller/PlaceController.java @@ -1,7 +1,28 @@ package com.sopkathon.domain.place.controller; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.sopkathon.domain.place.dto.GetPlaceListResponse; +import com.sopkathon.domain.place.service.PlaceService; +import com.sopkathon.global.error.code.SuccessCode; +import com.sopkathon.global.error.dto.SuccessResponse; + +import lombok.RequiredArgsConstructor; + @RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/places") public class PlaceController { + private final PlaceService placeService; + + @GetMapping + public ResponseEntity> getPlaceList(@RequestParam(name = "category", defaultValue = "ALL") String category, + @RequestParam(name = "subway") String subway){ + GetPlaceListResponse getPlaceListResponse = placeService.getPlaceList(category, subway); + return ResponseEntity.ok(SuccessResponse.of(SuccessCode.SUCCESS_FETCH, getPlaceListResponse)); + } } diff --git a/src/main/java/com/sopkathon/domain/place/dto/GetPlaceListResponse.java b/src/main/java/com/sopkathon/domain/place/dto/GetPlaceListResponse.java new file mode 100644 index 0000000..af2869c --- /dev/null +++ b/src/main/java/com/sopkathon/domain/place/dto/GetPlaceListResponse.java @@ -0,0 +1,11 @@ +package com.sopkathon.domain.place.dto; + +import java.util.List; + +public record GetPlaceListResponse( + List getPlaceResponseList +) { + public static GetPlaceListResponse of(List getPlaceResponseList) { + return new GetPlaceListResponse(getPlaceResponseList); + } +} diff --git a/src/main/java/com/sopkathon/domain/place/dto/GetPlaceResponse.java b/src/main/java/com/sopkathon/domain/place/dto/GetPlaceResponse.java new file mode 100644 index 0000000..88aae46 --- /dev/null +++ b/src/main/java/com/sopkathon/domain/place/dto/GetPlaceResponse.java @@ -0,0 +1,26 @@ +package com.sopkathon.domain.place.dto; + + +import com.sopkathon.domain.place.entity.PlaceEntity; + +import lombok.Builder; + +@Builder +public record GetPlaceResponse( + Long placeId, + String name, + String description, + String mapLink, + String photoUrl +) { + + public static GetPlaceResponse of(PlaceEntity placeEntity) { + return GetPlaceResponse.builder() + .placeId(placeEntity.getId()) + .name(placeEntity.getName()) + .description(placeEntity.getDescription()) + .mapLink(placeEntity.getMapLink()) + .photoUrl(placeEntity.getPhotoUrl()) + .build(); + } +} diff --git a/src/main/java/com/sopkathon/domain/place/entity/Category.java b/src/main/java/com/sopkathon/domain/place/entity/Category.java index 49bec1c..0a6c218 100644 --- a/src/main/java/com/sopkathon/domain/place/entity/Category.java +++ b/src/main/java/com/sopkathon/domain/place/entity/Category.java @@ -9,7 +9,11 @@ @Getter public enum Category { - NATURAL("자연"); + ORCHARD("과수원"), + CROPS("밭작물"), + LIVESTOCK("축산"), + PLANTS_AND_FLOWERS("식물·꽃"), + OTHER("기타"); private String name; diff --git a/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java b/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java index 804ca35..b1dd3b5 100644 --- a/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java +++ b/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java @@ -1,7 +1,6 @@ package com.sopkathon.domain.place.entity; import com.sopkathon.domain.review.entity.ReviewEntity; -import com.sopkathon.domain.similarPlace.entity.SimilarPlaceEntity; import com.sopkathon.domain.subway.entity.SubwayEntity; import jakarta.persistence.Column; @@ -29,6 +28,9 @@ public class PlaceEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Column(name = "name", nullable = false) + private String name; + @Column(name = "duration", nullable = false) private int duration; @@ -53,14 +55,9 @@ public class PlaceEntity { @JoinColumn(name = "review_id", nullable = false) private ReviewEntity reviewEntity; - @ManyToOne(targetEntity = SimilarPlaceEntity.class, fetch = FetchType.LAZY) - @JoinColumn(name = "similar_place_id", nullable = false) - private SimilarPlaceEntity similarPlaceEntity; - @Builder - public PlaceEntity(int duration, String description, String mapLink, String photoUrl, Category category, - SubwayEntity subwayEntity, ReviewEntity reviewEntity, SimilarPlaceEntity similarPlaceEntity) { + SubwayEntity subwayEntity, ReviewEntity reviewEntity) { this.duration = duration; this.description = description; this.mapLink = mapLink; @@ -68,6 +65,5 @@ public PlaceEntity(int duration, String description, String mapLink, String phot this.category = category; this.subwayEntity = subwayEntity; this.reviewEntity = reviewEntity; - this.similarPlaceEntity = similarPlaceEntity; } } diff --git a/src/main/java/com/sopkathon/domain/place/repository/PlaceRepository.java b/src/main/java/com/sopkathon/domain/place/repository/PlaceRepository.java index 9f38a80..93b5752 100644 --- a/src/main/java/com/sopkathon/domain/place/repository/PlaceRepository.java +++ b/src/main/java/com/sopkathon/domain/place/repository/PlaceRepository.java @@ -1,10 +1,16 @@ package com.sopkathon.domain.place.repository; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import com.sopkathon.domain.place.entity.Category; import com.sopkathon.domain.place.entity.PlaceEntity; +import com.sopkathon.domain.subway.entity.SubwayEntity; @Repository public interface PlaceRepository extends JpaRepository { + List findAllBySubwayEntity(SubwayEntity subwayEntity); + List findAllBySubwayEntityAndCategory(SubwayEntity subwayEntity, Category category); } diff --git a/src/main/java/com/sopkathon/domain/place/service/PlaceService.java b/src/main/java/com/sopkathon/domain/place/service/PlaceService.java index e39c019..b2bef54 100644 --- a/src/main/java/com/sopkathon/domain/place/service/PlaceService.java +++ b/src/main/java/com/sopkathon/domain/place/service/PlaceService.java @@ -1,4 +1,40 @@ package com.sopkathon.domain.place.service; +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.sopkathon.domain.place.dto.GetPlaceListResponse; +import com.sopkathon.domain.place.dto.GetPlaceResponse; +import com.sopkathon.domain.place.entity.Category; +import com.sopkathon.domain.place.entity.PlaceEntity; +import com.sopkathon.domain.place.repository.PlaceRepository; +import com.sopkathon.domain.subway.entity.SubwayEntity; +import com.sopkathon.domain.subway.service.SubwayService; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor public class PlaceService { + private final PlaceRepository placeRepository; + private final SubwayService SubwayService; + + public GetPlaceListResponse getPlaceList(String category, String subway){ + SubwayEntity subwayEntity = SubwayService.getSubwayEntity(subway); + List placeEntityList = getPlacesByCategory(subwayEntity, category); + + List getPlaceResponseList = placeEntityList.stream() + .map(GetPlaceResponse::of) + .toList(); + + return new GetPlaceListResponse(getPlaceResponseList); + } + + private List getPlacesByCategory(SubwayEntity subwayEntity, String category) { + if ("ALL".equals(category)) { + return placeRepository.findAllBySubwayEntity(subwayEntity); + } + return placeRepository.findAllBySubwayEntityAndCategory(subwayEntity, Category.fromName(category)); + } } diff --git a/src/main/java/com/sopkathon/domain/similarPlace/controller/SimilarPlaceController.java b/src/main/java/com/sopkathon/domain/similarPlace/controller/SimilarPlaceController.java deleted file mode 100644 index 3a5b062..0000000 --- a/src/main/java/com/sopkathon/domain/similarPlace/controller/SimilarPlaceController.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.sopkathon.domain.similarPlace.controller; - -import com.sopkathon.domain.similarPlace.service.SimilarPlaceService; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class SimilarPlaceController { -} diff --git a/src/main/java/com/sopkathon/domain/similarPlace/entity/SimilarPlaceEntity.java b/src/main/java/com/sopkathon/domain/similarPlace/entity/SimilarPlaceEntity.java deleted file mode 100644 index 5bccabd..0000000 --- a/src/main/java/com/sopkathon/domain/similarPlace/entity/SimilarPlaceEntity.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sopkathon.domain.similarPlace.entity; - -import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Table(name = "similar_place") -public class SimilarPlaceEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "duration", nullable = false) - private String duration; - - @Column(name = "description", nullable = false) - private String description; - - @Column(name = "photoUrl", nullable = false) - private String photoUrl; -} diff --git a/src/main/java/com/sopkathon/domain/similarPlace/repository/SimilarPlaceRepository.java b/src/main/java/com/sopkathon/domain/similarPlace/repository/SimilarPlaceRepository.java deleted file mode 100644 index 986e1d3..0000000 --- a/src/main/java/com/sopkathon/domain/similarPlace/repository/SimilarPlaceRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.sopkathon.domain.similarPlace.repository; - -import com.sopkathon.domain.similarPlace.entity.SimilarPlaceEntity; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface SimilarPlaceRepository extends JpaRepository { -} diff --git a/src/main/java/com/sopkathon/domain/similarPlace/service/SimilarPlaceService.java b/src/main/java/com/sopkathon/domain/similarPlace/service/SimilarPlaceService.java deleted file mode 100644 index d0bc775..0000000 --- a/src/main/java/com/sopkathon/domain/similarPlace/service/SimilarPlaceService.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.sopkathon.domain.similarPlace.service; - -import org.springframework.stereotype.Service; - -@Service -public class SimilarPlaceService { -} diff --git a/src/main/java/com/sopkathon/domain/subway/repository/SubwayRepository.java b/src/main/java/com/sopkathon/domain/subway/repository/SubwayRepository.java index ae6545a..bb22a50 100644 --- a/src/main/java/com/sopkathon/domain/subway/repository/SubwayRepository.java +++ b/src/main/java/com/sopkathon/domain/subway/repository/SubwayRepository.java @@ -7,4 +7,5 @@ @Repository public interface SubwayRepository extends JpaRepository { + SubwayEntity findBySubwayName(String subwayName); } diff --git a/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java b/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java index ea54694..4e6441e 100644 --- a/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java +++ b/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.stream.Collectors; + @Service @Transactional @RequiredArgsConstructor From 77a52d8ab7ab63f0f52eeb8f28805c0267c3a677 Mon Sep 17 00:00:00 2001 From: woals2840 Date: Sun, 18 May 2025 04:33:30 +0900 Subject: [PATCH 2/5] =?UTF-8?q?[feat/#12]=20api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/place/entity/Category.java | 25 ++++++++++++------- .../place/entity/CategoryConverter.java | 17 +++++++++++++ .../domain/place/entity/PlaceEntity.java | 9 +++---- .../domain/place/service/PlaceService.java | 2 +- .../domain/review/entity/ReviewEntity.java | 8 +++++- .../domain/subway/service/SubwayService.java | 4 +++ 6 files changed, 48 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/sopkathon/domain/place/entity/CategoryConverter.java diff --git a/src/main/java/com/sopkathon/domain/place/entity/Category.java b/src/main/java/com/sopkathon/domain/place/entity/Category.java index 0a6c218..943961c 100644 --- a/src/main/java/com/sopkathon/domain/place/entity/Category.java +++ b/src/main/java/com/sopkathon/domain/place/entity/Category.java @@ -1,5 +1,7 @@ package com.sopkathon.domain.place.entity; +import java.util.Arrays; + import com.sopkathon.global.error.code.ErrorCode; import com.sopkathon.global.error.exception.BusinessException; @@ -15,16 +17,21 @@ public enum Category { PLANTS_AND_FLOWERS("식물·꽃"), OTHER("기타"); - private String name; + private String korName; + + Category(String korName) { + this.korName = korName; + } - Category(String name) {} - public static Category fromName(String name) { - for (Category category : values()) { - if(category.name.equals(name)) { - return category; - } - } - throw new BusinessException(ErrorCode.DATA_NOT_FOUND); + public String getKorName() { + return korName; + } + + public static Category fromKorName(String korName) { + return Arrays.stream(Category.values()) + .filter(c -> c.korName.equals(korName)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Unknown category: " + korName)); } } diff --git a/src/main/java/com/sopkathon/domain/place/entity/CategoryConverter.java b/src/main/java/com/sopkathon/domain/place/entity/CategoryConverter.java new file mode 100644 index 0000000..3c45fcf --- /dev/null +++ b/src/main/java/com/sopkathon/domain/place/entity/CategoryConverter.java @@ -0,0 +1,17 @@ +package com.sopkathon.domain.place.entity; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter(autoApply = true) +public class CategoryConverter implements AttributeConverter { + @Override + public String convertToDatabaseColumn(Category attribute) { + return attribute.getKorName(); // 한글로 저장 + } + + @Override + public Category convertToEntityAttribute(String dbData) { + return Category.fromKorName(dbData); // 한글 → Enum으로 복원 + } +} diff --git a/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java b/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java index b1dd3b5..92cb2d0 100644 --- a/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java +++ b/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java @@ -4,6 +4,7 @@ import com.sopkathon.domain.subway.entity.SubwayEntity; import jakarta.persistence.Column; +import jakarta.persistence.Convert; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; @@ -43,7 +44,7 @@ public class PlaceEntity { @Column(name = "photo_url", nullable = false) private String photoUrl; - @Enumerated(EnumType.STRING) + @Convert(converter = CategoryConverter.class) @Column(name = "category", nullable = false) private Category category; @@ -51,19 +52,15 @@ public class PlaceEntity { @JoinColumn(name = "subway_id", nullable = false) private SubwayEntity subwayEntity; - @ManyToOne(targetEntity = ReviewEntity.class, fetch = FetchType.LAZY) - @JoinColumn(name = "review_id", nullable = false) - private ReviewEntity reviewEntity; @Builder public PlaceEntity(int duration, String description, String mapLink, String photoUrl, Category category, - SubwayEntity subwayEntity, ReviewEntity reviewEntity) { + SubwayEntity subwayEntity) { this.duration = duration; this.description = description; this.mapLink = mapLink; this.photoUrl = photoUrl; this.category = category; this.subwayEntity = subwayEntity; - this.reviewEntity = reviewEntity; } } diff --git a/src/main/java/com/sopkathon/domain/place/service/PlaceService.java b/src/main/java/com/sopkathon/domain/place/service/PlaceService.java index b2bef54..756dfa5 100644 --- a/src/main/java/com/sopkathon/domain/place/service/PlaceService.java +++ b/src/main/java/com/sopkathon/domain/place/service/PlaceService.java @@ -35,6 +35,6 @@ private List getPlacesByCategory(SubwayEntity subwayEntity, String if ("ALL".equals(category)) { return placeRepository.findAllBySubwayEntity(subwayEntity); } - return placeRepository.findAllBySubwayEntityAndCategory(subwayEntity, Category.fromName(category)); + return placeRepository.findAllBySubwayEntityAndCategory(subwayEntity, Category.fromKorName(category)); } } diff --git a/src/main/java/com/sopkathon/domain/review/entity/ReviewEntity.java b/src/main/java/com/sopkathon/domain/review/entity/ReviewEntity.java index c64708b..c0edafd 100644 --- a/src/main/java/com/sopkathon/domain/review/entity/ReviewEntity.java +++ b/src/main/java/com/sopkathon/domain/review/entity/ReviewEntity.java @@ -7,6 +7,8 @@ import java.time.LocalDate; +import com.sopkathon.domain.place.entity.PlaceEntity; + @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -17,7 +19,7 @@ public class ReviewEntity { private Long id; @Column(name = "createdAt", nullable = false) - private LocalDate createdAt; + private String createdAt; @Column(name = "author", nullable = false) private String author; @@ -27,4 +29,8 @@ public class ReviewEntity { @Column(name = "profile_image_url", nullable = false) private String profileImageUrl; + + @ManyToOne(targetEntity = PlaceEntity.class, fetch = FetchType.LAZY) + @JoinColumn(name = "place_id", nullable = false) + private PlaceEntity placeEntity; } diff --git a/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java b/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java index 4e6441e..995875e 100644 --- a/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java +++ b/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java @@ -26,4 +26,8 @@ public SubwayListRes getSubwayList() { return SubwayListRes.from(list); } + + public SubwayEntity getSubwayEntity(String subwayName) { + return subwayRepository.findBySubwayName(subwayName); + } } From 9306553b5a8702e125f46c319a71f2edd705f917 Mon Sep 17 00:00:00 2001 From: woals2840 Date: Sun, 18 May 2025 03:27:55 +0900 Subject: [PATCH 3/5] =?UTF-8?q?[feat/#12]=20=ED=95=84=ED=84=B0=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Conflicts: # src/main/java/com/sopkathon/domain/subway/service/SubwayService.java # Conflicts: # src/main/java/com/sopkathon/domain/subway/repository/SubwayRepository.java --- .../place/controller/PlaceController.java | 21 +++++++++++ .../place/dto/GetPlaceListResponse.java | 11 ++++++ .../domain/place/dto/GetPlaceResponse.java | 26 ++++++++++++++ .../domain/place/entity/Category.java | 6 +++- .../domain/place/entity/PlaceEntity.java | 12 +++---- .../place/repository/PlaceRepository.java | 6 ++++ .../domain/place/service/PlaceService.java | 36 +++++++++++++++++++ .../controller/SimilarPlaceController.java | 8 ----- .../entity/SimilarPlaceEntity.java | 25 ------------- .../repository/SimilarPlaceRepository.java | 9 ----- .../service/SimilarPlaceService.java | 7 ---- .../subway/repository/SubwayRepository.java | 1 + .../domain/subway/service/SubwayService.java | 1 + 13 files changed, 111 insertions(+), 58 deletions(-) create mode 100644 src/main/java/com/sopkathon/domain/place/dto/GetPlaceListResponse.java create mode 100644 src/main/java/com/sopkathon/domain/place/dto/GetPlaceResponse.java delete mode 100644 src/main/java/com/sopkathon/domain/similarPlace/controller/SimilarPlaceController.java delete mode 100644 src/main/java/com/sopkathon/domain/similarPlace/entity/SimilarPlaceEntity.java delete mode 100644 src/main/java/com/sopkathon/domain/similarPlace/repository/SimilarPlaceRepository.java delete mode 100644 src/main/java/com/sopkathon/domain/similarPlace/service/SimilarPlaceService.java diff --git a/src/main/java/com/sopkathon/domain/place/controller/PlaceController.java b/src/main/java/com/sopkathon/domain/place/controller/PlaceController.java index fbd00f5..6d2825d 100644 --- a/src/main/java/com/sopkathon/domain/place/controller/PlaceController.java +++ b/src/main/java/com/sopkathon/domain/place/controller/PlaceController.java @@ -1,7 +1,28 @@ package com.sopkathon.domain.place.controller; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.sopkathon.domain.place.dto.GetPlaceListResponse; +import com.sopkathon.domain.place.service.PlaceService; +import com.sopkathon.global.error.code.SuccessCode; +import com.sopkathon.global.error.dto.SuccessResponse; + +import lombok.RequiredArgsConstructor; + @RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/places") public class PlaceController { + private final PlaceService placeService; + + @GetMapping + public ResponseEntity> getPlaceList(@RequestParam(name = "category", defaultValue = "ALL") String category, + @RequestParam(name = "subway") String subway){ + GetPlaceListResponse getPlaceListResponse = placeService.getPlaceList(category, subway); + return ResponseEntity.ok(SuccessResponse.of(SuccessCode.SUCCESS_FETCH, getPlaceListResponse)); + } } diff --git a/src/main/java/com/sopkathon/domain/place/dto/GetPlaceListResponse.java b/src/main/java/com/sopkathon/domain/place/dto/GetPlaceListResponse.java new file mode 100644 index 0000000..af2869c --- /dev/null +++ b/src/main/java/com/sopkathon/domain/place/dto/GetPlaceListResponse.java @@ -0,0 +1,11 @@ +package com.sopkathon.domain.place.dto; + +import java.util.List; + +public record GetPlaceListResponse( + List getPlaceResponseList +) { + public static GetPlaceListResponse of(List getPlaceResponseList) { + return new GetPlaceListResponse(getPlaceResponseList); + } +} diff --git a/src/main/java/com/sopkathon/domain/place/dto/GetPlaceResponse.java b/src/main/java/com/sopkathon/domain/place/dto/GetPlaceResponse.java new file mode 100644 index 0000000..88aae46 --- /dev/null +++ b/src/main/java/com/sopkathon/domain/place/dto/GetPlaceResponse.java @@ -0,0 +1,26 @@ +package com.sopkathon.domain.place.dto; + + +import com.sopkathon.domain.place.entity.PlaceEntity; + +import lombok.Builder; + +@Builder +public record GetPlaceResponse( + Long placeId, + String name, + String description, + String mapLink, + String photoUrl +) { + + public static GetPlaceResponse of(PlaceEntity placeEntity) { + return GetPlaceResponse.builder() + .placeId(placeEntity.getId()) + .name(placeEntity.getName()) + .description(placeEntity.getDescription()) + .mapLink(placeEntity.getMapLink()) + .photoUrl(placeEntity.getPhotoUrl()) + .build(); + } +} diff --git a/src/main/java/com/sopkathon/domain/place/entity/Category.java b/src/main/java/com/sopkathon/domain/place/entity/Category.java index 49bec1c..0a6c218 100644 --- a/src/main/java/com/sopkathon/domain/place/entity/Category.java +++ b/src/main/java/com/sopkathon/domain/place/entity/Category.java @@ -9,7 +9,11 @@ @Getter public enum Category { - NATURAL("자연"); + ORCHARD("과수원"), + CROPS("밭작물"), + LIVESTOCK("축산"), + PLANTS_AND_FLOWERS("식물·꽃"), + OTHER("기타"); private String name; diff --git a/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java b/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java index 804ca35..b1dd3b5 100644 --- a/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java +++ b/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java @@ -1,7 +1,6 @@ package com.sopkathon.domain.place.entity; import com.sopkathon.domain.review.entity.ReviewEntity; -import com.sopkathon.domain.similarPlace.entity.SimilarPlaceEntity; import com.sopkathon.domain.subway.entity.SubwayEntity; import jakarta.persistence.Column; @@ -29,6 +28,9 @@ public class PlaceEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Column(name = "name", nullable = false) + private String name; + @Column(name = "duration", nullable = false) private int duration; @@ -53,14 +55,9 @@ public class PlaceEntity { @JoinColumn(name = "review_id", nullable = false) private ReviewEntity reviewEntity; - @ManyToOne(targetEntity = SimilarPlaceEntity.class, fetch = FetchType.LAZY) - @JoinColumn(name = "similar_place_id", nullable = false) - private SimilarPlaceEntity similarPlaceEntity; - @Builder - public PlaceEntity(int duration, String description, String mapLink, String photoUrl, Category category, - SubwayEntity subwayEntity, ReviewEntity reviewEntity, SimilarPlaceEntity similarPlaceEntity) { + SubwayEntity subwayEntity, ReviewEntity reviewEntity) { this.duration = duration; this.description = description; this.mapLink = mapLink; @@ -68,6 +65,5 @@ public PlaceEntity(int duration, String description, String mapLink, String phot this.category = category; this.subwayEntity = subwayEntity; this.reviewEntity = reviewEntity; - this.similarPlaceEntity = similarPlaceEntity; } } diff --git a/src/main/java/com/sopkathon/domain/place/repository/PlaceRepository.java b/src/main/java/com/sopkathon/domain/place/repository/PlaceRepository.java index 9f38a80..93b5752 100644 --- a/src/main/java/com/sopkathon/domain/place/repository/PlaceRepository.java +++ b/src/main/java/com/sopkathon/domain/place/repository/PlaceRepository.java @@ -1,10 +1,16 @@ package com.sopkathon.domain.place.repository; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import com.sopkathon.domain.place.entity.Category; import com.sopkathon.domain.place.entity.PlaceEntity; +import com.sopkathon.domain.subway.entity.SubwayEntity; @Repository public interface PlaceRepository extends JpaRepository { + List findAllBySubwayEntity(SubwayEntity subwayEntity); + List findAllBySubwayEntityAndCategory(SubwayEntity subwayEntity, Category category); } diff --git a/src/main/java/com/sopkathon/domain/place/service/PlaceService.java b/src/main/java/com/sopkathon/domain/place/service/PlaceService.java index e39c019..b2bef54 100644 --- a/src/main/java/com/sopkathon/domain/place/service/PlaceService.java +++ b/src/main/java/com/sopkathon/domain/place/service/PlaceService.java @@ -1,4 +1,40 @@ package com.sopkathon.domain.place.service; +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.sopkathon.domain.place.dto.GetPlaceListResponse; +import com.sopkathon.domain.place.dto.GetPlaceResponse; +import com.sopkathon.domain.place.entity.Category; +import com.sopkathon.domain.place.entity.PlaceEntity; +import com.sopkathon.domain.place.repository.PlaceRepository; +import com.sopkathon.domain.subway.entity.SubwayEntity; +import com.sopkathon.domain.subway.service.SubwayService; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor public class PlaceService { + private final PlaceRepository placeRepository; + private final SubwayService SubwayService; + + public GetPlaceListResponse getPlaceList(String category, String subway){ + SubwayEntity subwayEntity = SubwayService.getSubwayEntity(subway); + List placeEntityList = getPlacesByCategory(subwayEntity, category); + + List getPlaceResponseList = placeEntityList.stream() + .map(GetPlaceResponse::of) + .toList(); + + return new GetPlaceListResponse(getPlaceResponseList); + } + + private List getPlacesByCategory(SubwayEntity subwayEntity, String category) { + if ("ALL".equals(category)) { + return placeRepository.findAllBySubwayEntity(subwayEntity); + } + return placeRepository.findAllBySubwayEntityAndCategory(subwayEntity, Category.fromName(category)); + } } diff --git a/src/main/java/com/sopkathon/domain/similarPlace/controller/SimilarPlaceController.java b/src/main/java/com/sopkathon/domain/similarPlace/controller/SimilarPlaceController.java deleted file mode 100644 index 3a5b062..0000000 --- a/src/main/java/com/sopkathon/domain/similarPlace/controller/SimilarPlaceController.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.sopkathon.domain.similarPlace.controller; - -import com.sopkathon.domain.similarPlace.service.SimilarPlaceService; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class SimilarPlaceController { -} diff --git a/src/main/java/com/sopkathon/domain/similarPlace/entity/SimilarPlaceEntity.java b/src/main/java/com/sopkathon/domain/similarPlace/entity/SimilarPlaceEntity.java deleted file mode 100644 index 5bccabd..0000000 --- a/src/main/java/com/sopkathon/domain/similarPlace/entity/SimilarPlaceEntity.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sopkathon.domain.similarPlace.entity; - -import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Table(name = "similar_place") -public class SimilarPlaceEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "duration", nullable = false) - private String duration; - - @Column(name = "description", nullable = false) - private String description; - - @Column(name = "photoUrl", nullable = false) - private String photoUrl; -} diff --git a/src/main/java/com/sopkathon/domain/similarPlace/repository/SimilarPlaceRepository.java b/src/main/java/com/sopkathon/domain/similarPlace/repository/SimilarPlaceRepository.java deleted file mode 100644 index 986e1d3..0000000 --- a/src/main/java/com/sopkathon/domain/similarPlace/repository/SimilarPlaceRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.sopkathon.domain.similarPlace.repository; - -import com.sopkathon.domain.similarPlace.entity.SimilarPlaceEntity; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface SimilarPlaceRepository extends JpaRepository { -} diff --git a/src/main/java/com/sopkathon/domain/similarPlace/service/SimilarPlaceService.java b/src/main/java/com/sopkathon/domain/similarPlace/service/SimilarPlaceService.java deleted file mode 100644 index d0bc775..0000000 --- a/src/main/java/com/sopkathon/domain/similarPlace/service/SimilarPlaceService.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.sopkathon.domain.similarPlace.service; - -import org.springframework.stereotype.Service; - -@Service -public class SimilarPlaceService { -} diff --git a/src/main/java/com/sopkathon/domain/subway/repository/SubwayRepository.java b/src/main/java/com/sopkathon/domain/subway/repository/SubwayRepository.java index 52e8b99..3ea435c 100644 --- a/src/main/java/com/sopkathon/domain/subway/repository/SubwayRepository.java +++ b/src/main/java/com/sopkathon/domain/subway/repository/SubwayRepository.java @@ -10,4 +10,5 @@ @Repository public interface SubwayRepository extends JpaRepository { List findBySubwayNameContaining(String keyword); + SubwayEntity findBySubwayName(String subwayName); } diff --git a/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java b/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java index d9ccdfd..41e1c81 100644 --- a/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java +++ b/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.stream.Collectors; + @Service @Transactional @RequiredArgsConstructor From 88518bf730e2bbc6f25a8b1999a51578e4a6e646 Mon Sep 17 00:00:00 2001 From: woals2840 Date: Sun, 18 May 2025 04:33:30 +0900 Subject: [PATCH 4/5] =?UTF-8?q?[feat/#12]=20api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/place/entity/Category.java | 25 ++++++++++++------- .../place/entity/CategoryConverter.java | 17 +++++++++++++ .../domain/place/entity/PlaceEntity.java | 9 +++---- .../domain/place/service/PlaceService.java | 2 +- .../domain/review/entity/ReviewEntity.java | 8 +++++- .../domain/subway/service/SubwayService.java | 4 +++ 6 files changed, 48 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/sopkathon/domain/place/entity/CategoryConverter.java diff --git a/src/main/java/com/sopkathon/domain/place/entity/Category.java b/src/main/java/com/sopkathon/domain/place/entity/Category.java index 0a6c218..943961c 100644 --- a/src/main/java/com/sopkathon/domain/place/entity/Category.java +++ b/src/main/java/com/sopkathon/domain/place/entity/Category.java @@ -1,5 +1,7 @@ package com.sopkathon.domain.place.entity; +import java.util.Arrays; + import com.sopkathon.global.error.code.ErrorCode; import com.sopkathon.global.error.exception.BusinessException; @@ -15,16 +17,21 @@ public enum Category { PLANTS_AND_FLOWERS("식물·꽃"), OTHER("기타"); - private String name; + private String korName; + + Category(String korName) { + this.korName = korName; + } - Category(String name) {} - public static Category fromName(String name) { - for (Category category : values()) { - if(category.name.equals(name)) { - return category; - } - } - throw new BusinessException(ErrorCode.DATA_NOT_FOUND); + public String getKorName() { + return korName; + } + + public static Category fromKorName(String korName) { + return Arrays.stream(Category.values()) + .filter(c -> c.korName.equals(korName)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Unknown category: " + korName)); } } diff --git a/src/main/java/com/sopkathon/domain/place/entity/CategoryConverter.java b/src/main/java/com/sopkathon/domain/place/entity/CategoryConverter.java new file mode 100644 index 0000000..3c45fcf --- /dev/null +++ b/src/main/java/com/sopkathon/domain/place/entity/CategoryConverter.java @@ -0,0 +1,17 @@ +package com.sopkathon.domain.place.entity; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter(autoApply = true) +public class CategoryConverter implements AttributeConverter { + @Override + public String convertToDatabaseColumn(Category attribute) { + return attribute.getKorName(); // 한글로 저장 + } + + @Override + public Category convertToEntityAttribute(String dbData) { + return Category.fromKorName(dbData); // 한글 → Enum으로 복원 + } +} diff --git a/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java b/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java index b1dd3b5..92cb2d0 100644 --- a/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java +++ b/src/main/java/com/sopkathon/domain/place/entity/PlaceEntity.java @@ -4,6 +4,7 @@ import com.sopkathon.domain.subway.entity.SubwayEntity; import jakarta.persistence.Column; +import jakarta.persistence.Convert; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; @@ -43,7 +44,7 @@ public class PlaceEntity { @Column(name = "photo_url", nullable = false) private String photoUrl; - @Enumerated(EnumType.STRING) + @Convert(converter = CategoryConverter.class) @Column(name = "category", nullable = false) private Category category; @@ -51,19 +52,15 @@ public class PlaceEntity { @JoinColumn(name = "subway_id", nullable = false) private SubwayEntity subwayEntity; - @ManyToOne(targetEntity = ReviewEntity.class, fetch = FetchType.LAZY) - @JoinColumn(name = "review_id", nullable = false) - private ReviewEntity reviewEntity; @Builder public PlaceEntity(int duration, String description, String mapLink, String photoUrl, Category category, - SubwayEntity subwayEntity, ReviewEntity reviewEntity) { + SubwayEntity subwayEntity) { this.duration = duration; this.description = description; this.mapLink = mapLink; this.photoUrl = photoUrl; this.category = category; this.subwayEntity = subwayEntity; - this.reviewEntity = reviewEntity; } } diff --git a/src/main/java/com/sopkathon/domain/place/service/PlaceService.java b/src/main/java/com/sopkathon/domain/place/service/PlaceService.java index b2bef54..756dfa5 100644 --- a/src/main/java/com/sopkathon/domain/place/service/PlaceService.java +++ b/src/main/java/com/sopkathon/domain/place/service/PlaceService.java @@ -35,6 +35,6 @@ private List getPlacesByCategory(SubwayEntity subwayEntity, String if ("ALL".equals(category)) { return placeRepository.findAllBySubwayEntity(subwayEntity); } - return placeRepository.findAllBySubwayEntityAndCategory(subwayEntity, Category.fromName(category)); + return placeRepository.findAllBySubwayEntityAndCategory(subwayEntity, Category.fromKorName(category)); } } diff --git a/src/main/java/com/sopkathon/domain/review/entity/ReviewEntity.java b/src/main/java/com/sopkathon/domain/review/entity/ReviewEntity.java index c64708b..c0edafd 100644 --- a/src/main/java/com/sopkathon/domain/review/entity/ReviewEntity.java +++ b/src/main/java/com/sopkathon/domain/review/entity/ReviewEntity.java @@ -7,6 +7,8 @@ import java.time.LocalDate; +import com.sopkathon.domain.place.entity.PlaceEntity; + @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -17,7 +19,7 @@ public class ReviewEntity { private Long id; @Column(name = "createdAt", nullable = false) - private LocalDate createdAt; + private String createdAt; @Column(name = "author", nullable = false) private String author; @@ -27,4 +29,8 @@ public class ReviewEntity { @Column(name = "profile_image_url", nullable = false) private String profileImageUrl; + + @ManyToOne(targetEntity = PlaceEntity.class, fetch = FetchType.LAZY) + @JoinColumn(name = "place_id", nullable = false) + private PlaceEntity placeEntity; } diff --git a/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java b/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java index 41e1c81..f5a3b0a 100644 --- a/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java +++ b/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java @@ -36,4 +36,8 @@ public SubwayListRes getSubwayListByKeyword(String keyword) { return SubwayListRes.from(subwayList); } + + public SubwayEntity getSubwayEntity(String subwayName) { + return subwayRepository.findBySubwayName(subwayName); + } } From f15220c6e51d1eaa5d5d082c779818067b9f0862 Mon Sep 17 00:00:00 2001 From: woals2840 Date: Sun, 18 May 2025 04:37:47 +0900 Subject: [PATCH 5/5] =?UTF-8?q?[feat/#12]=20=EC=B6=A9=EB=8F=8C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sopkathon/domain/subway/service/SubwayService.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java b/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java index 8fbcbf7..f5a3b0a 100644 --- a/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java +++ b/src/main/java/com/sopkathon/domain/subway/service/SubwayService.java @@ -40,8 +40,4 @@ public SubwayListRes getSubwayListByKeyword(String keyword) { public SubwayEntity getSubwayEntity(String subwayName) { return subwayRepository.findBySubwayName(subwayName); } - - public SubwayEntity getSubwayEntity(String subwayName) { - return subwayRepository.findBySubwayName(subwayName); - } }