diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/config/security/CorsConfig.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/config/security/CorsConfig.java index f437ea21..97b483c9 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/config/security/CorsConfig.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/config/security/CorsConfig.java @@ -15,7 +15,7 @@ public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); // 쿠키나 인증헤더 자격증명 허용 - config.setAllowedOrigins(List.of("http://localhost:5173","http://localhost:63342")); // 허용할 출처 설정 + config.setAllowedOrigins(List.of("http://localhost:5173", "http://localhost:63342")); // 허용할 출처 설정 config.setAllowedMethods(List.of("GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS")); // 메서드 허용 config.setAllowedHeaders(List.of("*")); //클라이언트가 보낼 수 있는 헤더 config.setExposedHeaders(List.of("Authorization")); //클라이언트(브라우저)가 접근할 수 있는 헤더 지정 diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/controller/StoreController.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/controller/StoreController.java index f1dbc8d2..b39a53a8 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/controller/StoreController.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/controller/StoreController.java @@ -46,6 +46,22 @@ public ResponseEntity getAllStores() { description = "모든 주점을 페이지네이션으로 조회합니다." ) @ApiResponse(responseCode = "200", description = "모든 주점 페이지네이션 조회 성공") + public ResponseEntity getAllStoresByPageAndDeparments(Pageable pageable) { + return ResponseEntity + .ok() + .body( + ApiUtils.success( + storeService.getAllStoresByPageAndDeparments(pageable) + ) + ); + } + + @GetMapping("/low-wait/infinite-scroll") + @Operation( + summary = "모든 주점 페이지네이션 조회", + description = "모든 주점을 페이지네이션으로 조회합니다." + ) + @ApiResponse(responseCode = "200", description = "모든 주점 페이지네이션 조회 성공") public ResponseEntity getAllStores(Pageable pageable) { return ResponseEntity .ok() diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreDepartmentReadResponse.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreDepartmentReadResponse.java new file mode 100644 index 00000000..fe04584f --- /dev/null +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreDepartmentReadResponse.java @@ -0,0 +1,23 @@ +package com.nowait.applicationuser.store.dto; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@AllArgsConstructor +@Builder +public class StoreDepartmentReadResponse { + + private List storePageReadDtos; + private boolean hasNext; + + public static StoreDepartmentReadResponse of(List storePageReadDtos, boolean hasNext) { + return StoreDepartmentReadResponse.builder() + .storePageReadDtos(storePageReadDtos) + .hasNext(hasNext) + .build(); + } +} diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreImageUploadResponse.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreImageUploadResponse.java index 62822b3d..39dbf2a0 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreImageUploadResponse.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreImageUploadResponse.java @@ -10,12 +10,14 @@ @Builder public class StoreImageUploadResponse { private final Long id; + private final Long storeId; private final String imageUrl; private final ImageType imageType; public static StoreImageUploadResponse fromEntity(StoreImage storeImage) { return StoreImageUploadResponse.builder() .id(storeImage.getId()) + .storeId(storeImage.getStore().getStoreId()) .imageUrl(storeImage.getImageUrl()) .imageType(storeImage.getImageType()) .build(); diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StorePageReadDto.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StorePageReadDto.java new file mode 100644 index 00000000..050cc091 --- /dev/null +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StorePageReadDto.java @@ -0,0 +1,54 @@ +package com.nowait.applicationuser.store.dto; + +import java.time.LocalDateTime; +import java.util.List; + +import com.nowait.domaincorerdb.store.entity.ImageType; +import com.nowait.domaincorerdb.store.entity.Store; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@AllArgsConstructor +@Builder +public class StorePageReadDto { + private Long storeId; + private Long departmentId; + private String departmentName; + private String name; + private String location; + private String description; + private StoreImageUploadResponse profileImage; + private List bannerImages; + private Boolean isActive; + private Boolean deleted; + private LocalDateTime createdAt; + + public static StorePageReadDto fromEntity(Store store, List allImages, String departmentName) { + + StoreImageUploadResponse profile = allImages.stream() + .filter(image -> image.getImageType() == ImageType.PROFILE) + .findFirst() + .orElse(null); + + List banners = allImages.stream() + .filter(image -> image.getImageType() == ImageType.BANNER) + .toList(); + + return StorePageReadDto.builder() + .createdAt(store.getCreatedAt()) + .storeId(store.getStoreId()) + .departmentId(store.getDepartmentId()) + .departmentName(departmentName) + .name(store.getName()) + .location(store.getLocation()) + .description(store.getDescription()) + .isActive(store.getIsActive()) + .deleted(store.getDeleted()) + .profileImage(profile) + .bannerImages(banners) + .build(); + } +} diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreService.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreService.java index f8c854ad..f8bf540a 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreService.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreService.java @@ -4,6 +4,8 @@ import org.springframework.data.domain.Pageable; +import com.nowait.applicationuser.store.dto.StoreDepartmentReadResponse; +import com.nowait.applicationuser.store.dto.StorePageReadDto; import com.nowait.applicationuser.store.dto.StoreReadDto; import com.nowait.applicationuser.store.dto.StoreReadResponse; @@ -13,8 +15,10 @@ public interface StoreService { StoreReadResponse getAllStoresByPage(Pageable pageable); + StoreDepartmentReadResponse getAllStoresByPageAndDeparments(Pageable pageable); + StoreReadDto getStoreByStoreId(Long storeId); - List searchStoresByName(String name); + List searchStoresByName(String name); } diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreServiceImpl.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreServiceImpl.java index 39e94c03..566e91ea 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreServiceImpl.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreServiceImpl.java @@ -1,15 +1,21 @@ package com.nowait.applicationuser.store.service; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.nowait.applicationuser.store.dto.StoreDepartmentReadResponse; import com.nowait.applicationuser.store.dto.StoreImageUploadResponse; +import com.nowait.applicationuser.store.dto.StorePageReadDto; import com.nowait.applicationuser.store.dto.StoreReadDto; import com.nowait.applicationuser.store.dto.StoreReadResponse; +import com.nowait.domaincorerdb.department.entity.Department; +import com.nowait.domaincorerdb.department.repository.DepartmentRepository; import com.nowait.domaincorerdb.store.entity.Store; import com.nowait.domaincorerdb.store.entity.StoreImage; import com.nowait.domaincorerdb.store.exception.StoreNotFoundException; @@ -25,6 +31,7 @@ public class StoreServiceImpl implements StoreService { private final StoreRepository storeRepository; private final StoreImageRepository storeImageRepository; + private final DepartmentRepository departmentRepository; @Override @@ -67,6 +74,55 @@ public StoreReadResponse getAllStoresByPage(Pageable pageable) { return StoreReadResponse.of(storeRead, hasNext); } + @Override + @Transactional(readOnly = true) + public StoreDepartmentReadResponse getAllStoresByPageAndDeparments(Pageable pageable) { + // 1) 페이징된 Store 스냅샷 조회 + Slice slice = storeRepository.findAllByDeletedFalseOrderByStoreIdAsc(pageable); + List stores = slice.getContent(); + + // 2) 각 StoreId / Department ID 추출 + List storeIds = stores.stream() + .map(Store::getStoreId) + .toList(); + List deptIds = stores.stream() + .map(Store::getDepartmentId) + .distinct() + .toList(); + + // 3) 각 StoreId에 해당하는 이미지 조회 + List allImages = storeImageRepository.findByStore_StoreIdIn(storeIds); + Map> imageMap = allImages.stream() + .map(StoreImageUploadResponse::fromEntity) + .collect(Collectors.groupingBy( + StoreImageUploadResponse::getStoreId + )); + + + // 4) 각 DepartmentId에 해당하는 이름 조회 + List allDepts = departmentRepository.findAllById(deptIds); + Map deptNameMap = allDepts.stream() + .collect(Collectors.toMap( + Department::getId, + Department::getName + )); + + // 5) Dto 매핑 + List content = stores.stream() + .map(store -> { + List imgs = imageMap + .getOrDefault(store.getStoreId(), List.of()); + String departmentName = deptNameMap + .getOrDefault(store.getDepartmentId(), "Unknown Department"); + return StorePageReadDto.fromEntity(store, imgs, departmentName); + }) + .toList(); + + boolean hasNext = slice.hasNext(); + + return StoreDepartmentReadResponse.of(content, hasNext); + } + @Override @Transactional(readOnly = true) public StoreReadDto getStoreByStoreId(Long storeId) { @@ -84,19 +140,47 @@ public StoreReadDto getStoreByStoreId(Long storeId) { } @Override - public List searchStoresByName(String name) { + public List searchStoresByName(String name) { if (name == null || name.isBlank()) { throw new StoreParamEmptyException(); } + // 1) 페이징된 Store 스냅샷 조회 List stores = storeRepository.findByNameContainingIgnoreCaseAndDeletedFalse(name); + + // 2) 각 StoreId / Department ID 추출 + List storeIds = stores.stream() + .map(Store::getStoreId) + .toList(); + List deptIds = stores.stream() + .map(Store::getDepartmentId) + .distinct() + .toList(); + + // 3) 각 StoreId에 해당하는 이미지 조회 + List allImages = storeImageRepository.findByStore_StoreIdIn(storeIds); + Map> imageMap = allImages.stream() + .map(StoreImageUploadResponse::fromEntity) + .collect(Collectors.groupingBy( + StoreImageUploadResponse::getStoreId + )); + + // 4) 각 DepartmentId에 해당하는 이름 조회 + List allDepts = departmentRepository.findAllById(deptIds); + Map deptNameMap = allDepts.stream() + .collect(Collectors.toMap( + Department::getId, + Department::getName + )); + + // 5) Dto 매핑 return stores.stream() .map(store -> { - List images = storeImageRepository.findByStore(store); - List imageDto = images.stream() - .map(StoreImageUploadResponse::fromEntity) - .toList(); - return StoreReadDto.fromEntity(store, imageDto); + List imgs = imageMap + .getOrDefault(store.getStoreId(), List.of()); + String departmentName = deptNameMap + .getOrDefault(store.getDepartmentId(), "Unknown Department"); + return StorePageReadDto.fromEntity(store, imgs, departmentName); }) .toList(); } diff --git a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/department/repository/DepartmentRepository.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/department/repository/DepartmentRepository.java index c2ee280b..023d2409 100644 --- a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/department/repository/DepartmentRepository.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/department/repository/DepartmentRepository.java @@ -3,6 +3,8 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import com.nowait.domaincorerdb.department.entity.Department; + @Repository -public interface DepartmentRepository extends JpaRepository { +public interface DepartmentRepository extends JpaRepository { } diff --git a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreImageRepository.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreImageRepository.java index 1ad6929e..45639941 100644 --- a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreImageRepository.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreImageRepository.java @@ -15,5 +15,7 @@ public interface StoreImageRepository extends JpaRepository { List findByStore(Store store); + List findByStore_StoreIdIn(List storeIds); + Optional findByStoreStoreIdAndImageType(Long storeId, ImageType imageType); }