Files
operationSystem-back/src/main/java/com/caliverse/admin/domain/service/AIService.java

111 lines
5.0 KiB
Java

package com.caliverse.admin.domain.service;
import com.caliverse.admin.domain.dao.admin.MailMapper;
import com.caliverse.admin.domain.entity.AI.AIRequestType;
import com.caliverse.admin.domain.entity.AI.AIRole;
import com.caliverse.admin.domain.entity.Mail;
import com.caliverse.admin.domain.request.AIRequest;
import com.caliverse.admin.domain.request.LogGenericRequest;
import com.caliverse.admin.domain.request.OpenAIRequest;
import com.caliverse.admin.domain.response.AIResponse;
import com.caliverse.admin.domain.response.OpenAIResponse;
import com.caliverse.admin.global.common.code.CommonCode;
import com.caliverse.admin.global.common.constants.CommonConstants;
import com.caliverse.admin.global.common.utils.CommonUtils;
import com.caliverse.admin.logs.Indicatordomain.GenericMongoLog;
import com.caliverse.admin.logs.logservice.businesslogservice.BusinessLogGenericService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
@RequiredArgsConstructor
public class AIService {
@Autowired
private ObjectMapper mapper;
private final OpenAIService openAIService;
private final BusinessLogGenericService businessLogGenericService;
private final MailMapper mailMapper;
public AIResponse aiMessageAnalyze(AIRequest dataRequest){
List<Map<String,String>> messages = initMessage();
List<?> data = getDataList(dataRequest.getType(), dataRequest.getConditions());
messages = splitDataToMessages(messages, data, dataRequest.getMessage());
OpenAIRequest openAIRequest = new OpenAIRequest();
openAIRequest.setMessages(messages);
OpenAIResponse result = openAIService.askOpenAI(openAIRequest);
log.info(result.getChoices().get(0).getMessage().getContent());
return AIResponse.builder()
.resultData(AIResponse.ResultData.builder()
.result(result.getChoices().get(0).getMessage().getContent())
.build())
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
private List<Map<String, String>> splitDataToMessages(List<Map<String,String>> messages, List<?> dataList, String userMessage) {
String dataJson;
try {
dataJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(dataList);
} catch (JsonProcessingException e) {
throw new RuntimeException("JSON 변환 실패", e);
}
messages.add(CommonUtils.getAIMessage(AIRole.user, messageMerge(userMessage, dataJson)));
return messages;
}
private String messageMerge(String message, String data){
return String.format("사용자 질문: %s\n\n아래는 시스템이 제공하는 데이터입니다.\n%s", message, data);
}
private List<Map<String,String>> initMessage(){
List<Map<String,String>> messages = new ArrayList<>();
messages.add(CommonUtils.getAIMessage(AIRole.system,
"""
너는 프론트엔드 게시용 데이터를 생성하는 게임 데이터 분석 AI야. \
사용자는 게임 로그 데이터와 함께 다양한 질문을 보낼 수 있어. \
너는 항상 HTML 또는 React 코드 형식으로 응답해야 해. \
응답에는 반드시 다음 항목을 포함해줘: \
1) 분석된 내용 설명 \
2) 분석된 요약 결과 (표 또는 문단) \
3) 시각화 차트 (예: bar chart, pie chart 등) \
응답은 반드시 한국어로 작성해. \
절대로 파이썬, Java, Node.js 코드 같은 것은 포함하지 마. \
사용자의 웹에 그대로 게시될 수 있는 코드만 생성해. \
React를 쓸 경우, React 18 기준 코드로 TailwindCSS 기반의 스타일을 사용해줘.
"""));
return messages;
}
private List<?> getDataList(AIRequestType type, Map<String, Object> conditions){
switch (type){
case BUSINESS_LOG -> {
LogGenericRequest logReq = mapper.convertValue(conditions, LogGenericRequest.class);
List<GenericMongoLog> logs = businessLogGenericService.loadBusinessLogData(logReq, GenericMongoLog.class, true);
return logs;
}
case MAIL -> {
List<Mail> mailList = mailMapper.getMailList(conditions);
return mailList;
}
default -> throw new RuntimeException("Not Type");
}
}
}