Skip to content

Commit

Permalink
Merge pull request #23 from team-nabi/NABI-123--junhyuk--feat--sugges…
Browse files Browse the repository at this point in the history
…tion-available-list

Nabi 123  junhyuk  feat  suggestion available list
  • Loading branch information
hi-june authored Nov 9, 2023
2 parents 42f10e0 + 25259ca commit cd6a139
Show file tree
Hide file tree
Showing 17 changed files with 427 additions and 32 deletions.
7 changes: 6 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,14 @@ dependencies {
implementation 'com.auth0:java-jwt:4.4.0'

compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

testCompileOnly 'org.projectlombok:lombok'
testRuntimeOnly 'com.h2database:h2'
testAnnotationProcessor 'org.projectlombok:lombok'

runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'

testImplementation 'org.springframework.security:spring-security-test'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
import lombok.RequiredArgsConstructor;

import org.prgrms.nabimarketbe.domain.card.dto.request.CardCreateRequestDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.CardCreateResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.CardListReadPagingResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.CardSingleReadResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.*;
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 @@ -20,8 +18,6 @@

import java.util.List;

import java.util.List;

@RestController
@RequestMapping("/api/v1/cards")
@RequiredArgsConstructor
Expand All @@ -34,11 +30,17 @@ public class CardController {
MediaType.APPLICATION_JSON_VALUE
}, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<SingleResult<CardCreateResponseDTO>> createCard(
@RequestHeader(name = "authorization") String token,
@RequestPart("thumbnail") MultipartFile thumbnail,
@RequestPart("dto") CardCreateRequestDTO cardCreateRequestDTO,
@RequestPart("files") List<MultipartFile> files
) {
CardCreateResponseDTO cardCreateResponseDTO = cardService.createCard(cardCreateRequestDTO,thumbnail,files);
CardCreateResponseDTO cardCreateResponseDTO = cardService.createCard(
token,
cardCreateRequestDTO,
thumbnail,
files
);

return ResponseEntity.ok(ResponseFactory.getSingleResult(cardCreateResponseDTO));
}
Expand Down Expand Up @@ -71,4 +73,15 @@ public ResponseEntity<SingleResult<CardListReadPagingResponseDTO>> getCardsByCon

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

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

return ResponseEntity.ok(ResponseFactory.getSingleResult(cardListResponseDTO));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@

import org.prgrms.nabimarketbe.domain.card.entity.Card;
import org.prgrms.nabimarketbe.domain.card.entity.TradeType;
import org.prgrms.nabimarketbe.domain.cardimage.dto.request.CardImageCreateRequestDTO;
import org.prgrms.nabimarketbe.domain.category.entity.Category;
import org.prgrms.nabimarketbe.domain.category.entity.CategoryEnum;
import org.prgrms.nabimarketbe.domain.item.entity.Item;
import org.prgrms.nabimarketbe.domain.item.entity.PriceRange;
import org.prgrms.nabimarketbe.domain.user.entity.User;
import org.prgrms.nabimarketbe.global.annotation.ValidEnum;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;

public record CardCreateRequestDTO( // TODO: images form-data로 받기
@NotBlank(message = "공백을 허용하지 않습니다.")
Expand Down Expand Up @@ -46,14 +45,15 @@ public Item toItemEntity(Category category) {
.build();
}

public Card toCardEntity(Item item) {
public Card toCardEntity(Item item, User user) {
return Card.builder()
.cardTitle(cardTitle)
.content(content)
.tradeArea(tradeArea)
.poke(pokeAvailable)
.tradeType(tradeType)
.item(item)
.user(user)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.prgrms.nabimarketbe.domain.card.dto.response;

import java.util.List;

public record CardListResponseDTO<T>(
List<T> cardList
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.prgrms.nabimarketbe.domain.card.dto.response;

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

@Getter
@NoArgsConstructor
public class SuggestionAvailableCardResponseDTO {
private Long cardId;
private String thumbNail;
private String itemName;
private PriceRange priceRange;
private SuggestionType suggestionType;

public void updateSuggestionType(SuggestionType suggestionType) {
this.suggestionType = suggestionType;
}
}
15 changes: 12 additions & 3 deletions src/main/java/org/prgrms/nabimarketbe/domain/card/entity/Card.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.prgrms.nabimarketbe.domain.user.entity.User;
import org.prgrms.nabimarketbe.global.BaseEntity;
import org.prgrms.nabimarketbe.domain.item.entity.Item;
import org.prgrms.nabimarketbe.global.error.BaseException;
Expand Down Expand Up @@ -65,24 +66,31 @@ public class Card extends BaseEntity {
@JoinColumn(name = "item_id")
private Item item;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

@Builder
private Card(
String cardTitle,
String thumbNailImage,
String content,
String tradeArea,
Boolean poke,
TradeType tradeType,
Item item
Item item,
User user
) {
if (cardTitle.isBlank() || content.isBlank() || tradeArea.isBlank()) {
if (cardTitle.isBlank() || content.isBlank() || tradeArea.isBlank()) { // TODO: 구조 변경 후 thumbNailImage null 처리 추가
throw new BaseException(ErrorCode.UNKNOWN);
}

if (poke == null || tradeType == null || item == null) {
if (poke == null || tradeType == null || item == null || user == null) {
throw new BaseException(ErrorCode.UNKNOWN);
}

this.cardTitle = cardTitle;
this.thumbNailImage = thumbNailImage;
this.content = content;
this.tradeArea = tradeArea;
this.poke = poke;
Expand All @@ -91,6 +99,7 @@ private Card(
this.viewCount = 0;
this.dibCount = 0;
this.item = item;
this.user = user;
}

public void updateThumbNailImage(String url) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

import org.prgrms.nabimarketbe.domain.card.entity.Card;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface CardRepository extends JpaRepository<Card, Long>, CardRepositoryCustom {
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.prgrms.nabimarketbe.domain.card.repository;

import org.prgrms.nabimarketbe.domain.card.dto.response.CardListReadPagingResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.SuggestionAvailableCardResponseDTO;
import org.prgrms.nabimarketbe.domain.card.entity.CardStatus;
import org.prgrms.nabimarketbe.domain.category.entity.CategoryEnum;
import org.prgrms.nabimarketbe.domain.item.entity.PriceRange;
Expand All @@ -16,4 +17,10 @@ CardListReadPagingResponseDTO getCardsByCondition(
String cursorId,
Integer size
);

List<SuggestionAvailableCardResponseDTO> getSuggestionAvailableCards(
Long userId,
PriceRange priceRange,
Boolean pokeAvailable
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
import lombok.RequiredArgsConstructor;
import org.prgrms.nabimarketbe.domain.card.dto.response.CardListReadPagingResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.CardListReadResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.SuggestionAvailableCardResponseDTO;
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.suggestion.entity.SuggestionType;

import java.util.List;

Expand Down Expand Up @@ -63,6 +65,32 @@ public CardListReadPagingResponseDTO getCardsByCondition(
return new CardListReadPagingResponseDTO(cardList, nextCursor);
}

@Override
public List<SuggestionAvailableCardResponseDTO> getSuggestionAvailableCards(
Long userId,
PriceRange priceRange,
Boolean pokeAvailable
) {
List<SuggestionAvailableCardResponseDTO> cardList = jpaQueryFactory.select(
Projections.fields(
SuggestionAvailableCardResponseDTO.class,
card.cardId,
card.thumbNailImage.as("thumbNail"),
item.itemName,
item.priceRange
))
.from(card)
.leftJoin(item).on(card.item.itemId.eq(item.itemId))
.where(card.user.userId.eq(userId))
.fetch();

return getSuggestionResultCardList(
pokeAvailable,
priceRange,
cardList
);
}

private BooleanExpression cursorId(String cursorId){
if (cursorId == null) {
return null;
Expand Down Expand Up @@ -125,4 +153,29 @@ private String generateCursor(CardListReadResponseDTO cardListReadResponseDTO) {
.replace(":", "")
+ String.format("%08d", cardListReadResponseDTO.getCardId());
}

private List<SuggestionAvailableCardResponseDTO> getSuggestionResultCardList(
Boolean pokeAvailable,
PriceRange priceRange,
List<SuggestionAvailableCardResponseDTO> cardList
) {
if (pokeAvailable) {
return cardList.stream()
.peek(c -> {
if (c.getPriceRange().getValue() < priceRange.getValue()) {
c.updateSuggestionType(SuggestionType.POKE);
} else {
c.updateSuggestionType(SuggestionType.OFFER);
}
})
.toList();
}

List<SuggestionAvailableCardResponseDTO> offerOnlyCardList = cardList.stream()
.filter(c -> c.getPriceRange().getValue() >= priceRange.getValue())
.toList();
offerOnlyCardList.forEach(o -> o.updateSuggestionType(SuggestionType.OFFER));

return offerOnlyCardList;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
import lombok.RequiredArgsConstructor;

import org.prgrms.nabimarketbe.domain.card.dto.request.CardCreateRequestDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.CardCreateResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.CardListReadPagingResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.CardSingleReadResponseDTO;
import org.prgrms.nabimarketbe.domain.card.dto.response.*;
import org.prgrms.nabimarketbe.domain.card.entity.Card;
import org.prgrms.nabimarketbe.domain.card.entity.CardStatus;
import org.prgrms.nabimarketbe.domain.card.repository.CardRepository;
Expand All @@ -21,11 +19,15 @@
import org.prgrms.nabimarketbe.domain.item.entity.PriceRange;
import org.prgrms.nabimarketbe.domain.item.repository.ItemRepository;

import org.prgrms.nabimarketbe.domain.user.entity.User;
import org.prgrms.nabimarketbe.domain.user.repository.UserRepository;
import org.prgrms.nabimarketbe.domain.user.service.CheckService;
import org.prgrms.nabimarketbe.global.error.BaseException;
import org.prgrms.nabimarketbe.global.error.ErrorCode;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -40,19 +42,27 @@ public class CardService {

private final CardImageRepository cardImageRepository;

private final UserRepository userRepository;

private final CardImageService cardImageService;

private final CheckService checkService;

@Transactional
public CardCreateResponseDTO createCard(
String token,
CardCreateRequestDTO cardCreateRequestDTO,
MultipartFile thumbnail,
List<MultipartFile> imageFiles
) {
User user = userRepository.findById(checkService.parseToken(token))
.orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND));

Category category = categoryRepository.findCategoryByCategoryName(cardCreateRequestDTO.category())
.orElseThrow();
.orElseThrow(() -> new BaseException(ErrorCode.CATEGORY_NOT_FOUND));

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

Item savedItem = itemRepository.save(item);
Card savedCard = cardRepository.save(card);
Expand Down Expand Up @@ -157,4 +167,27 @@ public void updateViews(Long cardId) {

card.updateViewCount();
}

@Transactional(readOnly = true)
public CardListResponseDTO<SuggestionAvailableCardResponseDTO> getSuggestionAvailableCards(
String token,
Long cardId
) {
User requestUser = userRepository.findById(checkService.parseToken(token))
.orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND));
Card suggestionTargetCard = cardRepository.findById(cardId)
.orElseThrow(() -> new BaseException(ErrorCode.CARD_NOT_FOUND));

if (requestUser.getUserId().equals(suggestionTargetCard.getUser().getUserId())) {
throw new BaseException(ErrorCode.CARD_SUGGESTION_MYSELF_ERROR);
}

List<SuggestionAvailableCardResponseDTO> cardListResponse = cardRepository.getSuggestionAvailableCards(
requestUser.getUserId(),
suggestionTargetCard.getItem().getPriceRange(),
suggestionTargetCard.getPoke()
);

return new CardListResponseDTO<>(cardListResponse);
}
}
Loading

0 comments on commit cd6a139

Please sign in to comment.