diff --git a/src/main/java/com/gongspot/project/domain/place/controller/PlaceController.java b/src/main/java/com/gongspot/project/domain/place/controller/PlaceController.java index 55f0e06..346988e 100644 --- a/src/main/java/com/gongspot/project/domain/place/controller/PlaceController.java +++ b/src/main/java/com/gongspot/project/domain/place/controller/PlaceController.java @@ -5,7 +5,9 @@ import com.gongspot.project.domain.like.dto.LikeResponseDTO; import com.gongspot.project.domain.like.service.LikeQueryService; import com.gongspot.project.domain.place.converter.PlaceConverter; +import com.gongspot.project.domain.place.dto.PlaceRequestDTO; import com.gongspot.project.domain.place.dto.PlaceResponseDTO; +import com.gongspot.project.domain.place.entity.Place; import com.gongspot.project.domain.place.service.PlaceCommandService; import com.gongspot.project.domain.place.service.PlaceQueryService; import com.gongspot.project.domain.review.dto.ReviewResponseDTO; @@ -14,6 +16,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -130,4 +133,22 @@ public ApiResponse viewCongestion(@PathVariable("placeId") Long placeId) placeCommandService.viewCongestion(user.getId(), placeId); return ApiResponse.onSuccess("포인트 사용 완료"); } + + @PreAuthorize("hasRole('ADMIN')") + @Operation(summary = "공간 정보 수정 (관리자)") + @PatchMapping("/{placeId}") + public ApiResponse patchPlace( + @PathVariable("placeId") Long placeId, + @RequestBody PlaceRequestDTO.PlacePatchDTO patchDTO) { + placeCommandService.updatePlace(placeId, patchDTO); + return ApiResponse.onSuccess(); + } + + @PreAuthorize("hasRole('ADMIN')") + @Operation(summary = "공간 정보 상세 조회 (관리자)") + @GetMapping("/details/{placeId}") + public ApiResponse getPlaceDetail(@PathVariable("placeId") Long placeId) { + Place place = placeQueryService.getPlaceDetails(placeId); + return ApiResponse.onSuccess(PlaceConverter.toPlaceDetailDTO(place)); + } } \ No newline at end of file diff --git a/src/main/java/com/gongspot/project/domain/place/converter/PlaceConverter.java b/src/main/java/com/gongspot/project/domain/place/converter/PlaceConverter.java index 718dd57..9cb15dc 100644 --- a/src/main/java/com/gongspot/project/domain/place/converter/PlaceConverter.java +++ b/src/main/java/com/gongspot/project/domain/place/converter/PlaceConverter.java @@ -150,5 +150,19 @@ public static PlaceResponseDTO.SearchPlaceListDTO toSearchPlaceListDTO(List purposeList; + PlaceEnum type; + List moodList; + List facilityList; + List locationList; + } +} diff --git a/src/main/java/com/gongspot/project/domain/place/dto/PlaceResponseDTO.java b/src/main/java/com/gongspot/project/domain/place/dto/PlaceResponseDTO.java index 574cbd3..753b101 100644 --- a/src/main/java/com/gongspot/project/domain/place/dto/PlaceResponseDTO.java +++ b/src/main/java/com/gongspot/project/domain/place/dto/PlaceResponseDTO.java @@ -116,4 +116,20 @@ public static class VisitedPlaceListDTO { private Integer totalCount; private List visitedPlaces; } + + @Getter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class PlaceDetailDTO { + String name; + String locationInfo; + String openingHours; + String phoneNumber; + List purpose; + PlaceEnum type; + List mood; + List facilities; + List location; + } } diff --git a/src/main/java/com/gongspot/project/domain/place/entity/Place.java b/src/main/java/com/gongspot/project/domain/place/entity/Place.java index b23d9de..0c82923 100644 --- a/src/main/java/com/gongspot/project/domain/place/entity/Place.java +++ b/src/main/java/com/gongspot/project/domain/place/entity/Place.java @@ -9,8 +9,7 @@ import com.gongspot.project.domain.home.entity.HotCheck; import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; +import lombok.*; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/gongspot/project/domain/place/repository/PlaceRepository.java b/src/main/java/com/gongspot/project/domain/place/repository/PlaceRepository.java index 862678d..6b53a78 100644 --- a/src/main/java/com/gongspot/project/domain/place/repository/PlaceRepository.java +++ b/src/main/java/com/gongspot/project/domain/place/repository/PlaceRepository.java @@ -1,6 +1,7 @@ package com.gongspot.project.domain.place.repository; import com.gongspot.project.common.enums.*; +import com.gongspot.project.domain.place.dto.PlaceRequestDTO; import com.gongspot.project.domain.place.dto.PlaceResponseDTO; import com.gongspot.project.domain.place.entity.Place; import com.gongspot.project.domain.place.entity.QPlace; diff --git a/src/main/java/com/gongspot/project/domain/place/repository/PlaceRepositoryCustom.java b/src/main/java/com/gongspot/project/domain/place/repository/PlaceRepositoryCustom.java index a9e6b5b..59ce7fa 100644 --- a/src/main/java/com/gongspot/project/domain/place/repository/PlaceRepositoryCustom.java +++ b/src/main/java/com/gongspot/project/domain/place/repository/PlaceRepositoryCustom.java @@ -1,7 +1,9 @@ package com.gongspot.project.domain.place.repository; import com.gongspot.project.common.enums.*; +import com.gongspot.project.domain.place.dto.PlaceRequestDTO; import com.gongspot.project.domain.place.dto.PlaceResponseDTO; +import com.gongspot.project.domain.place.entity.Place; import java.util.List; diff --git a/src/main/java/com/gongspot/project/domain/place/repository/PlaceRepositoryImpl.java b/src/main/java/com/gongspot/project/domain/place/repository/PlaceRepositoryImpl.java index 82852fe..38fd96f 100644 --- a/src/main/java/com/gongspot/project/domain/place/repository/PlaceRepositoryImpl.java +++ b/src/main/java/com/gongspot/project/domain/place/repository/PlaceRepositoryImpl.java @@ -3,16 +3,23 @@ import com.gongspot.project.common.code.status.ErrorStatus; import com.gongspot.project.common.enums.*; import com.gongspot.project.common.exception.BusinessException; +import com.gongspot.project.domain.place.dto.PlaceRequestDTO; import com.gongspot.project.domain.place.dto.PlaceResponseDTO; +import com.gongspot.project.domain.place.entity.Place; +import com.gongspot.project.domain.place.entity.QPlace; import com.gongspot.project.domain.search.entity.RecentSearch; import com.gongspot.project.domain.user.entity.User; import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.Expression; import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.Expressions; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPQLQuery; import com.querydsl.jpa.impl.JPAQueryFactory; +import com.querydsl.jpa.impl.JPAUpdateClause; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.List; @@ -31,8 +38,14 @@ public class PlaceRepositoryImpl implements PlaceRepositoryCustom { public List findFilteredPlaces(Long userId, String keyword, List purpose, PlaceEnum type, List mood, List facilities, List location, Long page) { BooleanBuilder builder = new BooleanBuilder(); + String normalizedKeyword = keyword.toLowerCase().replace(" ", ""); + if (keyword != null && !keyword.isBlank()) { - builder.and(place.name.containsIgnoreCase(keyword)); + builder.and( + Expressions.stringTemplate( + "REPLACE(LOWER({0}), ' ', '')", place.name + ).like("%" + normalizedKeyword + "%") + ); } else { BooleanBuilder filterGroup = new BooleanBuilder(); diff --git a/src/main/java/com/gongspot/project/domain/place/service/PlaceCommandService.java b/src/main/java/com/gongspot/project/domain/place/service/PlaceCommandService.java index cda4da5..8e743cc 100644 --- a/src/main/java/com/gongspot/project/domain/place/service/PlaceCommandService.java +++ b/src/main/java/com/gongspot/project/domain/place/service/PlaceCommandService.java @@ -1,7 +1,10 @@ package com.gongspot.project.domain.place.service; +import com.gongspot.project.domain.place.dto.PlaceRequestDTO; + public interface PlaceCommandService { void isLikedPlace(Long UserId, Long placeId); void unLikedPlace(Long UserId, Long placeId); void viewCongestion(Long userId, Long placeId); + void updatePlace(Long placeId, PlaceRequestDTO.PlacePatchDTO patchDTO); } diff --git a/src/main/java/com/gongspot/project/domain/place/service/PlaceCommandServiceImpl.java b/src/main/java/com/gongspot/project/domain/place/service/PlaceCommandServiceImpl.java index 0e43e0b..a41bc57 100644 --- a/src/main/java/com/gongspot/project/domain/place/service/PlaceCommandServiceImpl.java +++ b/src/main/java/com/gongspot/project/domain/place/service/PlaceCommandServiceImpl.java @@ -4,6 +4,7 @@ import com.gongspot.project.common.exception.BusinessException; import com.gongspot.project.domain.like.entity.Like; import com.gongspot.project.domain.like.repository.LikeRepository; +import com.gongspot.project.domain.place.dto.PlaceRequestDTO; import com.gongspot.project.domain.place.entity.Place; import com.gongspot.project.domain.point.entity.Point; import com.gongspot.project.domain.point.repository.PointRepository; @@ -94,4 +95,21 @@ public void viewCongestion(Long userId, Long placeId) { pointRepository.save(point); } + + @Override + @Transactional + public void updatePlace(Long placeId, PlaceRequestDTO.PlacePatchDTO patchDTO) { + Place place = placeRepository.findById(placeId) + .orElseThrow(() -> new BusinessException(ErrorStatus.PLACE_NOT_FOUND)); + + if (patchDTO.getLocationInfo() != null) place.setLocationInfo(patchDTO.getLocationInfo()); + if (patchDTO.getOpeningHours() != null) place.setOpeningHours(patchDTO.getOpeningHours()); + if (patchDTO.getPhoneNumber() != null) place.setPhoneNumber(patchDTO.getPhoneNumber()); + if (patchDTO.getType() != null) place.setType(patchDTO.getType()); + + if (patchDTO.getPurposeList() != null) place.setPurpose(patchDTO.getPurposeList()); + if (patchDTO.getMoodList() != null) place.setMood(patchDTO.getMoodList()); + if (patchDTO.getFacilityList() != null) place.setFacilities(patchDTO.getFacilityList()); + if (patchDTO.getLocationList() != null) place.setLocation(patchDTO.getLocationList()); + } } \ No newline at end of file diff --git a/src/main/java/com/gongspot/project/domain/place/service/PlaceQueryService.java b/src/main/java/com/gongspot/project/domain/place/service/PlaceQueryService.java index ec3ca5a..b3db69d 100644 --- a/src/main/java/com/gongspot/project/domain/place/service/PlaceQueryService.java +++ b/src/main/java/com/gongspot/project/domain/place/service/PlaceQueryService.java @@ -2,6 +2,7 @@ import com.gongspot.project.common.enums.*; import com.gongspot.project.domain.place.dto.PlaceResponseDTO; +import com.gongspot.project.domain.place.entity.Place; import java.util.List; @@ -9,4 +10,5 @@ public interface PlaceQueryService { PlaceResponseDTO.GetPlaceDTO getPlace(Long userId, Long placeId); PlaceResponseDTO.VisitedPlaceListDTO getVisitedPlaces(Long userId); List getFilteredPlaces(Long userId, String keyword, List purpose, PlaceEnum type, List mood, List facilities, List location, Long page); + Place getPlaceDetails(Long placeId); } diff --git a/src/main/java/com/gongspot/project/domain/place/service/PlaceQueryServiceImpl.java b/src/main/java/com/gongspot/project/domain/place/service/PlaceQueryServiceImpl.java index d3c71ba..a3603ef 100644 --- a/src/main/java/com/gongspot/project/domain/place/service/PlaceQueryServiceImpl.java +++ b/src/main/java/com/gongspot/project/domain/place/service/PlaceQueryServiceImpl.java @@ -17,6 +17,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; import java.time.LocalDateTime; @@ -81,6 +82,7 @@ public PlaceResponseDTO.VisitedPlaceListDTO getVisitedPlaces(Long userId) { } @Override + @Transactional public List getFilteredPlaces(Long userId, String keyword, List purpose, PlaceEnum type, List mood, List facilities, List location, Long page) { if (keyword != null) { User user = userRepository.findById(userId) @@ -95,4 +97,10 @@ public List getFilteredPlaces(Long userId, Stri } return placeRepository.findFilteredPlaces(userId, keyword, purpose, type, mood, facilities, location, page); } + + @Override + public Place getPlaceDetails(Long placeId) { + return placeRepository.findById(placeId) + .orElseThrow(() -> new BusinessException(ErrorStatus.PLACE_NOT_FOUND)); + } } \ No newline at end of file