Skip to content
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] 찜한 스토어 조회(최신순) - #23 #26

Merged
merged 3 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package com.cakey.store.dto;

import lombok.AccessLevel;
import lombok.Builder;

import java.util.List;

@Builder(access = AccessLevel.PRIVATE)
public record StoreInfoListBylikesRes(
int nextLikesCursor,
Long lastStoreId,
Expand Down
37 changes: 8 additions & 29 deletions cakey-api/src/main/java/com/cakey/store/service/StoreService.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,20 @@ public StoreInfoListBylikesRes getStoreInfoListByStationAndLikes(final Long user
final List<StoreInfoDto> storeInfoDtos = storeFacade.findStoreInfoByStationAndLikes(userId, station, likesCursor, lastStoreId, size);

// 조회한 store들의 ID 추출
final List<Long> storeIds = getStoreIds(storeInfoDtos);
final List<Long> storeIds = storeFacade.getStoreIds(storeInfoDtos);

//메인 이미지 map
final Map<Long, List<CakeMainImageDto>> mainImageMap = getMainImageMap(storeIds);
final Map<Long, List<CakeMainImageDto>> mainImageMap = cakeFacade.getMainImageMap(storeIds);

//storInfo 생성
final List<StoreInfo> storeInfos = getStoreInfo(storeInfoDtos, mainImageMap);

//스토어 개수 조회
final int storeCount = getStoreCount(station);
final int storeCount = storeFacade.getStoreCountByStation(station);

final int nextLikesCursor = calculateNextCursor(storeInfoDtos);

final Long LastStoreId = calculateLastStoreId(storeInfoDtos);
final Long LastStoreId = storeFacade.calculateLastStoreId(storeInfoDtos);

// StoreInfoListRes 반환
return StoreInfoListBylikesRes.of(nextLikesCursor, LastStoreId, storeCount, storeInfos);
Expand All @@ -70,19 +70,19 @@ public StoreInfoListByLatest getStoreInfoListByStationAndLatest(final Long userI
final List<StoreInfoDto> storeInfoDtos = storeFacade.findStoreInfoByStationAndLatest(userId, station, storeIdCursor, size);

// 조회한 store들의 ID 추출
final List<Long> storeIds = getStoreIds(storeInfoDtos);
final List<Long> storeIds = storeFacade.getStoreIds(storeInfoDtos);

//메인 이미지 map
final Map<Long, List<CakeMainImageDto>> mainImageMap = getMainImageMap(storeIds);
final Map<Long, List<CakeMainImageDto>> mainImageMap = cakeFacade.getMainImageMap(storeIds);

//storInfo 생성
final List<StoreInfo> storeInfos = getStoreInfo(storeInfoDtos, mainImageMap);

//스토어 개수 조회
final int storeCount = getStoreCount(station);
final int storeCount = storeFacade.getStoreCountByStation(station);

//마지막 storeID 조회
final Long LastStoreId = calculateLastStoreId(storeInfoDtos);
final Long LastStoreId = storeFacade.calculateLastStoreId(storeInfoDtos);

return StoreInfoListByLatest.of(LastStoreId, storeCount, storeInfos);
}
Expand All @@ -102,27 +102,13 @@ private int calculateNextCursor(final List<StoreInfoDto> storeInfoDtos) {
return storeInfoDtos.isEmpty() ? -1 : storeInfoDtos.get(storeInfoDtos.size() - 1).getStoreLikesCount();
}

private Long calculateLastStoreId(final List<StoreInfoDto> storeInfoDtos) {
return storeInfoDtos.isEmpty() ? null : storeInfoDtos.get(storeInfoDtos.size() - 1).getStoreId();
}

//스토어 id들 조회
private List<Long> getStoreIds(final List<StoreInfoDto> storeInfoDtos) {
return storeInfoDtos.stream()
.map(StoreInfoDto::getStoreId)
.toList();
}

//메인이미지 매핑
private Map<Long, List<CakeMainImageDto>> getMainImageMap(final List<Long> storeIds) {
//스토어 대표 이미지 조회
final List<CakeMainImageDto> cakeMainImageDtos1 = cakeFacade.findMainImageByStoreIds(storeIds);

// 이미지를 storeId 기준으로 그룹화
return cakeMainImageDtos1.stream()
.collect(Collectors.groupingBy(CakeMainImageDto::getStoreId));
}

//storeInfo 생성
private List<StoreInfo> getStoreInfo(final List<StoreInfoDto> storeInfoDtos, final Map<Long, List<CakeMainImageDto>> imageMap) {
return storeInfoDtos.stream()
Expand All @@ -146,11 +132,4 @@ private List<StoreInfo> getStoreInfo(final List<StoreInfoDto> storeInfoDtos, fin
})
.toList();
}

//스토어 개수 조회
private int getStoreCount(final Station station) {
return (station == Station.ALL)
? storeFacade.countAllStores()
: storeFacade.countStoresByStation(station);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.cakey.storelikes.controller;

import com.cakey.common.response.ApiResponseUtil;
import com.cakey.common.response.BaseResponse;
import com.cakey.common.response.SuccessCode;
import com.cakey.storelikes.service.StoreLikesService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/v1/store/likes")
@RequiredArgsConstructor
public class StoreLikesController {
private final StoreLikesService storeLikesService;

@GetMapping("/latest")
public ResponseEntity<BaseResponse<?>> getLatestStoreByUserLikes(
@RequestHeader(value = "userId", required = true) final long userId,
@RequestParam(value = "storeIdCursor", defaultValue = "0", required = false) final Long storeIdCursor,
@RequestParam(value = "size", defaultValue = "10", required = false) final int size
) {
return ApiResponseUtil.success(
SuccessCode.OK,
storeLikesService.getLatestStoreLikesByUser(userId, storeIdCursor, size));

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.cakey.storelikes.dto;

import com.cakey.store.dto.StoreInfo;

import java.util.List;

public record StoreLatestLikedByUser(
Long lastStoreId,
long storeCount,
List<StoreInfo> stores
) {
public static StoreLatestLikedByUser fromStoreInfo(final Long lastStoreId,
final long storeCount,
final List<StoreInfo> stores) {
return new StoreLatestLikedByUser(lastStoreId, storeCount, stores);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.cakey.storelikes.service;

import com.cakey.cake.dto.CakeMainImageDto;
import com.cakey.cake.facade.CakeFacade;
import com.cakey.store.domain.Station;
import com.cakey.store.dto.StoreInfo;
import com.cakey.store.dto.StoreInfoDto;
import com.cakey.store.facade.StoreFacade;
import com.cakey.storelikes.dto.StoreLatestLikedByUser;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class StoreLikesService {

private final StoreFacade storeFacade;
private final CakeFacade cakeFacade;

public StoreLatestLikedByUser getLatestStoreLikesByUser(final long userId,
final Long storeIdCursor,
final int size) {

//페이지네이션으로 스토어 조회
final List<StoreInfoDto> storeInfoDtos = storeFacade.findLatestStoresLikedByUser(userId, storeIdCursor, size);

//조회한 store들의 id 추출
final List<Long> storeIds = storeFacade.getStoreIds(storeInfoDtos);

//메인 이미지 매핑
final Map<Long, List<CakeMainImageDto>> mainImageMap = cakeFacade.getMainImageMap(storeIds);

//storeInfo 생성
final List<StoreInfo> storeInfos = getStoreInfo(storeInfoDtos, mainImageMap);

//스토어 개수 조회
final int storeCount = storeInfos.size();

//마지막 스토어 아이디
final Long lastStoreId = storeFacade.calculateLastStoreId(storeInfoDtos);

return StoreLatestLikedByUser.fromStoreInfo(lastStoreId, storeCount, storeInfos);
}


//storeInfo 생성
private List<StoreInfo> getStoreInfo(final List<StoreInfoDto> storeInfoDtos, final Map<Long, List<CakeMainImageDto>> imageMap) {
return storeInfoDtos.stream()
.map(storeInfoDto -> {
// storeId에 해당하는 이미지 리스트 가져오기
final List<StoreInfo.StoreMainImage> images = imageMap.getOrDefault(storeInfoDto.getStoreId(), List.of())
.stream()
.map(image -> StoreInfo.StoreMainImage.of(image.getImageId(), image.getImageUrl()))
.toList();

// StoreInfo 생성
return StoreInfo.of(
storeInfoDto.getStoreId(),
storeInfoDto.getName(),
Station.valueOf(String.valueOf(storeInfoDto.getStation())),
storeInfoDto.getAddress(),
storeInfoDto.getStoreLikesCount(),
storeInfoDto.isLiked(),
images
);
})
.toList();
}

}
15 changes: 14 additions & 1 deletion cakey-domain/src/main/java/com/cakey/cake/facade/CakeFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,26 @@
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
public class CakeFacade {
private final CakeRetriever cakeRetriever;

public List<CakeMainImageDto> findMainImageByStoreIds(List<Long> storeIds) {
//스토어 대표 이미지 조회
public List<CakeMainImageDto> findMainImageByStoreIds(final List<Long> storeIds) {
return cakeRetriever.findMainImageByStoreIds(storeIds);
}

//메인이미지 매핑
public Map<Long, List<CakeMainImageDto>> getMainImageMap(final List<Long> storeIds) {
//스토어 대표 이미지 조회
final List<CakeMainImageDto> cakeMainImageDtos = findMainImageByStoreIds(storeIds);

// 이미지를 storeId 기준으로 그룹화
return cakeMainImageDtos.stream()
.collect(Collectors.groupingBy(CakeMainImageDto::getStoreId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public class CakeRetriever {
private final CakeRepository cakeRepository;

public List<CakeMainImageDto> findMainImageByStoreIds(List<Long> storeIds) {
public List<CakeMainImageDto> findMainImageByStoreIds(final List<Long> storeIds) {
return cakeRepository.findMainImageByStoreIds(storeIds);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
import java.util.List;

public interface CakeRepositoryCustom {
List<CakeMainImageDto> findMainImageByStoreIds(List<Long> storeIds);
List<CakeMainImageDto> findMainImageByStoreIds(final List<Long> storeIds);

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ public StoreInfoDto(Long storeId,
Station station,
String address,
boolean isLiked,
int nextCursor) {
int storeLikesCount) {
this.storeId = storeId;
this.name = name;
this.station = station;
this.address = address;
this.isLiked = isLiked;
this.storeLikesCount = nextCursor;
this.storeLikesCount = storeLikesCount;
}
}
33 changes: 29 additions & 4 deletions cakey-domain/src/main/java/com/cakey/store/facade/StoreFacade.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.cakey.store.facade;

import com.cakey.OrderBy;
import com.cakey.store.domain.Station;
import com.cakey.store.dto.StoreCoordianteDto;
import com.cakey.store.dto.StoreInfoDto;
Expand All @@ -12,12 +11,14 @@
@Component
@RequiredArgsConstructor
public class StoreFacade {

private final StoreRetriever storeRetriever;

public List<StoreCoordianteDto> findCoordinatesByStation(final Station station) {
return storeRetriever.findCoordinateByStation(station);
}

//스토어 조회(인기순)
public List<StoreInfoDto> findStoreInfoByStationAndLikes(final Long userId,
final Station station,
final int likesCursor,
Expand All @@ -26,21 +27,45 @@ public List<StoreInfoDto> findStoreInfoByStationAndLikes(final Long userId,
return storeRetriever.findStoreInfoByStationAndLikes(userId, station, likesCursor, lastStoreId, size);
}

//스토어 조회(최신순)
public List<StoreInfoDto> findStoreInfoByStationAndLatest(final Long userId,
final Station station,
final Long storeCursorId,
final int size) {

return storeRetriever.findStoreInfoByStationAndLatest(userId, station, storeCursorId, size);
}
//찜한 스토어(최신순)
public List<StoreInfoDto> findLatestStoresLikedByUser(final Long userId,
final Long storeIdCursor,
final int size) {
return storeRetriever.findStoresLikedByUser(userId, storeIdCursor, size);
}

// 조회한 store들의 ID 추출
public List<Long> getStoreIds(final List<StoreInfoDto> storeInfoDtos) {
return storeInfoDtos.stream()
.map(StoreInfoDto::getStoreId)
.toList();
}

//스토어 개수 조회
public int getStoreCountByStation(final Station station) {
return (station == Station.ALL)
? countAllStores()
: countStoresByStation(station);
}

public int countAllStores() {
private int countAllStores() {
return storeRetriever.countAllStores();
}

public int countStoresByStation(final Station station) {
private int countStoresByStation(final Station station) {
return storeRetriever.countStoresByStation(station);
}

//마지막 스토어아이디 계싼
public Long calculateLastStoreId(final List<StoreInfoDto> storeInfoDtos) {
return storeInfoDtos.isEmpty() ? null : storeInfoDtos.get(storeInfoDtos.size() - 1).getStoreId();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public List<StoreCoordianteDto> findCoordinateByStation(final Station station) {
return storeRepository.findStoreCoordinatesByStation(station);
}

//스토어 조회(인기순)
public List<StoreInfoDto> findStoreInfoByStationAndLikes(final Long userId,
final Station station,
final int likesCursor,
Expand All @@ -26,13 +27,21 @@ public List<StoreInfoDto> findStoreInfoByStationAndLikes(final Long userId,
return storeRepository.findStoreInfoByStationAndLikes(userId, station, likesCursor, lastStoreId, size);
}

//스토어 조회(최신순)
public List<StoreInfoDto> findStoreInfoByStationAndLatest(final Long userId,
final Station station,
final Long storeIdCursor,
final int size) {
return storeRepository.findStoreInfoByStationAndLatest(userId, station, storeIdCursor, size);
}

//찜한 스토어 조회(최신순)
public List<StoreInfoDto> findStoresLikedByUser(final long userId,
final Long storeIdCursor,
final int size) {
return storeRepository.findStoresLikedByUser(userId, storeIdCursor, size);
}

public int countAllStores() {
return storeRepository.countAllStores();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ List<StoreInfoDto> findStoreInfoByStationAndLatest(final Long userId,
final Long storeIdCursor,
final int size);

List<StoreInfoDto> findStoresLikedByUser(final long userId,
final Long storeIdCursor,
final int size);
}
Loading