Skip to content

Commit

Permalink
feature : develop extract product
Browse files Browse the repository at this point in the history
  • Loading branch information
ITSTIME1 authored Aug 18, 2024
2 parents b41ddca + b075791 commit fc311e9
Show file tree
Hide file tree
Showing 32 changed files with 1,384 additions and 0 deletions.
1 change: 1 addition & 0 deletions logic/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ dependencies {
testImplementation("io.projectreactor:reactor-test")
testImplementation("org.springframework.security:spring-security-test")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation("org.springframework.boot:spring-boot-starter-logging")
}

tasks.withType<Test> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling
@SpringBootApplication
public class LogicApplication {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.spring_greens.logic.extraction.controller;

import com.spring_greens.logic.global.controller.AbstractBaseController;
import com.spring_greens.logic.global.factory.converter.ifs.ConverterFactory;
import com.spring_greens.logic.global.factory.service.ifs.ServiceFactory;

public class ExtractionConroller extends AbstractBaseController{

public ExtractionConroller(ConverterFactory converterFactory, ServiceFactory serviceFactory) {
super(converterFactory, serviceFactory);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.spring_greens.logic.extraction.converter;

import com.spring_greens.logic.extraction.converter.ifs.ExtractionConverter;
import com.spring_greens.logic.global.dto.MallDTO;
import com.spring_greens.logic.global.dto.ProductDTO;
import com.spring_greens.logic.global.dto.ShopDTO;
import com.spring_greens.logic.global.entity.Mall;
import com.spring_greens.logic.global.entity.Product;
import com.spring_greens.logic.global.entity.Shop;

public class ExtrationConverterImpl implements ExtractionConverter{

@Override
public MallDTO craeteMallDTO(Mall mall) {
return MallDTO.builder()
.id(mall.getId())
.name(mall.getName())
.build();
}

@Override
public ProductDTO createProductDTO(Product product) {
return ProductDTO.builder()
.id(product.getId())
.name(product.getName())
.unit(product.getUnit())
.price(product.getPrice())
.totalViewers(product.getTotalViewers())
// .productImageUrl(product.get)
// .majorCategory(product.getMajorCategory())
// .subCategory(product.getSubCategory())
.detailsProductClickCount(product.getDetailsProductClickCount())
.dailyAdImpressions(product.getDailyAdImpressions())
.age(product.getAge())
.build();
}

@Override
public ShopDTO createShopDTO(Shop shop) {
return ShopDTO.builder()
.id(shop.getId())
.name(shop.getName())
.contact(shop.getContact())
.addressDetails(shop.getAddressDetails())
.build();
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.spring_greens.logic.extraction.converter.ifs;

import com.spring_greens.logic.global.dto.MallDTO;
import com.spring_greens.logic.global.dto.ProductDTO;
import com.spring_greens.logic.global.dto.ShopDTO;
import com.spring_greens.logic.global.entity.Mall;
import com.spring_greens.logic.global.entity.Product;
import com.spring_greens.logic.global.entity.Shop;

public interface ExtractionConverter {
MallDTO craeteMallDTO(Mall mall);
ProductDTO createProductDTO(Product product);
ShopDTO createShopDTO(Shop shop);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.spring_greens.logic.extraction.dto;

import java.util.List;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.spring_greens.logic.global.dto.ShopDTO;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class RedisDTO {
private Long mall_id;
private String mall_name;
private List<ShopDTO> shop_list;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.spring_greens.logic.extraction.dto;

public class RedisProduct {
public String product_id;
public String product_name;
public String product_unit;
public String product_price;
public String product_view_count;
// public String product_image_url;
// public String major_category;
// public String sub_category;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.spring_greens.logic.extraction.dto;

import java.util.List;

public class RedisShop {
public Long shop_id;
public String shop_name;
public String shop_contact;
public String shop_address_details;
public List<RedisProduct> product;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.spring_greens.logic.extraction.schduler;

import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.spring_greens.logic.global.factory.service.ifs.ServiceFactory;

import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class ExtractionScheduler {
private final ServiceFactory serviceFactory;

@Scheduled
public void extractionProductScheduler(){

serviceFactory.getExtractionService().ExtractionProductService();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
package com.spring_greens.logic.extraction.service;

import java.util.*;

import com.spring_greens.logic.extraction.dto.RedisProduct;
import com.spring_greens.logic.extraction.dto.RedisShop;
import com.spring_greens.logic.global.dto.ShopDTO;
import com.spring_greens.logic.global.enums.Mall;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.spring_greens.logic.extraction.dto.RedisDTO;
import com.spring_greens.logic.extraction.service.ifs.ExtractionService;
import com.spring_greens.logic.global.dto.ProductDTO;
import com.spring_greens.logic.global.factory.converter.ifs.ConverterFactory;
import com.spring_greens.logic.global.factory.repository.ifs.RepositoryFactory;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor
public class ExtractionServiceImpl implements ExtractionService{

private final static Logger logger = LoggerFactory.getLogger(ExtractionServiceImpl.class);

private final ConverterFactory converterFactory;
private final RepositoryFactory repositoryFactory;
private final Double[] weights = {0.2, 0.3, 0.5};
private double sum = 0.0;
private double max = 0.0;


public RedisDTO ExtractionProductService(){

// 상품을추출
List<ProductDTO> products = createProducts();

// 확률
List<Double> Probabilities = createAgeScores(products);

// 10개의 상품으을추출한다.
List<Integer> tenIndexs = rouletteAlgorithm(products, Probabilities);

// age -= 1
ageManagement(products);

// age를 부여한다.
ageGrant(tenIndexs, Probabilities, products);

// DTO를 만들어서 보낸다.
return createRedisDTO(tenIndexs, products);
}

public List<Double> createAgeScores(List<ProductDTO> products){
List<Double> ageScores = new ArrayList<Double>();

//각각의 가중치와 해당 값들을 구하여 더한 것이 ageScore
for(ProductDTO p : products){
double ageScore = weights[0]*p.getDailyAdImpressions() +
weights[1]*p.getDetailsProductClickCount() +
weights[2]*p.getTotalViewers();
ageScores.add(ageScore);
sum += ageScore;
}

//룰렛 휠 알고리즘을 위해 필요한 확률로 만들어준다.
for(int i = 0; i < ageScores.size(); i++){
ageScores.set(i, ageScores.get(i)/sum);
// maximum
if(ageScores.get(i) > max){
max = ageScores.get(i);
}
}

return ageScores;
}

public List<Integer> rouletteAlgorithm(List<ProductDTO> products, List<Double> ageScores){
//확률들을 누적시켜 더한 값을 리스트로 저장해둔다.
List<Integer> tenIndexs = new ArrayList<>();
List<Double> cumulativeProbabilities = new ArrayList<>();
double cumulativeSum = 0;

for (double probability : ageScores) {
cumulativeSum += probability;
cumulativeProbabilities.add(probability);
}

//상품 선택
Random random = new Random();
while(tenIndexs.size() < 10){
double r = random.nextDouble();
//0에서 1사이의 랜덤한 실수를 정하고, 그 실수보다 큰 한가지를 골라서 저장.
for(int i = 0; i < cumulativeProbabilities.size(); i++){
if (r <= cumulativeProbabilities.get(i)){
tenIndexs.add(i);
break;
}
}
}

return tenIndexs;
}

public void ageManagement(List<ProductDTO> products){
for(ProductDTO p : products){
Integer age = p.getAge();
if(age>0){
p.changeAge(age-1);
}
}
}


// 에이지 부여
public void ageGrant(List<Integer> tenIndexs, List<Double> probabilities, List<ProductDTO> products){
//최댓값을 5로 두고, 20%씩 낮추면서 4,3,2,1 이런식으로 부여할 예정
for(Integer i : tenIndexs){
double ratio = probabilities.get(i)/max;

if(ratio > 0.8){
products.get(i).changeAge(5);
} else if (ratio > 0.6) {
products.get(i).changeAge(4);
} else if (ratio > 0.4) {
products.get(i).changeAge(3);
} else if (ratio > 0.2) {
products.get(i).changeAge(2);
} else {
products.get(i).changeAge(1);
}

}
}



public RedisDTO createRedisDTO(List<Integer> tenIndexs, List<ProductDTO> products){
List<Long> productIds = new ArrayList<>();
List<ProductDTO> productDtos = new ArrayList<>();
List<RedisProduct> redisProducts = new ArrayList<>();
List<RedisShop> redisShops = new ArrayList<>();
List<RedisDTO> redisDTO = new ArrayList<>();

public class RedisDTO {
private Long mall_id;
private String mall_name;
private List<ShopDTO> shop_list;
}

//shop을 가져오기 위한 productID를 가져오는 반복문, 10개의 product를 저장하는 코드
for(Integer i : tenIndexs){
ProductDTO p = products.get(i);
productIds.add(p.getId());
productDtos.add(p);
}

// shop 정보가지고오기
List<ShopDTO> shops = createShopDTO(productIds);

for(int i = 0; i < Mall.values().length ; i++){
// return 1
// return 2
}



}

public List<ProductDTO> createProducts(){

Optional<List<ProductDTO>> products = repositoryFactory.getProductRepository().findAllAge();

if(products.isPresent()){
return products.get();
}else{
log.info("DB Product 데이터 추출 실패");
throw new NoSuchElementException("No products found");
}

}

public List<ShopDTO> createShopDTO(List<Long> productId){
Optional<List<ShopDTO>> shops = repositoryFactory.getShopRepository().findByProduct(productId);
if(shops.isPresent()){
return shops.get();
}else{
log.info("DB Shop 데이터 추출 실패");
throw new NoSuchElementException("No products found");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.spring_greens.logic.extraction.service.ifs;

import java.util.List;

import com.spring_greens.logic.extraction.dto.RedisDTO;
import com.spring_greens.logic.global.dto.ProductDTO;
import com.spring_greens.logic.global.dto.ShopDTO;

public interface ExtractionService {
public RedisDTO ExtractionProductService();
public List<Double> createAgeScores(List<ProductDTO> product);
public List<Integer> rouletteAlgorithm(List<ProductDTO> products, List<Double> ageScores);
public void ageManagement(List<ProductDTO> products);
public void ageGrant(List<Integer> tenIndexs, List<Double> probabilities, List<ProductDTO> Products);
public RedisDTO createRedisDTO(List<Integer> tenIndexs, List<ProductDTO> products);
public List<ShopDTO> createShopDTO(List<Long> productId);
}
Loading

0 comments on commit fc311e9

Please sign in to comment.