Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into NABI-261--yejin--fix--…
Browse files Browse the repository at this point in the history
…suggestion-available-list
  • Loading branch information
born-A committed Nov 20, 2023
2 parents bccf596 + 52a7c48 commit 44f0454
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.prgrms.nabimarketbe.domain.card.service.CardService;
import org.prgrms.nabimarketbe.domain.category.entity.CategoryEnum;
import org.prgrms.nabimarketbe.domain.item.entity.PriceRange;
import org.prgrms.nabimarketbe.global.util.OrderCondition;
import org.prgrms.nabimarketbe.global.util.ResponseFactory;
import org.prgrms.nabimarketbe.global.util.model.CommonResult;
import org.prgrms.nabimarketbe.global.util.model.SingleResult;
Expand Down Expand Up @@ -76,13 +77,17 @@ public ResponseEntity<SingleResult<CardPagingResponseDTO>> getCardsByCondition(
@RequestParam(required = false) String cursorId,
@RequestParam Integer size
) {
// TODO: 클라이언트에게 정렬 조건 받도록 추후에 수정하면 더 유연할 듯
OrderCondition condition = OrderCondition.CARD_CREATED_DESC;

CardPagingResponseDTO cardListReadPagingResponseDTO = cardService.getCardsByCondition(
category,
priceRange,
status,
cardTitle,
cursorId,
size
size,
condition
);

return ResponseEntity.ok(ResponseFactory.getSingleResult(cardListReadPagingResponseDTO));
Expand Down Expand Up @@ -116,7 +121,7 @@ public ResponseEntity<SingleResult<CardResponseDTO<CardUpdateResponseDTO>>> upda

@PutMapping("/status/{cardId}")
public ResponseEntity<CommonResult> updateCardStatusById(
@RequestHeader(name = "authorization") String token,
@RequestHeader(name = "Authorization") String token,
@PathVariable Long cardId,
@RequestBody CardStatusUpdateRequestDTO cardStatusUpdateRequestDTO
) {
Expand All @@ -131,7 +136,7 @@ public ResponseEntity<CommonResult> updateCardStatusById(

@GetMapping("/{status}/my-cards")
public ResponseEntity<SingleResult<CardPagingResponseDTO>> getMyCardsByStatus(
@RequestHeader(name = "authorization") String token,
@RequestHeader(name = "Authorization") String token,
@PathVariable CardStatus status,
@RequestParam(required = false) String cursorId,
@RequestParam Integer size
Expand All @@ -148,7 +153,7 @@ public ResponseEntity<SingleResult<CardPagingResponseDTO>> getMyCardsByStatus(

@DeleteMapping("/{cardId}")
public ResponseEntity<CommonResult> deleteCardById(
@RequestHeader(name = "authorization") String token,
@RequestHeader(name = "Authorization") String token,
@PathVariable Long cardId
) {
cardService.deleteCardById(token, cardId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.prgrms.nabimarketbe.domain.category.entity.CategoryEnum;
import org.prgrms.nabimarketbe.domain.item.entity.PriceRange;
import org.prgrms.nabimarketbe.domain.user.entity.User;
import org.springframework.data.domain.Pageable;

import java.util.List;

Expand All @@ -17,7 +18,7 @@ CardPagingResponseDTO getCardsByCondition(
List<CardStatus> status,
String title,
String cursorId,
Integer size
Pageable pageable
);

CardPagingResponseDTO getMyCardsByStatus(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package org.prgrms.nabimarketbe.domain.card.repository;

import com.querydsl.core.types.ConstantImpl;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.core.types.dsl.StringExpressions;
import com.querydsl.core.types.dsl.StringTemplate;
import com.querydsl.jpa.impl.JPAQueryFactory;
Expand All @@ -20,18 +19,19 @@
import org.prgrms.nabimarketbe.domain.item.entity.PriceRange;
import org.prgrms.nabimarketbe.domain.suggestion.dto.response.projection.SuggestionInfo;
import org.prgrms.nabimarketbe.domain.user.entity.User;
import org.prgrms.nabimarketbe.global.util.CursorPaging;
import org.prgrms.nabimarketbe.global.util.QueryDslUtil;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

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

import static org.prgrms.nabimarketbe.domain.card.entity.QCard.card;
import static org.prgrms.nabimarketbe.domain.item.entity.QItem.item;
import static org.prgrms.nabimarketbe.domain.suggestion.entity.QSuggestion.suggestion;

@RequiredArgsConstructor
public class CardRepositoryImpl implements CardRepositoryCustom {
public class CardRepositoryImpl implements CardRepositoryCustom, CursorPaging {
private static final int FAMOUS_CARD_SIZE = 5;

private final JPAQueryFactory jpaQueryFactory;
Expand All @@ -43,7 +43,7 @@ public CardPagingResponseDTO getCardsByCondition(
List<CardStatus> status,
String cardTitle,
String cursorId,
Integer size
Pageable pageable
) {
List<CardListReadResponseDTO> cardList = jpaQueryFactory.select(
Projections.fields(
Expand All @@ -67,14 +67,11 @@ public CardPagingResponseDTO getCardsByCondition(
priceRangeEquals(priceRange),
titleEquals(cardTitle)
)
.orderBy(getOrderSpecifier(Sort.by(
Sort.Order.desc("createdDate"),
Sort.Order.desc("cardId")
)))
.limit(size)
.orderBy(QueryDslUtil.getOrderSpecifier(pageable.getSort(), card))
.limit(pageable.getPageSize())
.fetch();

String nextCursor = cardList.size() < size ? null : generateCursor(cardList.get(cardList.size() - 1));
String nextCursor = cardList.size() < pageable.getPageSize() ? null : generateCursor(cardList.get(cardList.size() - 1));

return new CardPagingResponseDTO(cardList, nextCursor);
}
Expand Down Expand Up @@ -106,7 +103,15 @@ public CardPagingResponseDTO getMyCardsByStatus(
card.status.eq(status),
card.user.eq(user)
)
.orderBy(card.createdDate.desc()) // 디폴트는 생성일자 최신순 정렬
.orderBy(
QueryDslUtil.getOrderSpecifier(
Sort.by(
Sort.Order.desc("createdDate"),
Sort.Order.desc("cardId")
),
card
)
)
.limit(size)
.fetch();

Expand Down Expand Up @@ -149,6 +154,29 @@ public List<CardSuggestionResponseDTO> getSuggestionAvailableCards(
return cardList;
}

@Override
public BooleanExpression cursorId(String cursorId) {
if (cursorId == null) {
return null;
}

// 생성일자
StringTemplate dateCursorTemplate = Expressions.stringTemplate(
"DATE_FORMAT({0}, {1})",
card.createdDate,
ConstantImpl.create("%Y%m%d%H%i%s")
);

// pk
StringExpression pkCursorTemplate = StringExpressions.lpad(
card.cardId.stringValue(),
8,
'0'
);

return dateCursorTemplate.concat(pkCursorTemplate).lt(cursorId);
}

@Override
public List<CardFamousResponseDTO> getCardsByPopularity() {
List<CardFamousResponseDTO> cardList = jpaQueryFactory
Expand Down Expand Up @@ -178,25 +206,6 @@ private BooleanExpression statusEquals(CardStatus status) {
return card.status.eq(status);
}

private BooleanExpression cursorId(String cursorId) {
if (cursorId == null) {
return null;
}

StringTemplate stringTemplate = Expressions.stringTemplate(
"DATE_FORMAT({0}, {1})",
card.createdDate, // 디폴트는 생성일자 최신순 정렬
ConstantImpl.create("%Y%m%d%H%i%s")
);

return stringTemplate.concat(StringExpressions.lpad(
card.cardId.stringValue(),
8,
'0'
))
.lt(cursorId);
}

private BooleanExpression categoryEquals(CategoryEnum category) {
if (category == null) {
return null;
Expand Down Expand Up @@ -240,15 +249,4 @@ private String generateCursor(CardListReadResponseDTO cardListReadResponseDTO) {
.replace(":", "")
+ String.format("%08d", cardListReadResponseDTO.getCardId());
}

private OrderSpecifier[] getOrderSpecifier(Sort sort) {
List<OrderSpecifier> orders = new ArrayList<>();

for (Sort.Order order : sort) { // Sort에 여러 정렬 기준을 담을 수 있음
Order direction = order.getDirection().isAscending() ? Order.ASC : Order.DESC;
orders.add(QueryDslUtil.getSortedColumn(direction, card, order.getProperty()));
}

return orders.toArray(OrderSpecifier[]::new);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.prgrms.nabimarketbe.domain.card.service;

import lombok.RequiredArgsConstructor;
import java.util.ArrayList;
import java.util.List;

import org.prgrms.nabimarketbe.domain.card.dto.request.CardCreateRequestDTO;
import org.prgrms.nabimarketbe.domain.card.dto.request.CardStatusUpdateRequestDTO;
import org.prgrms.nabimarketbe.domain.card.dto.request.CardUpdateRequestDTO;
Expand Down Expand Up @@ -33,12 +35,13 @@
import org.prgrms.nabimarketbe.domain.user.service.CheckService;
import org.prgrms.nabimarketbe.global.error.BaseException;
import org.prgrms.nabimarketbe.global.error.ErrorCode;
import org.prgrms.nabimarketbe.global.util.OrderCondition;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
Expand Down Expand Up @@ -74,26 +77,21 @@ public CardResponseDTO<CardCreateResponseDTO> createCard(

Card card = cardCreateRequestDTO.toCardEntity(item, user);

CardImage thumbnail = new CardImage(cardCreateRequestDTO.thumbnail(), card);

// images 비어있을 경우..
List<CardImage> images = Optional.ofNullable(cardCreateRequestDTO.images())
.orElse(new ArrayList<>())
List<CardImage> images = cardCreateRequestDTO.images()
.stream()
.map(i -> i.toCardImageEntity(card))
.toList();

List<CardImage> newCardImages = addThumbnail(images, thumbnail);

Item savedItem = itemRepository.save(item);
Card savedCard = cardRepository.save(card);

cardImageBatchRepository.saveAll(newCardImages);
cardImageBatchRepository.saveAll(images);

CardCreateResponseDTO cardCreateResponseDTO = CardCreateResponseDTO.of(
savedCard,
savedItem,
newCardImages
images
);

return new CardResponseDTO<>(cardCreateResponseDTO);
Expand Down Expand Up @@ -139,22 +137,17 @@ public CardResponseDTO<CardUpdateResponseDTO> updateCardById(

cardImageRepository.deleteAllByCard(card);

CardImage thumbnail = new CardImage(cardUpdateRequestDTO.thumbnail(), card);

List<CardImage> images = Optional.ofNullable(cardUpdateRequestDTO.images())
.orElse(new ArrayList<>())
List<CardImage> images = cardUpdateRequestDTO.images()
.stream()
.map(i -> i.toCardImageEntity(card))
.toList();

List<CardImage> newCardImages = addThumbnail(images, thumbnail);

cardImageBatchRepository.saveAll(newCardImages);
cardImageBatchRepository.saveAll(images);

CardUpdateResponseDTO cardUpdateResponseDTO = CardUpdateResponseDTO.of(
card,
item,
newCardImages
images
);

return new CardResponseDTO<>(cardUpdateResponseDTO);
Expand Down Expand Up @@ -201,20 +194,29 @@ public CardUserResponseDTO getCardById(

@Transactional(readOnly = true)
public CardPagingResponseDTO getCardsByCondition(
CategoryEnum category,
PriceRange priceRange,
List<CardStatus> status,
String title,
String cursorId,
Integer size
CategoryEnum category,
PriceRange priceRange,
List<CardStatus> status,
String title,
String cursorId,
Integer size,
OrderCondition orderCondition
) {

// 전달 받은 orderCondition 과 page size 에 맞게 pageRequest 를 구성 후 repo 에 넘김
PageRequest pageRequest = PageRequest.of(
0,
size,
getSortFromOrderCondition(orderCondition)
);

return cardRepository.getCardsByCondition(
category,
priceRange,
status,
title,
cursorId,
size
pageRequest
);
}

Expand Down Expand Up @@ -388,4 +390,16 @@ private List<CardImage> addThumbnail(

return newCardImages;
}

private Sort getSortFromOrderCondition(OrderCondition orderCondition) {
switch (orderCondition) {
case CARD_CREATED_DESC -> {
return Sort.by(
Sort.Order.desc("createdDate"),
Sort.Order.desc("cardId")
);
}
default -> throw new BaseException(ErrorCode.INVALID_ORDER_CONDITION);
}
}
}
Loading

0 comments on commit 44f0454

Please sign in to comment.