Skip to content

Commit

Permalink
[FEATURE] 추천 전략 적용 (#154)
Browse files Browse the repository at this point in the history
* feat : HEEXE 상품 추천 전략 작성 #138

* feat : Strategy Factory 구현 #138

* feat : 추천 전략 적용 #138

* spotless apply #138

* edit : BMPER -> BFPER #138

* spotless apply #138

* BFPER, BFPLA 추천 전략 로직 수정 #138

* BMLIP 추천 전략 로직 수정 #138

* FCTOP 추천 전략 로직 수정 #138

* FCTOP 추천 전략 로직 수정 #138

* FEFAS 추천 전략 로직 수정 #138

* FEBAG 추천 전략 로직 수정 #138

* FAACC 추천 전략 로직 수정 #138

* edit : HCCUP 추천 전략 로직 수정 #138

* edit : HCDIS 추천 전략 로직 수정 #138

* edit : FEDIG 추천 전략 로직 수정 #138

* spotless Apply #138
  • Loading branch information
bongsh0112 authored Feb 5, 2024
1 parent d72ae34 commit 33d83b4
Show file tree
Hide file tree
Showing 19 changed files with 477 additions and 183 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.transaction.annotation.Transactional;
import tify.server.api.common.slice.SliceResponse;
import tify.server.api.config.security.SecurityUtils;
import tify.server.api.product.model.dto.ProductFilterCondition;
import tify.server.api.product.model.vo.ProductRetrieveVo;
import tify.server.core.annotation.UseCase;
Expand All @@ -20,18 +20,22 @@
import tify.server.domain.domains.product.dto.model.ProductRetrieveDto;
import tify.server.domain.domains.question.adaptor.FavorQuestionAdaptor;
import tify.server.domain.domains.question.domain.FavorQuestionCategory;
import tify.server.domain.domains.question.strategy.ProductRecommendationStrategy;
import tify.server.domain.domains.question.strategy.ProductRecommendationStrategyFactory;

@UseCase
@RequiredArgsConstructor
public class RetrieveProductListUseCase {

private final ProductAdaptor productAdaptor;
private final FavorQuestionAdaptor favorQuestionAdaptor;
private final ProductRecommendationStrategyFactory strategyFactory;

@Transactional(readOnly = true)
public SliceResponse<ProductRetrieveVo> executeToSmallCategory(
ProductFilterCondition productFilterCondition, Pageable pageable) {
List<Long> categoryIdList = new ArrayList<>();
List<ProductRecommendationStrategy> strategies = new ArrayList<>();
productFilterCondition
.getSmallCategoryList()
.forEach(
Expand All @@ -40,19 +44,30 @@ public SliceResponse<ProductRetrieveVo> executeToSmallCategory(
favorQuestionAdaptor.queryBySmallCategory(category).stream()
.map(FavorQuestionCategory::getId)
.toList());
strategies.addAll(strategyFactory.findStrategy(category));
});

if (productFilterCondition.getPriceOrder().equals(PriceOrder.DEFAULT)
&& productFilterCondition.getPriceFilter().equals(PriceFilter.DEFAULT)) {
// TODO : 추천 전략을 적용하는 부분일듯
List<ProductRetrieveDto> list =
productAdaptor.findAllBySmallCategoryId(
new ProductCategoryCondition(
categoryIdList,
productFilterCondition.getPriceOrder(),
productFilterCondition.getPriceFilter(),
pageable));
Collections.shuffle(list);
List<ProductRetrieveDto> list = new ArrayList<>();
strategies.forEach(
strategy -> {
list.addAll(
strategy
.recommendation(
SecurityUtils.getCurrentUserId(),
strategy.getStrategyName().getValue())
.stream()
.map(
product -> {
return ProductRetrieveDto.of(
product,
favorQuestionAdaptor.queryCategory(
product
.getFavorQuestionCategoryId()));
})
.toList());
});
return SliceResponse.of(
new SliceImpl<>(
list.stream().map(ProductRetrieveVo::from).toList(), pageable, true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,12 @@ public class ProductRetrieveDto {
private Product product;

private FavorQuestionCategory favorQuestionCategory;

public static ProductRetrieveDto of(
Product product, FavorQuestionCategory favorQuestionCategory) {
return ProductRetrieveDto.builder()
.product(product)
.favorQuestionCategory(favorQuestionCategory)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,10 @@ public List<FavorQuestionCategory> queryBySmallCategory(SmallCategory smallCateg
public List<FavorQuestion> queryAll() {
return favorQuestionRepository.findAll();
}

public FavorQuestionCategory queryCategory(Long favorQuestionCategory) {
return favorQuestionCategoryRepository
.findById(favorQuestionCategory)
.orElseThrow(() -> FavorQuestionCategoryNotFoundException.EXCEPTION);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import tify.server.domain.domains.product.adaptor.ProductAdaptor;
import tify.server.domain.domains.product.domain.Product;
import tify.server.domain.domains.question.adaptor.FavorAnswerAdaptor;
import tify.server.domain.domains.question.domain.FavorAnswer;
import tify.server.domain.domains.question.dto.condition.FavorRecommendationDTO;

@Component
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class BFMOIRecommendationStrategy implements ProductRecommendationStrategy {
Expand All @@ -20,8 +22,7 @@ public class BFMOIRecommendationStrategy implements ProductRecommendationStrateg
private static final String CATEGORY_NAME = "BFMOI";

@Override
public List<Product> recommendation(
Long userId, String categoryName, List<FavorRecommendationDTO> dto) {
public List<Product> recommendation(Long userId, String categoryName) {

List<FavorRecommendationDTO> recommendationDTO = getRecommendationDTO(userId);
List<Product> productList = new ArrayList<>();
Expand Down Expand Up @@ -74,6 +75,11 @@ public List<Product> recommendation(
}
}

@Override
public StrategyName getStrategyName() {
return StrategyName.BFMOI;
}

private List<Product> filterStep(String categoryName, String answer) {
return productAdaptor.queryAllByCategoryNameAndCharacter(categoryName, answer);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,23 @@
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import tify.server.domain.domains.product.adaptor.ProductAdaptor;
import tify.server.domain.domains.product.domain.Product;
import tify.server.domain.domains.question.adaptor.FavorAnswerAdaptor;
import tify.server.domain.domains.question.dto.condition.FavorRecommendationDTO;

@Component
@RequiredArgsConstructor
public class BMPERRecommendationStrategy implements ProductRecommendationStrategy {
public class BFPERRecommendationStrategy implements ProductRecommendationStrategy {

private final ProductAdaptor productAdaptor;
private final FavorAnswerAdaptor favorAnswerAdaptor;

private static final String CATEGORY_NAME = "BMPER";
private static final String CATEGORY_NAME = "BFPER";

@Override
public List<Product> recommendation(
Long userId, String categoryName, List<FavorRecommendationDTO> dto) {
public List<Product> recommendation(Long userId, String categoryName) {

List<FavorRecommendationDTO> recommendationDTO = getRecommendationDTO(userId);
List<Product> productList = new ArrayList<>();
Expand All @@ -32,6 +33,7 @@ public List<Product> recommendation(

/** 2번 스텝(내가 원하는 나의 이미지?) 객관식 2개까지 가능이기 때문에 답변 개수별로 경우를 나눔 */
String[] splitAnswer = recommendationDTO.get(1).getAnswer().split(", ");

if (splitAnswer.length > 1) {
return productList.stream()
.filter(product -> product.getCharacteristic().contains(splitAnswer[0]))
Expand All @@ -47,6 +49,11 @@ public List<Product> recommendation(
}
}

@Override
public StrategyName getStrategyName() {
return StrategyName.valueOf(CATEGORY_NAME);
}

private List<Product> filterStep(String categoryName, String answer) {
return productAdaptor.queryAllByCategoryNameAndCharacter(categoryName, answer);
}
Expand All @@ -57,10 +64,14 @@ private List<FavorRecommendationDTO> getRecommendationDTO(Long userId) {
favorAnswerAdaptor
.searchByCategoryNameAndNumber(userId, CATEGORY_NAME, 1L)
.getAnswerContent();
if (firstAnswer.equals("진한") || firstAnswer.equals("깊은")) {
favorRecommendationDTOs.add(new FavorRecommendationDTO(1L, "퍼퓸, 오드퍼퓸"));
} else if (firstAnswer.equals("은은한") || firstAnswer.equals("가벼운")) {
favorRecommendationDTOs.add(new FavorRecommendationDTO(1L, "오드뚜왈렛, 오드코롱, 샤워코롱"));
if (firstAnswer.equals("진한")) {
favorRecommendationDTOs.add(new FavorRecommendationDTO(1L, " 퍼퓸"));
} else if (firstAnswer.equals("깊은")) {
favorRecommendationDTOs.add(new FavorRecommendationDTO(1L, "오드퍼퓸"));
} else if (firstAnswer.equals("은은한")) {
favorRecommendationDTOs.add(new FavorRecommendationDTO(1L, "오드뚜왈렛"));
} else if (firstAnswer.equals("가벼운")) {
favorRecommendationDTOs.add(new FavorRecommendationDTO(1L, "오드코롱•샤워코롱"));
}

favorRecommendationDTOs.add(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import tify.server.domain.domains.product.adaptor.ProductAdaptor;
import tify.server.domain.domains.product.domain.Product;
import tify.server.domain.domains.question.adaptor.FavorAnswerAdaptor;
import tify.server.domain.domains.question.domain.FavorAnswer;
import tify.server.domain.domains.question.dto.condition.FavorRecommendationDTO;

@Component
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class BFPLARecommendationStrategy implements ProductRecommendationStrategy {
Expand All @@ -21,8 +23,7 @@ public class BFPLARecommendationStrategy implements ProductRecommendationStrateg
private final FavorAnswerAdaptor favorAnswerAdaptor;

@Override
public List<Product> recommendation(
Long userId, String categoryName, List<FavorRecommendationDTO> dto) {
public List<Product> recommendation(Long userId, String categoryName) {

List<FavorRecommendationDTO> recommendationDTO = getRecommendationDTO(userId);
List<Product> productList = new ArrayList<>();
Expand All @@ -43,35 +44,47 @@ public List<Product> recommendation(
productList.addAll(filterStep(CATEGORY_NAME, firstFavorRecommendationDTO.getAnswer()));
}

return productList;

/**
* 2번 스텝(원하는 우리집의 이미지?) 1번 스텝과 거의 동일함 answer가 최대 2개 선택이므로 경우를 나눈다 1개인 경우 productList를 답변으로
* 필터한다 2개인 경우 필터를 두번 거친다
*
* <p>// TODO : 질문에 대한 답변을 포함하는 상품이 아직 없음.. 나중에 상품 업데이트 후 다시 활성화
*/
FavorRecommendationDTO secondFavorRecommendationDTO = recommendationDTO.get(1);
List<Product> resultProductList = new ArrayList<>();
if (secondFavorRecommendationDTO.getAnswer().split(", ").length > 1) {
return productList.stream()
.filter(
product ->
product.getCharacteristic()
.contains(
secondFavorRecommendationDTO.getAnswer()
.split(", ")[0]))
.filter(
product ->
product.getCharacteristic()
.contains(
secondFavorRecommendationDTO.getAnswer()
.split(", ")[1]))
.toList();
} else {
return productList.stream()
.filter(
product ->
product.getCharacteristic()
.contains(secondFavorRecommendationDTO.getAnswer()))
.toList();
}
// FavorRecommendationDTO secondFavorRecommendationDTO = recommendationDTO.get(1);
// List<Product> resultProductList = new ArrayList<>();
// if (secondFavorRecommendationDTO.getAnswer().split(", ").length > 1) {
// return productList.stream()
// .filter(
// product ->
// product.getCharacteristic()
// .contains(
//
// secondFavorRecommendationDTO.getAnswer()
// .split(", ")[0]))
// .filter(
// product ->
// product.getCharacteristic()
// .contains(
//
// secondFavorRecommendationDTO.getAnswer()
// .split(", ")[1]))
// .toList();
// } else {
// return productList.stream()
// .filter(
// product ->
// product.getCharacteristic()
//
// .contains(secondFavorRecommendationDTO.getAnswer()))
// .toList();
// }
}

@Override
public StrategyName getStrategyName() {
return StrategyName.valueOf(CATEGORY_NAME);
}

private List<Product> filterStep(String categoryName, String answer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import tify.server.core.exception.BaseException;
import tify.server.domain.domains.product.adaptor.ProductAdaptor;
Expand All @@ -13,6 +14,7 @@
import tify.server.domain.domains.question.dto.condition.FavorRecommendationDTO;
import tify.server.domain.domains.question.exception.QuestionException;

@Component
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class BMEYERecommendationStrategy implements ProductRecommendationStrategy {
Expand All @@ -26,8 +28,7 @@ public class BMEYERecommendationStrategy implements ProductRecommendationStrateg
private static final String SECOND_CATEGORY_NAME = "BMEYE";

@Override
public List<Product> recommendation(
Long userId, String categoryName, List<FavorRecommendationDTO> dto) {
public List<Product> recommendation(Long userId, String categoryName) {

List<FavorRecommendationDTO> recommendationDTO = getRecommendationDTO(userId);

Expand All @@ -41,6 +42,11 @@ public List<Product> recommendation(
return secondStep(firstProducts, recommendationDTO.get(1).getAnswer());
}

@Override
public StrategyName getStrategyName() {
return StrategyName.valueOf(SECOND_CATEGORY_NAME);
}

private List<FavorRecommendationDTO> getRecommendationDTO(Long userId) {
List<FavorAnswer> favorAnswers = new ArrayList<>();
favorAnswers.add(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.Arrays;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import tify.server.core.exception.BaseException;
import tify.server.domain.domains.product.adaptor.ProductAdaptor;
Expand All @@ -14,6 +15,7 @@
import tify.server.domain.domains.question.dto.condition.FavorRecommendationDTO;
import tify.server.domain.domains.question.exception.QuestionException;

@Component
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class BMLIPRecommendationStrategy implements ProductRecommendationStrategy {
Expand All @@ -26,8 +28,7 @@ public class BMLIPRecommendationStrategy implements ProductRecommendationStrateg
private static final String CATEGORY_NAME = "BMLIP";

@Override
public List<Product> recommendation(
Long userId, String categoryName, List<FavorRecommendationDTO> dto) {
public List<Product> recommendation(Long userId, String categoryName) {

List<FavorRecommendationDTO> recommendationDTO = getRecommendationDTO(userId);

Expand All @@ -52,6 +53,11 @@ public List<Product> recommendation(
return otherStep(secondStepProducts, recommendationDTO.get(2).getAnswer());
}

@Override
public StrategyName getStrategyName() {
return StrategyName.valueOf(CATEGORY_NAME);
}

private List<FavorRecommendationDTO> getRecommendationDTO(Long userId) {
List<FavorAnswer> favorAnswers = new ArrayList<>();
favorAnswers.add(
Expand All @@ -76,7 +82,7 @@ private List<Product> otherStep(List<Product> findProducts, String answer) {
return product.getCharacteristic().contains(answerSplits.get(0));
} else if (answerSplits.size() == 2) {
return product.getCharacteristic().contains(answerSplits.get(0))
&& product.getCharacteristic()
|| product.getCharacteristic()
.contains(answerSplits.get(1));
} else {
return true;
Expand Down
Loading

0 comments on commit 33d83b4

Please sign in to comment.