Skip to content

Commit

Permalink
Merge pull request #43 from 28th-meetup/fix/store
Browse files Browse the repository at this point in the history
Fix/store
  • Loading branch information
summit45 committed Nov 17, 2023
2 parents 16e2ed7 + ccf83b2 commit 0bf20f4
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/main/java/com/kusitms/jipbap/food/FoodRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import java.util.List;
import java.util.Optional;

public interface FoodRepository extends JpaRepository<Food, Long> {
public interface FoodRepository extends JpaRepository<Food, Long>, FoodRepositoryExtension {

List<Food> findAllByStore(Store store);

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/kusitms/jipbap/food/FoodRepositoryExtension.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.kusitms.jipbap.food;

import com.kusitms.jipbap.user.User;
import org.springframework.data.domain.Pageable;

import java.util.List;

public interface FoodRepositoryExtension {
List<Food> searchByNameOrderBySort(User user, Pageable pageable, String keyword, String standard, String order);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.kusitms.jipbap.food;

import com.kusitms.jipbap.common.utils.QueryDslUtils;
import com.kusitms.jipbap.order.Review;
import com.kusitms.jipbap.order.ReviewRepositoryExtension;
import com.kusitms.jipbap.store.Store;
import com.kusitms.jipbap.user.User;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.util.ArrayList;
import java.util.List;

import static com.kusitms.jipbap.food.QFood.food;
import static com.kusitms.jipbap.order.QOrder.order;
import static com.kusitms.jipbap.order.QReview.review;
import static com.kusitms.jipbap.store.QStore.store;
import static org.springframework.util.ObjectUtils.isEmpty;

@RequiredArgsConstructor
public class FoodRepositoryExtensionImpl implements FoodRepositoryExtension {

private final JPAQueryFactory queryFactory;


@Override
public List<Food> searchByNameOrderBySort(User user, Pageable pageable, String keyword, String standard, String order) {

List<OrderSpecifier<?>> orderSpecifiers = getAllOrderSpecifiersByPageable(pageable);

return queryFactory.selectFrom(food)
.where(
containsKeyword(keyword)
)
.orderBy(orderSpecifiers.toArray(OrderSpecifier[]::new))
.fetch();
}

private BooleanExpression containsKeyword(String keyword) {
if(keyword == null) {
return null;
}
return food.name.contains(keyword);
}

private List<OrderSpecifier<?>> getAllOrderSpecifiersByPageable(Pageable pageable) {

List<OrderSpecifier<?>> orderSpecifierList = new ArrayList<>();

if (!isEmpty(pageable.getSort())) {
for (Sort.Order order : pageable.getSort()) {
Order direction = order.getDirection().isAscending() ? Order.ASC : Order.DESC;
switch (order.getProperty()) {
// 기본 정렬조건: 추천순
case "bookmark": // 추천순
orderSpecifierList.add(QueryDslUtils.getSortedColumn(direction, store, "bookmarkCount"));
orderSpecifierList.add(QueryDslUtils.getSortedColumn(Order.DESC, store, "id"));
break;
case "review": // 후기순
orderSpecifierList.add(QueryDslUtils.getSortedColumn(direction, store, "reviewCount"));
orderSpecifierList.add(QueryDslUtils.getSortedColumn(Order.DESC, store, "id"));
break;
case "rate": // 평점순
orderSpecifierList.add(QueryDslUtils.getSortedColumn(direction, store, "avgRate"));
orderSpecifierList.add(QueryDslUtils.getSortedColumn(Order.DESC, store, "id"));
break;
case "id": // 최신순
orderSpecifierList.add(QueryDslUtils.getSortedColumn(direction, store, "id"));
break;
default:
break;
}
}
}

return orderSpecifierList;
}
}
1 change: 0 additions & 1 deletion src/main/java/com/kusitms/jipbap/food/dto/FoodDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,4 @@ public class FoodDto {
private String description;
private String image;


}
33 changes: 28 additions & 5 deletions src/main/java/com/kusitms/jipbap/store/StoreController.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
import com.kusitms.jipbap.order.dto.OrderDto;
import com.kusitms.jipbap.security.Auth;
import com.kusitms.jipbap.security.AuthInfo;
import com.kusitms.jipbap.store.dto.BookmarkedStoreListResponseDto;
import com.kusitms.jipbap.store.dto.RegisterStoreRequestDto;
import com.kusitms.jipbap.store.dto.StoreDetailResponseDto;
import com.kusitms.jipbap.store.dto.StoreDto;
import com.kusitms.jipbap.store.dto.*;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
Expand Down Expand Up @@ -55,7 +52,7 @@ public CommonResponse<StoreDto> registerStore(
* @return Slice<?>: 슬라이스 단위
*/
@Operation(summary = "가게 리스트 검색")
@GetMapping
@GetMapping("/pagenation-deprecated")
public CommonResponse<Slice<StoreDetailResponseDto>> searchStore(
@Auth AuthInfo authInfo,
@RequestParam(required = false) String keyword,
Expand All @@ -73,6 +70,32 @@ public CommonResponse<Slice<StoreDetailResponseDto>> searchStore(
return new CommonResponse<>(storeService.searchStoreList(authInfo.getEmail(), pageable, keyword, field, direction, lastId));
}

/**
* 가게 및 음식 검색 api - 페이지네이션 미적용
*
* @param keyword: 검색 키워드 (키워드가 포함한 가게를 검색한다)
* @param field: 검색 기준 (추천-bookmark, 후기-review, 평점-rate, 가격-price, 최신-id)
* (추천순: 가게 즐겨찾기 개수 순서, 후기: 가게에 속한 주문에 달린 리뷰 수)
* @param direction: 정렬 기준 (ASC, DESC)
*/
@Operation(summary = "가게 또는 메뉴 검색 (페이지네이션 미적용)")
@GetMapping
public CommonResponse<StoreFoodResponseDto> searchStoreAndFood(
@Auth AuthInfo authInfo,
@RequestParam(required = false) String keyword,
@RequestParam String field,
@RequestParam String direction
) {
Sort sort;
if ("asc".equals(direction) || "ASC".equals(direction)) {
sort = Sort.by(Sort.Direction.ASC, field);
} else {
sort = Sort.by(Sort.Direction.DESC, field);
}
Pageable pageable = PageRequest.of(0, 10000, sort);
return new CommonResponse<>(storeService.searchStoresAndFoods(authInfo.getEmail(), pageable, keyword, field, direction));
}

@Operation(summary = "가게 상세정보")
@GetMapping("/{storeId}")
public CommonResponse<StoreDetailResponseDto> storeDetail(@Auth AuthInfo authInfo, @PathVariable Long storeId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.kusitms.jipbap.user.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
import java.util.Optional;

public interface StoreRepository extends JpaRepository<Store, Long>, StoreRepositoryExtension {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;

import java.util.List;

public interface StoreRepositoryExtension {

Slice<StoreDetailResponseDto> searchByKeywordOrderBySort(User user, Pageable pageable, String keyword, String standard, String order, Long lastId);
List<Store> searchByNameOrderBySort(User user, Pageable pageable, String keyword, String standard, String order);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.kusitms.jipbap.store;

import com.kusitms.jipbap.common.utils.QueryDslUtils;
import com.kusitms.jipbap.food.Food;
import com.kusitms.jipbap.store.dto.StoreDetailResponseDto;
import com.kusitms.jipbap.store.dto.StoreDto;
import com.kusitms.jipbap.user.User;
Expand All @@ -17,6 +18,7 @@
import java.util.ArrayList;
import java.util.List;

import static com.kusitms.jipbap.food.QFood.food;
import static com.kusitms.jipbap.store.QStore.store;
import static org.springframework.util.ObjectUtils.isEmpty;

Expand All @@ -29,7 +31,7 @@ public class StoreRepositoryExtensionImpl implements StoreRepositoryExtension{
@Override
public Slice<StoreDetailResponseDto> searchByKeywordOrderBySort(User user, Pageable pageable, String keyword, String standard, String order, Long lastId) {

List<OrderSpecifier<?>> orderSpecifiers = getAllOrderSpecifiers(pageable);
List<OrderSpecifier<?>> orderSpecifiers = getAllOrderSpecifiersByPageable(pageable);

List<Store> storeList = queryFactory.selectFrom(store)
.where(
Expand Down Expand Up @@ -71,6 +73,19 @@ public Slice<StoreDetailResponseDto> searchByKeywordOrderBySort(User user, Pagea
return new SliceImpl<>(dtoList, pageable, hasNext);
}

@Override
public List<Store> searchByNameOrderBySort(User user, Pageable pageable, String keyword, String standard, String order) {

List<OrderSpecifier<?>> orderSpecifiers = getAllOrderSpecifiersByPageable(pageable);

return queryFactory.selectFrom(store)
.where(
containsKeyword(keyword)
)
.orderBy(orderSpecifiers.toArray(OrderSpecifier[]::new))
.fetch();
}

// user가 즐겨찾기한 store인지 검사
private Boolean isUserBookmarkedStore(User user, Store store) {
return storeBookmarkRepository.existsByUserAndStore(user, store);
Expand Down Expand Up @@ -125,7 +140,7 @@ private BooleanExpression containsKeyword(String keyword) {
return store.name.contains(keyword);
}

private List<OrderSpecifier<?>> getAllOrderSpecifiers(Pageable pageable) {
private List<OrderSpecifier<?>> getAllOrderSpecifiersByPageable(Pageable pageable) {

List<OrderSpecifier<?>> orderSpecifierList = new ArrayList<>();

Expand Down
41 changes: 29 additions & 12 deletions src/main/java/com/kusitms/jipbap/store/StoreService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
import com.amazonaws.services.s3.AmazonS3;
import com.kusitms.jipbap.common.exception.S3RegisterFailureException;
import com.kusitms.jipbap.common.utils.S3Utils;
import com.kusitms.jipbap.store.dto.BookmarkedStoreListResponseDto;
import com.kusitms.jipbap.store.dto.RegisterStoreRequestDto;
import com.kusitms.jipbap.store.dto.StoreDetailResponseDto;
import com.kusitms.jipbap.store.dto.StoreDto;
import com.kusitms.jipbap.food.dto.FoodDto;
import com.kusitms.jipbap.store.dto.*;
import com.kusitms.jipbap.store.exception.StoreExistsException;
import com.kusitms.jipbap.store.exception.StoreNotExistsException;
import com.kusitms.jipbap.user.User;
Expand Down Expand Up @@ -53,14 +51,12 @@ public StoreDto registerStore(String email, RegisterStoreRequestDto dto, List<Mu
}

//이미지가 null이 아닌 경우 s3 업로드
if(image != null && image.size() != 0) {
for(int i=0; i<3; i++) {
if(image.get(i)!=null) {
try {
imageUri[i] = S3Utils.saveFile(amazonS3, bucket, image.get(i));
} catch (IOException e) {
throw new S3RegisterFailureException("가게 이미지 저장 중 오류가 발생했습니다.");
}
if(image != null) {
for(int i=0; i<image.size(); i++) {
try {
imageUri[i] = S3Utils.saveFile(amazonS3, bucket, image.get(i));
} catch (IOException e) {
throw new S3RegisterFailureException("가게 이미지 저장 중 오류가 발생했습니다.");
}
}
}
Expand Down Expand Up @@ -104,6 +100,27 @@ public Slice<StoreDetailResponseDto> searchStoreList(String email, Pageable page
return storeRepository.searchByKeywordOrderBySort(user, pageable, keyword, standard, order, lastId);
}

@Transactional
public StoreFoodResponseDto searchStoresAndFoods(String email, Pageable pageable, String keyword, String standard, String order) {
User user = userRepository.findByEmail(email).orElseThrow(()-> new UserNotFoundException("유저 정보가 존재하지 않습니다."));

List<StoreDetailResponseDto> storeList = storeRepository.searchByNameOrderBySort(user, pageable, keyword, standard, order)
.stream().map(s -> new StoreDetailResponseDto(
new StoreDto(
s.getId(), s.getName(), s.getDescription(), s.getKoreanYn(), s.getAvgRate(), s.getMinOrderAmount(),
new String[]{s.getImage(), s.getImage2(), s.getImage3()}
), storeBookmarkRepository.existsByUserAndStore(user, s))
)
.collect(Collectors.toList());

List<FoodDto> foodList = foodRepository.searchByNameOrderBySort(user, pageable, keyword, standard, order)
.stream().map(f -> new FoodDto(f.getId(), f.getStore().getId(), f.getCategory().getId(), f.getName(), f.getDollarPrice(), f.getCanadaPrice(), f.getDescription(), f.getImage()))
.collect(Collectors.toList());


return new StoreFoodResponseDto(storeList, foodList);
}

@Transactional
public StoreDetailResponseDto getStoreDetail(String email, Long storeId) {
User user = userRepository.findByEmail(email).orElseThrow(()-> new UserNotFoundException("유저 정보가 존재하지 않습니다."));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.kusitms.jipbap.store.dto;

import com.kusitms.jipbap.food.dto.FoodDto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.List;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class StoreFoodResponseDto {

private List<StoreDetailResponseDto> stores;
private List<FoodDto> foods;
}

0 comments on commit 0bf20f4

Please sign in to comment.