Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into NABI-252--yejin--fix--…
Browse files Browse the repository at this point in the history
…suggestion-available-cards
  • Loading branch information
born-A committed Nov 20, 2023
2 parents 8368563 + 0ec3eba commit 0fea86d
Show file tree
Hide file tree
Showing 14 changed files with 235 additions and 116 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package org.prgrms.nabimarketbe.domain.card.api;

import java.util.List;

import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
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;
import org.prgrms.nabimarketbe.domain.card.dto.response.CardCreateResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.wrapper.CardPagingResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.CardUpdateResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.projection.CardFamousResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.wrapper.CardListResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.wrapper.CardPagingResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.wrapper.CardResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.wrapper.CardUserResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.CardUpdateResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.wrapper.CardSuggestionResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.wrapper.CardUserResponseDTO;
import org.prgrms.nabimarketbe.domain.card.entity.CardStatus;
import org.prgrms.nabimarketbe.domain.card.service.CardService;
import org.prgrms.nabimarketbe.domain.category.entity.CategoryEnum;
Expand All @@ -31,10 +34,7 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import java.util.List;

@RestController
@RequestMapping("/api/v1/cards")
Expand All @@ -58,43 +58,43 @@ public ResponseEntity<SingleResult<CardResponseDTO<CardCreateResponseDTO>>> crea
return ResponseEntity.ok(ResponseFactory.getSingleResult(card));
}

@GetMapping("/{cardId}")
public ResponseEntity<SingleResult<CardUserResponseDTO>> getCardById(
@RequestHeader(value = "Authorization", required = false) String token,
@PathVariable Long cardId) {
CardUserResponseDTO cardSingleReadResponseDTO = cardService.getCardById(token, cardId);
@GetMapping("/{cardId}")
public ResponseEntity<SingleResult<CardUserResponseDTO>> getCardById(
@RequestHeader(value = "Authorization", required = false) String token,
@PathVariable Long cardId) {
CardUserResponseDTO cardSingleReadResponseDTO = cardService.getCardById(token, cardId);

return ResponseEntity.ok(ResponseFactory.getSingleResult(cardSingleReadResponseDTO));
}
return ResponseEntity.ok(ResponseFactory.getSingleResult(cardSingleReadResponseDTO));
}

@GetMapping
public ResponseEntity<SingleResult<CardPagingResponseDTO>> getCardsByCondition(
@RequestParam(required = false) CategoryEnum category,
@RequestParam(required = false) PriceRange priceRange,
@RequestParam(required = false) List<CardStatus> status,
@RequestParam(required = false) String cardTitle,
@RequestParam(required = false) String cursorId,
@RequestParam Integer size
@RequestParam(required = false) CategoryEnum category,
@RequestParam(required = false) PriceRange priceRange,
@RequestParam(required = false) List<CardStatus> status,
@RequestParam(required = false) String cardTitle,
@RequestParam(required = false) String cursorId,
@RequestParam Integer size
) {
CardPagingResponseDTO cardListReadPagingResponseDTO = cardService.getCardsByCondition(
category,
priceRange,
status,
cardTitle,
cursorId,
size
category,
priceRange,
status,
cardTitle,
cursorId,
size
);

return ResponseEntity.ok(ResponseFactory.getSingleResult(cardListReadPagingResponseDTO));
}

@GetMapping("/{cardId}/available-cards")
public ResponseEntity<SingleResult<CardListResponseDTO<CardSuggestionResponseDTO>>> getSuggestionAvailableCards(
@RequestHeader(name = "Authorization") String token,
@PathVariable(name = "cardId") Long targetCardId
@RequestHeader(name = "Authorization") String token,
@PathVariable(name = "cardId") Long targetCardId
) {
CardListResponseDTO<CardSuggestionResponseDTO> cardListResponseDTO
= cardService.getSuggestionAvailableCards(token, targetCardId);
= cardService.getSuggestionAvailableCards(token, targetCardId);

return ResponseEntity.ok(ResponseFactory.getSingleResult(cardListResponseDTO));
}
Expand All @@ -116,9 +116,9 @@ public ResponseEntity<SingleResult<CardResponseDTO<CardUpdateResponseDTO>>> upda

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

@GetMapping("/{status}/my-cards")
public ResponseEntity<SingleResult<CardPagingResponseDTO>> getMyCardsByStatus(
@RequestHeader(name = "authorization") String token,
@PathVariable CardStatus status,
@RequestParam(required = false) String cursorId,
@RequestParam Integer size
@RequestHeader(name = "authorization") String token,
@PathVariable CardStatus status,
@RequestParam(required = false) String cursorId,
@RequestParam Integer size
) {
CardPagingResponseDTO cardListReadPagingResponseDTO = cardService.getMyCardsByStatus(
token,
status,
cursorId,
size
token,
status,
cursorId,
size
);

return ResponseEntity.ok(ResponseFactory.getSingleResult(cardListReadPagingResponseDTO));
}

@DeleteMapping("/{cardId}")
public ResponseEntity<CommonResult> deleteCardById(
@RequestHeader(name = "authorization") String token,
@PathVariable Long cardId
@RequestHeader(name = "authorization") String token,
@PathVariable Long cardId
) {
cardService.deleteCardById(token, cardId);

return ResponseEntity.ok(ResponseFactory.getSuccessResult());
}

