diff --git a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/application/service/PosterContentService.java b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/application/service/PosterContentService.java index 4af4ddc..94c5362 100644 --- a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/application/service/PosterContentService.java +++ b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/application/service/PosterContentService.java @@ -48,33 +48,19 @@ public class PosterContentService implements PosterContentUseCase { @Override @Transactional public PosterContentCreateResponse generatePosterContent(List images, PosterContentCreateRequest request) { - log.info("지점1-1"); + // 1. 이미지 blob storage에 저장하고 request 저장 List imageUrls = blobStorageService.uploadImage(images, posterImageContainer); request.setImages(imageUrls); - log.info("지점2-1"); + // 2. AI 요청 String generatedPoster = aiPosterGenerator.generatePoster(request); - // 3. 저장 - Content savedContent = savePosterContent(request, generatedPoster); - - // 생성 조건 정보 구성 - CreationConditions conditions = CreationConditions.builder() - .category(request.getCategory()) - .requirement(request.getRequirement()) - .eventName(request.getEventName()) - .startDate(request.getStartDate()) - .endDate(request.getEndDate()) - .photoStyle(request.getPhotoStyle()) - .build(); - return PosterContentCreateResponse.builder() .contentId(null) // 임시 생성이므로 ID 없음 .contentType(ContentType.POSTER.name()) .title(request.getTitle()) - .posterImage(generatedPoster) - .posterSizes(new HashMap<>()) // 빈 맵 반환 (사이즈 변환 안함) + .content(generatedPoster) .status(ContentStatus.DRAFT.name()) .build(); } @@ -85,7 +71,7 @@ public class PosterContentService implements PosterContentUseCase { * @param request 포스터 콘텐츠 저장 요청 */ @Transactional - public Content savePosterContent(PosterContentCreateRequest request, String generatedPoster) { + public Content savePosterContent(PosterContentSaveRequest request) { // 생성 조건 구성 CreationConditions conditions = CreationConditions.builder() .category(request.getCategory()) @@ -101,7 +87,7 @@ public class PosterContentService implements PosterContentUseCase { .contentType(ContentType.POSTER) .platform(Platform.GENERAL) .title(request.getTitle()) - .content(generatedPoster) +// .content(request.gen) .images(request.getImages()) .status(ContentStatus.PUBLISHED) .creationConditions(conditions) @@ -109,8 +95,6 @@ public class PosterContentService implements PosterContentUseCase { .build(); // 저장 - Content savedContent = contentRepository.save(content); - - return savedContent; + return contentRepository.save(content); } } \ No newline at end of file diff --git a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/application/usecase/PosterContentUseCase.java b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/application/usecase/PosterContentUseCase.java index 101482b..7f346e3 100644 --- a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/application/usecase/PosterContentUseCase.java +++ b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/application/usecase/PosterContentUseCase.java @@ -1,6 +1,7 @@ // marketing-content/src/main/java/com/won/smarketing/content/application/usecase/PosterContentUseCase.java package com.won.smarketing.content.application.usecase; +import com.won.smarketing.content.domain.model.Content; import com.won.smarketing.content.presentation.dto.PosterContentCreateRequest; import com.won.smarketing.content.presentation.dto.PosterContentCreateResponse; import com.won.smarketing.content.presentation.dto.PosterContentSaveRequest; @@ -15,10 +16,15 @@ import java.util.List; public interface PosterContentUseCase { /** - * 포스터 콘텐츠 생성 및 저장 + * 포스터 콘텐츠 생성 * @param request 포스터 콘텐츠 생성 요청 * @return 포스터 콘텐츠 생성 응답 */ PosterContentCreateResponse generatePosterContent(List images, PosterContentCreateRequest request); + /** + * 포스터 콘텐츠 저장 + * @param request 포스터 콘텐츠 저장 요청 + */ + Content savePosterContent(PosterContentSaveRequest request); } \ No newline at end of file diff --git a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/config/WebClientConfig.java b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/config/WebClientConfig.java index 7f7cf08..8fb41fc 100644 --- a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/config/WebClientConfig.java +++ b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/config/WebClientConfig.java @@ -1,4 +1,3 @@ -// marketing-content/src/main/java/com/won/smarketing/content/config/WebClientConfig.java package com.won.smarketing.content.config; import org.springframework.context.annotation.Bean; @@ -20,8 +19,8 @@ public class WebClientConfig { @Bean public WebClient webClient() { HttpClient httpClient = HttpClient.create() - .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000) - .responseTimeout(Duration.ofMillis(30000)); + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 15000) // 연결 타임아웃: 15초 + .responseTimeout(Duration.ofMinutes(5)); // 응답 타임아웃: 5분 return WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) diff --git a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/infrastructure/external/PythonAiPosterGenerator.java b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/infrastructure/external/PythonAiPosterGenerator.java index fc1405c..4ea396a 100644 --- a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/infrastructure/external/PythonAiPosterGenerator.java +++ b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/infrastructure/external/PythonAiPosterGenerator.java @@ -51,7 +51,7 @@ public class PythonAiPosterGenerator implements AiPosterGenerator { .bodyValue(requestBody) .retrieve() .bodyToMono(Map.class) - .timeout(Duration.ofSeconds(60)) // 포스터 생성은 시간이 오래 걸릴 수 있음 + .timeout(Duration.ofSeconds(90)) // 포스터 생성은 시간이 오래 걸릴 수 있음 .block(); // 응답에서 content(이미지 URL) 추출 diff --git a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/presentation/controller/ContentController.java b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/presentation/controller/ContentController.java index f306abc..ab7afa1 100644 --- a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/presentation/controller/ContentController.java +++ b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/presentation/controller/ContentController.java @@ -85,6 +85,19 @@ public class ContentController { return ResponseEntity.ok(ApiResponse.success(response, "포스터 콘텐츠가 성공적으로 생성되었습니다.")); } + /** + * 홍보 포스터 저장 + * + * @param request 포스터 콘텐츠 저장 요청 + * @return 저장 성공 응답 + */ + @Operation(summary = "홍보 포스터 저장", description = "생성된 홍보 포스터를 저장합니다.") + @PostMapping("/poster/save") + public ResponseEntity> savePosterContent(@Valid @RequestBody PosterContentSaveRequest request) { + posterContentUseCase.savePosterContent(request); + return ResponseEntity.ok(ApiResponse.success(null, "포스터 콘텐츠가 성공적으로 저장되었습니다.")); + } + /** * 콘텐츠 수정 * diff --git a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/presentation/dto/PosterContentCreateResponse.java b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/presentation/dto/PosterContentCreateResponse.java index 0c02b68..5fa5c53 100644 --- a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/presentation/dto/PosterContentCreateResponse.java +++ b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/presentation/dto/PosterContentCreateResponse.java @@ -31,19 +31,9 @@ public class PosterContentCreateResponse { @Schema(description = "생성된 포스터 타입") private String contentType; - @Schema(description = "포스터 이미지 URL") - private String posterImage; - - @Schema(description = "원본 이미지 URL 목록") - private List originalImages; - @Schema(description = "이미지 스타일", example = "모던") private String imageStyle; @Schema(description = "생성 상태", example = "DRAFT") private String status; - - @Schema(description = "포스터사이즈", example = "800x600") - private Map posterSizes; - } \ No newline at end of file diff --git a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/presentation/dto/PosterContentSaveRequest.java b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/presentation/dto/PosterContentSaveRequest.java index f3c5877..eb549f0 100644 --- a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/presentation/dto/PosterContentSaveRequest.java +++ b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/presentation/dto/PosterContentSaveRequest.java @@ -32,7 +32,6 @@ public class PosterContentSaveRequest { @Schema(description = "발행 상태", example = "PUBLISHED") private String status; - // CreationConditions에 필요한 필드들 @Schema(description = "콘텐츠 카테고리", example = "이벤트") private String category;