diff --git a/src/main/java/com/backend/soullive_a/controller/ModelController.java b/src/main/java/com/backend/soullive_a/controller/ModelController.java index 1be8a7d..ad138eb 100644 --- a/src/main/java/com/backend/soullive_a/controller/ModelController.java +++ b/src/main/java/com/backend/soullive_a/controller/ModelController.java @@ -1,13 +1,17 @@ package com.backend.soullive_a.controller; -import com.backend.soullive_a.dto.request.ModelRequest; +import com.backend.soullive_a.dto.response.ModelRecommendResponse; import com.backend.soullive_a.dto.response.ModelResponse; +import com.backend.soullive_a.dto.response.RecentModelResponse; import com.backend.soullive_a.exception.base.BaseResponse; import com.backend.soullive_a.service.ModelService; -import jakarta.validation.Valid; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; - +@Tag(name = "모델 API", description = "모델 조회,생성,최근 조회한 모델 API입니다.") @RestController @RequiredArgsConstructor @RequestMapping("/api/model") @@ -19,31 +23,38 @@ public class ModelController { * @param modelName * @return */ + @Operation(summary = "모델 조회 API", description = "모델 기본 정보를 조회하는 API입니다.") @GetMapping("") - public BaseResponse getModel(@RequestParam String modelName) { + public BaseResponse getModel(@RequestParam String modelName, @RequestParam Long productId) { return BaseResponse.builder() .isSuccess(true) .code(200) .message("모델 조회에 성공했습니다.") - .data(modelService.getModel(modelName)) + .data(modelService.getModel(modelName,productId)) .build(); } - /** - * 모델 등록 api - * @param request - * @return - */ - @PostMapping("") - public BaseResponse createModel(@RequestBody @Valid ModelRequest request) { - System.out.println("@"); - return BaseResponse.builder() - .isSuccess(true) - .code(200) - .message("모델 생성에 성공했습니다.") - .data(modelService.createModel(request)) - .build(); + @Operation(summary = "최근 조회 모델 API", description = "최근 조회한 모델들을 조회하는 API입니다.") + @GetMapping("/recent/{productId}") + public BaseResponse> getRecentModel(@Parameter(name = "상품 id",description = "상품 기본키(필수)", + required = true) @PathVariable Long productId){ + return BaseResponse.>builder() + .isSuccess(true) + .code(200) + .message("최근 조회한 모델 조회 성공") + .data(modelService.getRecentModel(productId)) + .build(); + } + @Operation(summary = "모델 추천 API", description = "모델을 추천 받는 API이다.") + @GetMapping("/recommendation") + public BaseResponse> getRecommendModel(){ + return BaseResponse.>builder() + .isSuccess(true) + .code(200) + .message("모델 추천 성공") + .data(modelService.getRecommendModel()) + .build(); } } diff --git a/src/main/java/com/backend/soullive_a/controller/ModelIntroductionController.java b/src/main/java/com/backend/soullive_a/controller/ModelIntroductionController.java index 8e1b4bd..9a72306 100644 --- a/src/main/java/com/backend/soullive_a/controller/ModelIntroductionController.java +++ b/src/main/java/com/backend/soullive_a/controller/ModelIntroductionController.java @@ -1,15 +1,15 @@ package com.backend.soullive_a.controller; -import com.backend.soullive_a.dto.request.ModelIntroduceRequest; + import com.backend.soullive_a.dto.response.ModelIntroductionResponse; -import com.backend.soullive_a.dto.response.ModelResponse; import com.backend.soullive_a.exception.base.BaseResponse; import com.backend.soullive_a.service.ModelIntroductionService; -import jakarta.validation.Valid; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; - +@Tag(name = "모델 소개 API", description = "모델 소개 API입니다.") @RestController @RequiredArgsConstructor @RequestMapping("/api/model/introduction") @@ -22,6 +22,7 @@ public class ModelIntroductionController { * @param modelName * @return */ + @Operation(summary = "모델 소개 API", description = "모델 소개 정보를 조회하는 API입니다.") @GetMapping("") public BaseResponse getModelIntroduction(@RequestParam String modelName) { return BaseResponse.builder() @@ -33,17 +34,7 @@ public BaseResponse getModelIntroduction(@RequestPara } -// @PostMapping("/{modelId}") -// public BaseResponse createModelIntroduction( -// @PathVariable Long modelId, -// @RequestBody @Valid ModelIntroduceRequest request) { -// return BaseResponse.builder() -// .isSuccess(true) -// .code(2006) -// .message("모델소개 정보 생성에 성공했습니다.") -// .data(modelIntroductionService.createModelIntroduction(request, modelId)) -// .build(); -// } + } diff --git a/src/main/java/com/backend/soullive_a/controller/ModelIssueController.java b/src/main/java/com/backend/soullive_a/controller/ModelIssueController.java new file mode 100644 index 0000000..c67f1c9 --- /dev/null +++ b/src/main/java/com/backend/soullive_a/controller/ModelIssueController.java @@ -0,0 +1,26 @@ +package com.backend.soullive_a.controller; + +import com.backend.soullive_a.dto.response.model.issue.ModelIssueResponse; +import com.backend.soullive_a.exception.base.BaseResponse; +import com.backend.soullive_a.service.ModelIssueService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("api/model/issue") +public class ModelIssueController { + private final ModelIssueService modelIssueService; + @GetMapping() + public BaseResponse getIssue(@RequestParam String modelName) { + return BaseResponse.builder() + .code(200) + .message("부정이슈 조회에 성공했습니다.") + .isSuccess(true) + .data(modelIssueService.getIssue(modelName)) + .build(); + } +} diff --git a/src/main/java/com/backend/soullive_a/controller/ModelPopularityController.java b/src/main/java/com/backend/soullive_a/controller/ModelPopularityController.java index 7729a04..40ead40 100644 --- a/src/main/java/com/backend/soullive_a/controller/ModelPopularityController.java +++ b/src/main/java/com/backend/soullive_a/controller/ModelPopularityController.java @@ -3,12 +3,14 @@ import com.backend.soullive_a.dto.response.model.popularity.ModelPopularityResponse; import com.backend.soullive_a.exception.base.BaseResponse; import com.backend.soullive_a.service.ModelPopularityService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; - +@Tag(name = "모델 화제성 API", description = "모델 화제성 API입니다.") @RestController @RequiredArgsConstructor @RequestMapping("/api/model/popularity") @@ -16,6 +18,7 @@ public class ModelPopularityController { private final ModelPopularityService modelPopularityService; + @Operation(summary = "모델 화제성 API", description = "모델 화제성 정보를 조회하는 API입니다.") @GetMapping("") public BaseResponse getModelPopularity( @RequestParam String name diff --git a/src/main/java/com/backend/soullive_a/controller/ProductController.java b/src/main/java/com/backend/soullive_a/controller/ProductController.java index 98cf5e3..728cedf 100644 --- a/src/main/java/com/backend/soullive_a/controller/ProductController.java +++ b/src/main/java/com/backend/soullive_a/controller/ProductController.java @@ -4,13 +4,15 @@ import com.backend.soullive_a.dto.response.ProductResponse; import com.backend.soullive_a.exception.base.BaseResponse; import com.backend.soullive_a.service.ProductService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import java.util.List; - +@Tag(name = "광고 상품 API", description = "광고 상품 API입니다.") @Slf4j @RestController @RequestMapping("api/product") @@ -19,6 +21,7 @@ public class ProductController { private final ProductService productService; + @Operation(summary = "광고 상품 생성 API", description = "광고 상품을 생성하는 API입니다.") @PostMapping("") public BaseResponse createProduct( @RequestBody @Valid CreateProductRequest createProductRequest @@ -30,7 +33,7 @@ public BaseResponse createProduct( .data(productService.createProduct(createProductRequest)) .build(); } - + @Operation(summary = "모든 광고 상품 조회 API", description = "모든 광고 상품을 조회 API입니다.") @GetMapping() public BaseResponse> getAllProduct() { return BaseResponse.>builder() @@ -40,7 +43,7 @@ public BaseResponse> getAllProduct() { .data(productService.getAllProduct()) .build(); } - + @Operation(summary = "특정 광고 상품 조회 API", description = "특정 광고 상품을 조회 API입니다.") @GetMapping("/{id}") public BaseResponse getProduct(@PathVariable Long id) { return BaseResponse.builder() @@ -50,7 +53,7 @@ public BaseResponse getProduct(@PathVariable Long id) { .data(productService.getProduct(id)) .build(); } - + @Operation(summary = "특정 광고 상품 삭제 API", description = "특정 광고 상품을 삭제 API입니다.") @DeleteMapping("/{id}") public BaseResponse deleteProduct(@PathVariable Long id) { diff --git a/src/main/java/com/backend/soullive_a/dto/response/ModelRecommendResponse.java b/src/main/java/com/backend/soullive_a/dto/response/ModelRecommendResponse.java new file mode 100644 index 0000000..6e5819c --- /dev/null +++ b/src/main/java/com/backend/soullive_a/dto/response/ModelRecommendResponse.java @@ -0,0 +1,15 @@ +package com.backend.soullive_a.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(name = "모델 추천 응답 model") +public record ModelRecommendResponse( + @Schema(name = "imageUrl", example = "https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_profile.png", description = "모델 이미지 url입니다.") + String imageUrl, + @Schema(name = "name", example = "김희애", description = "모델 이름입니다.") + String name, + @Schema(name = "job", example = "텔런트/영화배우", description = "모델 직업(구분자)입니다.") + String job +) { + +} diff --git a/src/main/java/com/backend/soullive_a/dto/response/RecentModelResponse.java b/src/main/java/com/backend/soullive_a/dto/response/RecentModelResponse.java new file mode 100644 index 0000000..44f1eb2 --- /dev/null +++ b/src/main/java/com/backend/soullive_a/dto/response/RecentModelResponse.java @@ -0,0 +1,19 @@ +package com.backend.soullive_a.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "최근 조회한 모델 model 객체") +public record RecentModelResponse( + @Schema(name = "modelId", example = "1", description = "모델 기본키") + Long modelId, + @Schema(name = "imageUrl", example = "https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_profile.png", description = "모델 이미지 url입니다.") + String imageUrl, + @Schema(name = "modelName", example = "한지민", description = "모델 이름입니다.") + String modelName, + @Schema(name = "aiRate", example = "3.0", description = "ai 추천 점수입니다.") + Float aiRate, + @Schema(name = "job", example = "배우", description = "직업에 대한 값입니다.") + String job +) { + +} diff --git a/src/main/java/com/backend/soullive_a/dto/response/model/issue/ModelIssueResponse.java b/src/main/java/com/backend/soullive_a/dto/response/model/issue/ModelIssueResponse.java new file mode 100644 index 0000000..47abd74 --- /dev/null +++ b/src/main/java/com/backend/soullive_a/dto/response/model/issue/ModelIssueResponse.java @@ -0,0 +1,14 @@ +package com.backend.soullive_a.dto.response.model.issue; + +import lombok.Builder; + +import java.util.List; + +@Builder +public record ModelIssueResponse( + String scoreUrl, + String aiComment, + Integer crime, + List modelNewsResponseList +) { +} diff --git a/src/main/java/com/backend/soullive_a/dto/response/model/issue/ModelNewsResponse.java b/src/main/java/com/backend/soullive_a/dto/response/model/issue/ModelNewsResponse.java new file mode 100644 index 0000000..57cff58 --- /dev/null +++ b/src/main/java/com/backend/soullive_a/dto/response/model/issue/ModelNewsResponse.java @@ -0,0 +1,15 @@ +package com.backend.soullive_a.dto.response.model.issue; + +import jakarta.persistence.Column; +import lombok.Builder; + +import java.time.LocalDate; + +@Builder +public record ModelNewsResponse( + String company, + LocalDate newsDate, + String title, + String newsUrl +) { +} diff --git a/src/main/java/com/backend/soullive_a/entity/model/issue/ModelIssue.java b/src/main/java/com/backend/soullive_a/entity/model/issue/ModelIssue.java new file mode 100644 index 0000000..dce32b4 --- /dev/null +++ b/src/main/java/com/backend/soullive_a/entity/model/issue/ModelIssue.java @@ -0,0 +1,30 @@ +package com.backend.soullive_a.entity.model.issue; + +import com.backend.soullive_a.entity.model.Model; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class ModelIssue { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "MODEL_ISSUE_ID", nullable = false) + private Long id; + + @Column(name = "SCORE_URL", nullable = false) + private String scoreUrl; + + @Column(name = "AI_COMMENT", nullable = false) + private String aiComment; + + @Column(name = "CRIME", nullable = false) + private Integer crime; + + @OneToOne + @JoinColumn(name = "MODEL_ID", nullable = false) + private Model model; +} diff --git a/src/main/java/com/backend/soullive_a/entity/model/issue/ModelNews.java b/src/main/java/com/backend/soullive_a/entity/model/issue/ModelNews.java new file mode 100644 index 0000000..775787a --- /dev/null +++ b/src/main/java/com/backend/soullive_a/entity/model/issue/ModelNews.java @@ -0,0 +1,35 @@ +package com.backend.soullive_a.entity.model.issue; + +import jakarta.persistence.*; +import lombok.*; + +import java.time.LocalDate; + +@Getter +@Entity +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class ModelNews { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "MODEL_NEWS_ID", nullable = false) + private Long id; + + @Column(name = "COMPANY", nullable = false) + private String company; + + @Column(name = "NEWS_DATE", nullable = false) + private LocalDate newsDate; + + @Column(name = "TITLE", nullable = false) + private String title; + + @Column(name = "NEWS_URL", nullable = false) + private String newsUrl; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "MODEL_ISSUE_ID", nullable = false) + private ModelIssue modelIssue; + +} diff --git a/src/main/java/com/backend/soullive_a/repository/ModelRepository.java b/src/main/java/com/backend/soullive_a/repository/ModelRepository.java index ba26875..5a4c11b 100644 --- a/src/main/java/com/backend/soullive_a/repository/ModelRepository.java +++ b/src/main/java/com/backend/soullive_a/repository/ModelRepository.java @@ -1,12 +1,20 @@ package com.backend.soullive_a.repository; +import com.backend.soullive_a.dto.response.ModelRecommendResponse; import com.backend.soullive_a.entity.model.Model; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; +import org.springframework.data.jpa.repository.Query; import java.util.Optional; public interface ModelRepository extends JpaRepository { + public Optional findByModelName(String modelName); + + @Query("select " + + "new com.backend.soullive_a.dto.response.ModelRecommendResponse(m.imageUrl,m.modelName,m.job) " + + "From Model m ") + List findAllRecommendModel(); } diff --git a/src/main/java/com/backend/soullive_a/repository/ProductModelRepository.java b/src/main/java/com/backend/soullive_a/repository/ProductModelRepository.java index 6f695e5..166b980 100644 --- a/src/main/java/com/backend/soullive_a/repository/ProductModelRepository.java +++ b/src/main/java/com/backend/soullive_a/repository/ProductModelRepository.java @@ -1,8 +1,19 @@ package com.backend.soullive_a.repository; +import com.backend.soullive_a.dto.response.RecentModelResponse; import com.backend.soullive_a.entity.model.ProductModel; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface ProductModelRepository extends JpaRepository { + @Query("Select " + + "new com.backend.soullive_a.dto.response.RecentModelResponse(m.id,m.imageUrl,m.modelName,m.aiRate,m.job) " + + "From ProductModel p " + + "Inner Join Model m On p.model.id = m.id " + + "Where p.product.id = :productId " + + "ORDER BY p.searchTime DESC") + List getRecentModels(@Param("productId") Long productId); } diff --git a/src/main/java/com/backend/soullive_a/repository/model/issue/ModelIssueRepository.java b/src/main/java/com/backend/soullive_a/repository/model/issue/ModelIssueRepository.java new file mode 100644 index 0000000..897131f --- /dev/null +++ b/src/main/java/com/backend/soullive_a/repository/model/issue/ModelIssueRepository.java @@ -0,0 +1,10 @@ +package com.backend.soullive_a.repository.model.issue; + +import com.backend.soullive_a.entity.model.issue.ModelIssue; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface ModelIssueRepository extends JpaRepository { + public Optional findByModelModelName(String modelName); +} diff --git a/src/main/java/com/backend/soullive_a/repository/model/issue/ModelNewsRepository.java b/src/main/java/com/backend/soullive_a/repository/model/issue/ModelNewsRepository.java new file mode 100644 index 0000000..10e8771 --- /dev/null +++ b/src/main/java/com/backend/soullive_a/repository/model/issue/ModelNewsRepository.java @@ -0,0 +1,12 @@ +package com.backend.soullive_a.repository.model.issue; + +import com.backend.soullive_a.entity.model.issue.ModelIssue; +import com.backend.soullive_a.entity.model.issue.ModelNews; +import com.backend.soullive_a.entity.model.popularity.ModelPopularGender; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ModelNewsRepository extends JpaRepository { + List findAllByModelIssueModelModelName(String modelName); +} diff --git a/src/main/java/com/backend/soullive_a/service/ModelIntroductionService.java b/src/main/java/com/backend/soullive_a/service/ModelIntroductionService.java index c648ce2..2dcc30b 100644 --- a/src/main/java/com/backend/soullive_a/service/ModelIntroductionService.java +++ b/src/main/java/com/backend/soullive_a/service/ModelIntroductionService.java @@ -9,6 +9,6 @@ public interface ModelIntroductionService { public ModelIntroductionResponse getModelIntroduction(String modelName); - public ModelIntroductionResponse createModelIntroduction(ModelIntroduceRequest request, Long modelId); + } diff --git a/src/main/java/com/backend/soullive_a/service/ModelIssueService.java b/src/main/java/com/backend/soullive_a/service/ModelIssueService.java new file mode 100644 index 0000000..3398821 --- /dev/null +++ b/src/main/java/com/backend/soullive_a/service/ModelIssueService.java @@ -0,0 +1,8 @@ +package com.backend.soullive_a.service; + + +import com.backend.soullive_a.dto.response.model.issue.ModelIssueResponse; + +public interface ModelIssueService { + public ModelIssueResponse getIssue(String name); +} diff --git a/src/main/java/com/backend/soullive_a/service/ModelService.java b/src/main/java/com/backend/soullive_a/service/ModelService.java index 05d1757..f3788d1 100644 --- a/src/main/java/com/backend/soullive_a/service/ModelService.java +++ b/src/main/java/com/backend/soullive_a/service/ModelService.java @@ -1,10 +1,14 @@ package com.backend.soullive_a.service; -import com.backend.soullive_a.dto.request.ModelRequest; +import com.backend.soullive_a.dto.response.ModelRecommendResponse; import com.backend.soullive_a.dto.response.ModelResponse; +import com.backend.soullive_a.dto.response.RecentModelResponse; +import java.util.List; public interface ModelService { - public ModelResponse getModel(String modelName ); + public ModelResponse getModel(String modelName, Long productId); - public ModelResponse createModel(ModelRequest request); + public List getRecentModel(Long productId); + + public List getRecommendModel(); } diff --git a/src/main/java/com/backend/soullive_a/service/impl/ModelIntroductionServiceImpl.java b/src/main/java/com/backend/soullive_a/service/impl/ModelIntroductionServiceImpl.java index 3881e22..3e2427b 100644 --- a/src/main/java/com/backend/soullive_a/service/impl/ModelIntroductionServiceImpl.java +++ b/src/main/java/com/backend/soullive_a/service/impl/ModelIntroductionServiceImpl.java @@ -93,101 +93,6 @@ public ModelIntroductionResponse getModelIntroduction(String modelName) { } - /** - * 모델소개 생성 서비스 로직 - * - * @param modelId - * @return - */ - @Override - @Transactional - public ModelIntroductionResponse createModelIntroduction(ModelIntroduceRequest request, Long modelId) { - List modelImageKeywordList = new ArrayList<>(); - List modelRecentWorkList = new ArrayList<>(); - List modelRecentAdvertisementList = new ArrayList<>(); - - Model model = modelRepository.findById(modelId) - .orElseThrow(() -> new NotFoundUserException()); - - // ModelIntroduction 엔티티 저장 - modelIntroductionRepository.save( - ModelIntroduction.builder() - .model(model) - .build() - ); - - // ModelImageKeyword 엔티티 각각 저장 - for (String keyword : request.keywords()) { - ModelImageKeyword modelImageKeyword = ModelImageKeyword.builder() - .model(model) - .keyword(keyword) - .build(); - - modelImageKeywordRepository.save(modelImageKeyword); - - // ModelImageKeywordResponse (String) 생성 - modelImageKeywordList.add(keyword); - - } - - // ModelRecentWorkRequest 엔티티 각각 저장 - for (ModelRecentWorkRequest modelRecentWorkRequest : request.modelRecentWorks()) { - ModelRecentWork modelRecentWork = ModelRecentWork.builder() - .imageUrl(modelRecentWorkRequest.imageUrl()) - .year(modelRecentWorkRequest.year()) - .category(modelRecentWorkRequest.category()) - .title(modelRecentWorkRequest.title()) - .genre(modelRecentWorkRequest.genre()) - .role(modelRecentWorkRequest.role()) - .model(model) - .build(); - - modelRecentWorkRepository.save(modelRecentWork); - - // ModelRecentWorkResponse 생성 - ModelRecentWorkResponse modelRecentWorkResponse = ModelRecentWorkResponse.builder() - .imageUrl(modelRecentWorkRequest.imageUrl()) - .year(modelRecentWorkRequest.year()) - .category(modelRecentWorkRequest.category()) - .title(modelRecentWorkRequest.title()) - .genre(modelRecentWorkRequest.genre()) - .role(modelRecentWorkRequest.role()) - .build(); - - modelRecentWorkList.add(modelRecentWorkResponse); - } - - // modelRecentAdvertisementRepository 엔티티 각각 저장 - for (ModelRecentAdvertisementRequest modelRecentAdvertisementRequest : request.modelRecentAdvertisements()) { - ModelRecentAdvertisement modelRecentAdvertisement = ModelRecentAdvertisement.builder() - .imageUrl(modelRecentAdvertisementRequest.imageUrl()) - .year(modelRecentAdvertisementRequest.year()) - .brand(modelRecentAdvertisementRequest.brand()) - .model(model) - .build(); - - modelRecentAdvertisementRepository.save(modelRecentAdvertisement); - - // ModelRecentAdvertisementResponse 생성 - ModelRecentAdvertisementResponse modelRecentAdvertisementResponse = ModelRecentAdvertisementResponse.builder() - .imageUrl(modelRecentAdvertisementRequest.imageUrl()) - .year(modelRecentAdvertisementRequest.year()) - .brand(modelRecentAdvertisementRequest.brand()) - .build(); - - modelRecentAdvertisementList.add(modelRecentAdvertisementResponse); - } - - //ModelIntroductionResponse 생성 - - return ModelIntroductionResponse.builder() - .modelImageKeywords(modelImageKeywordList) - .modelRecentWorks(modelRecentWorkList) - .modelRecentAdvertisements(modelRecentAdvertisementList) - .build(); - - } - } diff --git a/src/main/java/com/backend/soullive_a/service/impl/ModelIssueImpl.java b/src/main/java/com/backend/soullive_a/service/impl/ModelIssueImpl.java new file mode 100644 index 0000000..3ff5ccb --- /dev/null +++ b/src/main/java/com/backend/soullive_a/service/impl/ModelIssueImpl.java @@ -0,0 +1,59 @@ +package com.backend.soullive_a.service.impl; + +import com.backend.soullive_a.constant.GenderType; +import com.backend.soullive_a.dto.response.model.issue.ModelIssueResponse; +import com.backend.soullive_a.dto.response.model.issue.ModelNewsResponse; +import com.backend.soullive_a.entity.model.issue.ModelIssue; +import com.backend.soullive_a.entity.model.issue.ModelNews; +import com.backend.soullive_a.entity.model.popularity.ModelPopularGender; +import com.backend.soullive_a.exception.custom.NotFoundUserException; +import com.backend.soullive_a.repository.model.issue.ModelIssueRepository; +import com.backend.soullive_a.repository.model.issue.ModelNewsRepository; +import com.backend.soullive_a.service.ModelIssueService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class ModelIssueImpl implements ModelIssueService { + + private final ModelIssueRepository modelIssueRepository; + private final ModelNewsRepository modelNewsRepository; + + /** + * 부정이슈 조회 서비스로직 + * @param modelName + * @return + */ + @Override + public ModelIssueResponse getIssue(String modelName) { + ModelIssue modelIssue = modelIssueRepository.findByModelModelName(modelName) + .orElseThrow(() -> new NotFoundUserException()); + + List modelNewsList = modelNewsRepository.findAllByModelIssueModelModelName(modelName); + + List modelNewsResponse = new ArrayList<>(); + + for (ModelNews modelNews : modelNewsList) { + modelNewsResponse.add( + ModelNewsResponse.builder() + .company(modelNews.getCompany()) + .newsDate(modelNews.getNewsDate()) + .title(modelNews.getTitle()) + .newsUrl(modelNews.getNewsUrl()) + .build() + ); + } + + return ModelIssueResponse.builder() + .scoreUrl(modelIssue.getScoreUrl()) + .aiComment(modelIssue.getAiComment()) + .crime(modelIssue.getCrime()) + .modelNewsResponseList(modelNewsResponse) + .build(); + } +} diff --git a/src/main/java/com/backend/soullive_a/service/impl/ModelServiceImpl.java b/src/main/java/com/backend/soullive_a/service/impl/ModelServiceImpl.java index 58ec9fa..2de4b59 100644 --- a/src/main/java/com/backend/soullive_a/service/impl/ModelServiceImpl.java +++ b/src/main/java/com/backend/soullive_a/service/impl/ModelServiceImpl.java @@ -1,11 +1,18 @@ package com.backend.soullive_a.service.impl; -import com.backend.soullive_a.dto.request.ModelRequest; +import com.backend.soullive_a.dto.response.ModelRecommendResponse; import com.backend.soullive_a.dto.response.ModelResponse; +import com.backend.soullive_a.dto.response.RecentModelResponse; +import com.backend.soullive_a.entity.Product; import com.backend.soullive_a.entity.model.Model; +import com.backend.soullive_a.entity.model.ProductModel; import com.backend.soullive_a.exception.custom.NotFoundUserException; import com.backend.soullive_a.repository.ModelRepository; +import com.backend.soullive_a.repository.ProductModelRepository; +import com.backend.soullive_a.repository.ProductRepository; import com.backend.soullive_a.service.ModelService; +import java.time.LocalDateTime; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -15,13 +22,19 @@ public class ModelServiceImpl implements ModelService { private final ModelRepository modelRepository; + private final ProductRepository productRepository; + private final ProductModelRepository productModelRepository; @Override - public ModelResponse getModel(String modelName) { + @Transactional + public ModelResponse getModel(String modelName,Long productId) { System.out.println(modelName); Model model = modelRepository.findByModelName(modelName) .orElseThrow(() -> new NotFoundUserException()); + //최근 조회 모델 데이터 업데이트 + updateRecentViewModel(model,productId); + return ModelResponse.builder() .modelId(model.getId()) @@ -37,37 +50,39 @@ public ModelResponse getModel(String modelName) { .build(); } - @Override - @Transactional - public ModelResponse createModel(ModelRequest request) { - // 중복 검사 로직 추가 - Model model = modelRepository.save(Model.builder() - .imageUrl(request.imageUrl()) - .modelName(request.modelName()) - .birth(request.birth()) - .age(request.age()) + /** + * 최근 조회한 모델들 조회 + */ + @Override + @Transactional + public List getRecentModel(Long productId) { + return productModelRepository.getRecentModels(productId); + } - .job(request.job()) - .info(request.info()) - .agency(request.agency()) - .aiRate(request.aiRate()) - .build()); + @Override + @Transactional + public List getRecommendModel(){ - return ModelResponse.builder() - .modelId(model.getId()) + return modelRepository.findAllRecommendModel(); + } + /** + * 광고 상품 엔티티 생성 + * @param model + * @param productId + */ + private void updateRecentViewModel(Model model, Long productId){ - .imageUrl(model.getImageUrl()) - .modelName(model.getModelName()) - .birth(model.getBirth()) - .age(model.getAge()) + Product product = productRepository.findById(productId) + .orElseThrow(NotFoundUserException::new); - .job(model.getJob()) - .info(model.getInfo()) - .agency(model.getAgency()) - .aiRate(model.getAiRate()) - .build(); + productModelRepository.save( + ProductModel.builder() + .model(model) + .product(product) + .searchTime(LocalDateTime.now()) + .build() + ); } - } diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index fb495f0..6359b98 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -1,13 +1,21 @@ -- 유저 INSERT INTO soullive.user (user_id, password, phone_number) VALUES (1, 'password', '010-0000-0000'); --- 모델1 김희애 +-- 모델 INSERT INTO soullive.model (model_id, model_name, birth, age, job, info, agency, ai_rate, image_url) -VALUES (1, '김희애', '1967-04-23', '56세', '텔런트/영화배우', '', 'YG 엔터테인먼트', 4.0, 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_profile.png'); +VALUES + (1, '김희애', '1967-04-23', '56세', '텔런트/영화배우', '', 'YG 엔터테인먼트', 4.0, 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_profile.png'), + (2, '한지민', '1982-11-05', '41세', '배우', '', 'BH 엔터테인먼트', 3.0, 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_profile.png'), + (3, '김고은', '1991-07-02', '32세', '배우', '', 'BH 엔터테인먼트', 3.0, 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_profile.png'); -INSERT INTO soullive.model_introduction (model_id, model_introduction_id) VALUES (1, 1); +-- 모델소개 +INSERT INTO soullive.model_introduction (model_id, model_introduction_id) +VALUES + (1, 1), + (2, 2), + (3, 3); --- 모델1 김희애 모델소개 +-- 모델소개 > 모델이미지키워드 INSERT INTO soullive.model_image_keyword (model_image_keyword_id, model_id, keyword) VALUES (1, 1, '#세련됨'), @@ -16,35 +24,103 @@ VALUES (4, 1, '#우아한'), (5, 1, '#프리미엄'), (6, 1, '#럭셔리함'), - (7, 1, '#신뢰감'); + (7, 1, '#신뢰감'), + (8, 2, '#깨끗한'), + (9, 2, '#다재다능한'), + (10, 2, '#대중에게 친숙한'), + (11, 2, '#강인한'), + (12, 2, '#예술적인'), + (13, 2, '#섬세한'), + (14, 2, '#귀여운'), + (15, 3, '#세련됨'), + (16, 3, '#청순한'), + (17, 3, '#사랑스러운'), + (18, 3, '#자연스러운'), + (19, 3, '#예술적인'), + (20, 3, '#명량한'), + (21, 3, '#포근한'); +-- 모델소개 > 최근 작품 INSERT INTO soullive.model_recent_work (model_recent_work_id, `year`, model_id, category, genre, image_url, `role`, title) VALUES (1, 2020, 1, '드라마', '가족, 멜로', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentwork1.png', '지선우역 (주연)', '부부의 세계'), (2, 2023, 1, '드라마', '드라마, 정치', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentwork2.png', '황도희역 (주연)', '퀸메이커'), - (3, 2024, 1, '영화', '범죄', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentwork3.png', '심은조역 (주연)', '데드맨'); + (3, 2024, 1, '영화', '범죄', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentwork3.png', '심은조역 (주연)', '데드맨'), + (4, 2023, 2, '드라마', '판타지', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentwork1.png', '봉예분역 (주연)', '힙하게'), + (5, 2022, 2, '드라마', '가족', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentwork2.png', '이영옥역 (주연)', '우리들의 블루스'), + (6, 2022, 2, '드라마', 'SF', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentwork3.png', '차이후역 (주연)', '욘더'), + (7, 2024, 3, '영화', '스릴러', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentwork1.png', '이화림역 (주연)', '파묘'), + (8, 2022, 3, '영화', '뮤지컬', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentwork2.png', '설희역 (주연)', '영웅'), + (9, 2022, 3, '드라마', '미스터리', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentwork3.png', '오인주역 (주연)', '작은아씨들'); +-- 모델소개 > 최근 광고 활동 INSERT INTO soullive.model_recent_advertisement (model_recent_advertisement_id, `year`, model_id, brand, image_url) VALUES (1, 2019, 1, 'LG 프라엘', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentadvertisement1.png'), (2, 2021, 1, '트렌비', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentadvertisement2.png'), - (3, 2024, 1, '우리은행 투체어스', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentadvertisement3.png'); + (3, 2024, 1, '우리은행 투체어스', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentadvertisement3.png'), + (4, 2023, 2, '삼성화재', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentadvertisement1.png'), + (5, 2022, 2, '탑스탭 세제', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentadvertisement2.png'), + (6, 2020, 2, '동인비', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentadvertisement3.png'), + (7, 2019, 3, '듀오랩', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentadvertisement1.png'), + (8, 2021, 3, '디스커버리 익스페디션', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentadvertisement2.png'), + (9, 2024, 3, '네스프레소', 'https://soullive-bucket.s3.ap-northeast-2.amazonaws.com/heeae_recentadvertisement3.png'); -- 모델 화제성 INSERT INTO soullive.model_popularity (model_popularity_id,model_id,score_url,ai_comment,sns_url,search_url,brand_score_url) values - (1,1,null,'최근 화제성에서는 다소 약한 모습을 보여주고 있지만 3040 남녀 모두에게 높은 인지도를 갖고 있고 앞으로 2개의 주연 활동을 앞두고 있어 더 큰 화제성을 갖을 것으로 예상됩니다.',null,null,null); + (1,1,null,'최근 화제성에서는 다소 약한 모습을 보여주고 있지만 3040 남녀 모두에게 높은 인지도를 갖고 있고 앞으로 2개의 주연 활동을 앞두고 있어 더 큰 화제성을 갖을 것으로 예상됩니다.',null,null,null), + (2,2,null,'한지민은 20대부터 40대까지 넓은 연령층에게 선호되며 최근 화제성이 계속해서 높아지고 있는 모델입니다.',null,null,null), + (3,3,null,'김고은은 최근 개봉작 “파묘"로 큰 인기를 얻고 있으며 2030에게 연기력을 인정받으며 화제성이 높은 배우입니다.',null,null,null); + +-- 모델 화제성 선호 성별 INSERT INTO soullive.model_popular_gender (gender_id, model_popularity_id, gender_type) values ('1','1','MALE'), - ('2','1','FEMALE'); + ('2','1','FEMALE'), + ('3','2','MALE'), + ('4','2','FEMALE'), + ('5','3','MALE'), + ('6','3','FEMALE'); +-- 모델 화제성 선호연령대 INSERT INTO soullive.model_popular_age (age_id, model_popularity_id,age_type) values (1,1,'THIRTY'), (2,1,'FORTY'), - (3,1,'FIFTY'); + (3,1,'FIFTY'), + (4,2,'TWENTY'), + (5,2,'THIRTY'), + (6,2,'FORTY'), + (7,3,'TWENTY'), + (8,3,'THIRTY'); + +-- 모델 예정 주요 활동 INSERT INTO soullive.model_scheduled_work (model_scheduled_work_id,image_url,model_popularity_id,year,category,title,is_main_actor,genre) values - (1,null, 1, 2024, '방영 예정 영화','돌풍',true,'공포'), - (2,null, 1, 2024, '방영 예정 영화','보통의 가족',true,'공포'); + (1,null, 1, 2024, '방영 예정 영화','돌풍',true,'드라마'), + (2,null, 1, 2024, '방영 예정 영화','보통의 가족',true,'드라마'), + (3,null, 2, 2024, '방영 예정 드라마','인사하는 사이',true,'휴먼'), + (4,null, 2, 2024, '방영 예정 영화','보통의 가족',true,'공포'), + (5,null, 3, 2024, '방영 예정 영화','대도시의 사랑법',true,'로맨스'), + (6,null, 3, 2024, '방영 예정 드라마','은중과 상연',true,'로맨스'), + (7,null, 3, 2024, '방영 예정 드라마','자백의 대가',true,'가족'); + +-- 모델 부정이슈 +INSERT INTO soullive.model_issue (model_issue_id, model_id, score_url, ai_comment,crime) +VALUES + (1, 1, '', '2020년에 처음 알려진 김희애 남편의 횔령 혐의 피소가 있지만 사건의 전말이 정확하지 않고 김희애 배우 본인의 문제가 아니었기에 논란이 크지 않았습니다.', 0), + (2, 2, '', '한지민은 데뷔 이래로 큰 논란이나 사건이 없었으며 대중들에게 줄곧 바른 이미지를 유지해왔습니다.', 0), + (3, 3, '', '김고은은 범죄이력이 없으며 두드러지는 사건사고가 없었기 때문에 부정적인 이슈를 일으킬 가능성이 낮습니다.', 0); + +--모델 부정이슈 뉴스 +INSERT INTO soullive.model_news (model_news_id, model_issue_id, company, news_date, title ,news_url) +VALUES + (1, 1, '살구뉴스', '2022-12-18', '“잘나가다 남편 때문에" 김희애 남편, 회사 논란 밝혀지자 모두 경악', 'https://www.salgoonews.com/news/articleView.html?idxno=25726'), + (2, 1, '톱스타뉴스', '2022-08-05', '"부부의 세계" 김희애, 드라마 남편과 실제 남편 이찬진의 오버랩횡령 혐의 논란', 'https://www.topstarnews.net/news/articleView.html?idxno=773836'), + (3, 1, '스포츠동아', '2022-08-05', '"김희애 남편" 이찬진 전 포티스 대표, 수십억 횡령 혐의 피소', 'https://sports.donga.com/article/all/20200429/100861465/2'), + (4, 2, 'The fact', '2023-08-19', '한지민의 ''힙하게'', ''성추행 논란'' 완전히 못 지운 찜찜한 출발[TF초점]', 'https://www.topstarnews.net/news/articleView.html?idxno=773836'), + (5, 2, '금강일보', '2022-08-05', '이민기·한지민 주연 ‘힙하게’, 캐릭터 컨셉 논란', 'https://sports.donga.com/article/all/20200429/100861465/2'), + (6, 3, '톱스타뉴스', '2023-08-19', '"수지도 5만 원인데”...배우 김고은, 
팬미팅 가격 고가 논란', 'https://www.topstarnews.net/news/articleView.html?idxno=773836'), + (7, 3, '국제신문', '2019-05-05', '김고은 측 ''인터뷰 논란 악플 경고글'' 돌연 삭제...
이유는?', 'https://sports.donga.com/article/all/20200429/100861465/2'); +