diff --git a/stock-diary/src/main/java/com/ogd/stockdiary/application/report/controller/ReportController.java b/stock-diary/src/main/java/com/ogd/stockdiary/application/report/controller/ReportController.java index c0f0824..24917e6 100644 --- a/stock-diary/src/main/java/com/ogd/stockdiary/application/report/controller/ReportController.java +++ b/stock-diary/src/main/java/com/ogd/stockdiary/application/report/controller/ReportController.java @@ -3,6 +3,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import com.fasterxml.jackson.core.JsonProcessingException; import com.ogd.stockdiary.application.report.dto.Mapper.ReportMapper; @@ -25,12 +26,13 @@ public class ReportController { @PostMapping("/{retrospectionId}/feedback") public ResponseEntity> CreateFeedback( - @RequestBody(required = false) CreateFeedbackRequest request, - @PathVariable Long retrospectionId) + @RequestPart(required = false) CreateFeedbackRequest request, + @PathVariable Long retrospectionId, + @RequestPart(value = "image", required = false) MultipartFile imageFile) throws JsonProcessingException { // 요청을 command 객체로 변환 - CreateFeedbackCommand command = ReportMapper.toCommand(request, retrospectionId); + CreateFeedbackCommand command = ReportMapper.toCommand(request, retrospectionId, imageFile); // 서비스에 전달 후 피드백 엔티티 반환 Feedback feedback = createFeedbackUseCase.createFeedbackUseCase(command); // 응답용 DTO diff --git a/stock-diary/src/main/java/com/ogd/stockdiary/application/report/dto/Mapper/ReportMapper.java b/stock-diary/src/main/java/com/ogd/stockdiary/application/report/dto/Mapper/ReportMapper.java index 6c22844..f2dd548 100644 --- a/stock-diary/src/main/java/com/ogd/stockdiary/application/report/dto/Mapper/ReportMapper.java +++ b/stock-diary/src/main/java/com/ogd/stockdiary/application/report/dto/Mapper/ReportMapper.java @@ -3,6 +3,9 @@ import java.util.List; import java.util.Map; +import com.ogd.stockdiary.domain.report.entity.RetrospectionForReport; +import org.springframework.web.multipart.MultipartFile; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; @@ -14,8 +17,8 @@ public class ReportMapper { public static CreateFeedbackCommand toCommand( - CreateFeedbackRequest request, Long retrospectionId) { - return new CreateFeedbackCommand(retrospectionId); + CreateFeedbackRequest request, Long retrospectionId, MultipartFile imageFile) { + return new CreateFeedbackCommand(retrospectionId, imageFile); } public static CreateFeedbackResponse toResponse(Feedback feedback) diff --git a/stock-diary/src/main/java/com/ogd/stockdiary/application/report/dto/Response/CreateFeedbackResponse.java b/stock-diary/src/main/java/com/ogd/stockdiary/application/report/dto/Response/CreateFeedbackResponse.java index 8371ea0..3ff5351 100644 --- a/stock-diary/src/main/java/com/ogd/stockdiary/application/report/dto/Response/CreateFeedbackResponse.java +++ b/stock-diary/src/main/java/com/ogd/stockdiary/application/report/dto/Response/CreateFeedbackResponse.java @@ -6,6 +6,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; public record CreateFeedbackResponse( + // 응답값에 추가할 것: 삼성 전자, 가격, 몇 주 필드 @JsonProperty("요약 한 마디") String summerizedFeedback, @JsonProperty("당시 시장 현황") String market, @JsonProperty("AI 추천 원칙") List> principles) {} diff --git a/stock-diary/src/main/java/com/ogd/stockdiary/application/report/service/ReportService.java b/stock-diary/src/main/java/com/ogd/stockdiary/application/report/service/ReportService.java index d2fecfe..a555a81 100644 --- a/stock-diary/src/main/java/com/ogd/stockdiary/application/report/service/ReportService.java +++ b/stock-diary/src/main/java/com/ogd/stockdiary/application/report/service/ReportService.java @@ -7,12 +7,16 @@ import org.springframework.ai.chat.messages.Message; import org.springframework.ai.chat.messages.SystemMessage; +import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; +import org.springframework.ai.model.Media; import org.springframework.ai.openai.OpenAiChatOptions; +import org.springframework.core.io.Resource; import org.springframework.stereotype.Service; +import org.springframework.util.MimeType; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -67,10 +71,30 @@ public Feedback createFeedbackUseCase(CreateFeedbackCommand command) PromptTemplate promptTemplate = new PromptTemplate(userText); - Map variables = Map.of("symbol", symbol, "market", market, "order", order, "content", content); + // Map variables = + // Map.of("symbol", symbol, "market", market, "order", order, "content", + // content); + + Map variables = + Map.of( + "symbol", symbol != null ? symbol : "", + "market", market != null ? market : "", + "order", order != null ? order : "", + "content", content != null ? content : ""); + + // 이미지를 Media 객체로 + Resource resource = command.imageFile().getResource(); + Media media = + Media.builder() + .mimeType(MimeType.valueOf(command.imageFile().getContentType())) + .data(resource) + .build(); + + // 플레이스 홀더 렌더링한 텍스트 + String renderText = promptTemplate.render(variables); - // 플레이스 홀더 넣은 유저 메시지 구성 - Message userMessage = promptTemplate.createMessage(variables); + // 유저 메시지 + Message userMessage = new UserMessage(renderText, List.of(media)); String modelName = "gpt-4.1-nano"; diff --git a/stock-diary/src/main/java/com/ogd/stockdiary/domain/report/port/in/CreateFeedbackCommand.java b/stock-diary/src/main/java/com/ogd/stockdiary/domain/report/port/in/CreateFeedbackCommand.java index 0e24b25..4f2c148 100644 --- a/stock-diary/src/main/java/com/ogd/stockdiary/domain/report/port/in/CreateFeedbackCommand.java +++ b/stock-diary/src/main/java/com/ogd/stockdiary/domain/report/port/in/CreateFeedbackCommand.java @@ -1,3 +1,5 @@ package com.ogd.stockdiary.domain.report.port.in; -public record CreateFeedbackCommand(Long retrospectionId) {} +import org.springframework.web.multipart.MultipartFile; + +public record CreateFeedbackCommand(Long retrospectionId, MultipartFile imageFile) {} diff --git a/stock-diary/src/main/resources/application.yml b/stock-diary/src/main/resources/application.yml index d578966..636e162 100644 --- a/stock-diary/src/main/resources/application.yml +++ b/stock-diary/src/main/resources/application.yml @@ -22,9 +22,9 @@ spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver - url: ${DB_URL} - username: ${DB_USERNAME} - password: ${DB_PASSWORD} + url: ${DB_URL:jdbc:mysql://foodiy.iptime.org:23306/dev_db?serverTimezone=Asia/Seoul} + username: ${DB_USERNAME:joonhee} + password: ${DB_PASSWORD:depromeet} h2: console: enabled: true