@GetMapping("/popular")
public ResponseEntity<SingleResult<CardListResponseDTO<CardFamousResponseDTO>>> getCardsByPopularity() {
CardListResponseDTO<CardFamousResponseDTO> cardList = cardService.getCardsByPopularity();

return ResponseEntity.ok(ResponseFactory.getSingleResult(cardList));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.prgrms.nabimarketbe.domain.card.dto.response.projection;

import lombok.Getter;
import org.prgrms.nabimarketbe.domain.item.entity.PriceRange;

@Getter
public class CardFamousResponseDTO {
private Long cardId;

private String itemName;

private PriceRange priceRange;

private String thumbnail;
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
package org.prgrms.nabimarketbe.domain.card.repository;

import java.util.List;

import org.prgrms.nabimarketbe.domain.card.dto.response.projection.CardFamousResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.wrapper.CardPagingResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.wrapper.CardSuggestionResponseDTO;
import org.prgrms.nabimarketbe.domain.card.entity.CardStatus;
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 java.util.List;

public interface CardRepositoryCustom {
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
);

CardPagingResponseDTO getMyCardsByStatus(
User user,
CardStatus status,
String cursorId,
Integer size
User user,
CardStatus status,
String cursorId,
Integer size
);

List<CardSuggestionResponseDTO> getSuggestionAvailableCards(
Long userId,
Long targetCardId
Long userId,
Long targetCardId
);

List<CardFamousResponseDTO> getCardsByPopularity();
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
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.StringExpressions;
import com.querydsl.core.types.dsl.StringTemplate;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.prgrms.nabimarketbe.domain.card.dto.response.projection.CardFamousResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.projection.CardInfoResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.projection.CardListReadResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.wrapper.CardPagingResponseDTO;
Expand All @@ -17,7 +20,10 @@
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.QueryDslUtil;
import org.springframework.data.domain.Sort;

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

import static org.prgrms.nabimarketbe.domain.card.entity.QCard.card;
Expand All @@ -26,6 +32,8 @@

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

private final JPAQueryFactory jpaQueryFactory;

@Override
Expand Down Expand Up @@ -59,7 +67,10 @@ public CardPagingResponseDTO getCardsByCondition(
priceRangeEquals(priceRange),
titleEquals(cardTitle)
)
.orderBy(card.createdDate.desc()) // 디폴트는 생성일자 최신순 정렬
.orderBy(getOrderSpecifier(Sort.by(
Sort.Order.desc("createdDate"),
Sort.Order.desc("cardId")
)))
.limit(size)
.fetch();

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

@Override
public List<CardFamousResponseDTO> getCardsByPopularity() {
List<CardFamousResponseDTO> cardList = jpaQueryFactory
.select(
Projections.fields(
CardFamousResponseDTO.class,
card.cardId,
card.item.itemName,
card.item.priceRange,
card.thumbnail
)
)
.from(card)
.where(statusEquals(CardStatus.TRADE_AVAILABLE))
.orderBy(card.viewCount.desc(), card.dibCount.desc())
.limit(FAMOUS_CARD_SIZE)
.fetch();

return cardList;
}

private BooleanExpression statusEquals(CardStatus status) {
if (status == null) {
return null;
}

return card.status.eq(status);
}

private BooleanExpression cursorId(String cursorId) {
if (cursorId == null) {
return null;
Expand Down Expand Up @@ -200,4 +240,15 @@ 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
Expand Up @@ -7,6 +7,7 @@
import org.prgrms.nabimarketbe.domain.card.dto.response.CardCreateResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.CardDetailResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.CardUpdateResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.projection.CardFamousResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.wrapper.CardListResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.wrapper.CardPagingResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.wrapper.CardResponseDTO;
Expand Down Expand Up @@ -159,7 +160,7 @@ public CardResponseDTO<CardUpdateResponseDTO> updateCardById(
return new CardResponseDTO<>(cardUpdateResponseDTO);
}

@Transactional(readOnly = true)
@Transactional
public CardUserResponseDTO getCardById(
String token,
Long cardId
Expand Down Expand Up @@ -315,7 +316,7 @@ public List<CardSuggestionResponseDTO> getSuggestionResultCardList(
) {
Card targetCard = cardRepository.findById(targetId)
.orElseThrow(() -> new BaseException(ErrorCode.CARD_NOT_FOUND));

Boolean pokeAvailable = targetCard.getPokeAvailable();
PriceRange priceRange = targetCard.getItem().getPriceRange();

Expand All @@ -325,6 +326,14 @@ public List<CardSuggestionResponseDTO> getSuggestionResultCardList(
return parseCardListWithOnlyOffer(cardList, priceRange);
}

@Transactional(readOnly = true)
public CardListResponseDTO<CardFamousResponseDTO> getCardsByPopularity() {
List<CardFamousResponseDTO> cardList = cardRepository.getCardsByPopularity();
CardListResponseDTO<CardFamousResponseDTO> response = new CardListResponseDTO<>(cardList);

return response;
}

private List<CardSuggestionResponseDTO> parseCardListWithPokeAndOffer(
List<CardSuggestionResponseDTO> cardList,
PriceRange targetPriceRange
Expand Down
Loading

0 comments on commit 0fea86d

Please sign in to comment.