Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/main/java/com/back/domain/chatbot/dto/ChatResponseDto.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.back.domain.chatbot.dto;

import com.back.domain.chatbot.enums.MessageSender;
import com.back.domain.chatbot.enums.MessageType;
import lombok.AllArgsConstructor;
import lombok.Builder;
Expand All @@ -16,9 +17,12 @@
@Builder
public class ChatResponseDto {

private Long id; // 메시지 ID (DB 저장 후 생성)
private Long userId; // 사용자 ID
private String message; // 텍스트 메시지
private MessageSender sender; // 메시지 발신자 (USER / CHATBOT)
private MessageType type; // 메시지 표시 타입
private LocalDateTime timestamp;
private LocalDateTime createdAt; // 생성 시간 (timestamp → createdAt으로 변경)

// 단계별 추천 관련 데이터 (type이 RADIO_OPTIONS 또는 CARD_LIST일 때 사용)
private StepRecommendationResponseDto stepData;
Expand All @@ -30,12 +34,14 @@ public class ChatResponseDto {
public ChatResponseDto(String message) {
this.message = message;
this.type = MessageType.TEXT;
this.timestamp = LocalDateTime.now();
this.sender = MessageSender.CHATBOT;
this.createdAt = LocalDateTime.now();
}

public ChatResponseDto(String message, StepRecommendationResponseDto stepData) {
this.message = message;
this.timestamp = LocalDateTime.now();
this.sender = MessageSender.CHATBOT;
this.createdAt = LocalDateTime.now();
this.stepData = stepData;

// stepData 내용에 따라 type 자동 설정
Expand Down
71 changes: 52 additions & 19 deletions src/main/java/com/back/domain/chatbot/service/ChatbotService.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,15 @@ else if (currentStep >= 1 && currentStep <= 4) {

// ========== 3순위: 기본 일반 대화 ==========
log.info("[DEFAULT] 일반 대화 모드 - userId: {}", requestDto.getUserId());
String response = generateAIResponse(requestDto);
ChatConversation savedResponse = generateAIResponse(requestDto);

return ChatResponseDto.builder()
.message(response)
.id(savedResponse.getId())
.userId(requestDto.getUserId())
.message(savedResponse.getMessage())
.sender(MessageSender.CHATBOT)
.type(MessageType.TEXT)
.timestamp(LocalDateTime.now())
.createdAt(savedResponse.getCreatedAt())
.build();

} catch (Exception e) {
Expand Down Expand Up @@ -170,9 +173,10 @@ private String buildConversationContext(List<ChatConversation> recentChats) {

/**
* 대화 저장 - 변경사항: 사용자 메시지와 봇 응답을 각각 별도로 저장
* @return 저장된 봇 응답 엔티티 (id 포함)
*/
@Transactional
public void saveConversation(ChatRequestDto requestDto, String response) {
public ChatConversation saveConversation(ChatRequestDto requestDto, String response) {
// 1. 사용자 메시지 저장
ChatConversation userMessage = ChatConversation.builder()
.userId(requestDto.getUserId())
Expand All @@ -189,7 +193,7 @@ public void saveConversation(ChatRequestDto requestDto, String response) {
.sender(MessageSender.CHATBOT)
.createdAt(LocalDateTime.now())
.build();
chatConversationRepository.save(botResponse);
return chatConversationRepository.save(botResponse);
}

/**
Expand Down Expand Up @@ -254,6 +258,7 @@ public ChatResponseDto createGreetingMessage(Long userId) {
// 중복 확인: 동일한 인사말이 이미 존재하는지 확인
boolean greetingExists = chatConversationRepository.existsByUserIdAndMessage(userId, greetingMessage);

ChatConversation savedGreeting = null;
// 중복되지 않을 경우에만 DB에 저장
if (!greetingExists) {
ChatConversation greeting = ChatConversation.builder()
Expand All @@ -262,18 +267,21 @@ public ChatResponseDto createGreetingMessage(Long userId) {
.sender(MessageSender.CHATBOT)
.createdAt(LocalDateTime.now())
.build();
chatConversationRepository.save(greeting);
savedGreeting = chatConversationRepository.save(greeting);
log.info("인사말 저장 완료 - userId: {}", userId);
} else {
log.info("이미 인사말이 존재하여 저장 생략 - userId: {}", userId);
}

// ChatResponseDto 반환
// ChatResponseDto 반환 (요청된 형식에 맞춰 id, userId, sender, type, createdAt 포함)
return ChatResponseDto.builder()
.id(savedGreeting != null ? savedGreeting.getId() : null)
.userId(userId)
.message(greetingMessage)
.sender(MessageSender.CHATBOT)
.type(MessageType.RADIO_OPTIONS)
.stepData(stepData)
.timestamp(LocalDateTime.now())
.createdAt(LocalDateTime.now())
.build();
}

Expand Down Expand Up @@ -350,8 +358,9 @@ private String postProcessResponse(String response, InternalMessageType type) {

/**
* AI 응답 생성
* @return 저장된 봇 응답 엔티티 (id 포함)
*/
private String generateAIResponse(ChatRequestDto requestDto) {
private ChatConversation generateAIResponse(ChatRequestDto requestDto) {
log.info("Normal chat mode for userId: {}", requestDto.getUserId());

// 메시지 타입 감지 (내부 enum 사용)
Expand All @@ -378,10 +387,8 @@ private String generateAIResponse(ChatRequestDto requestDto) {
// 응답 후처리
response = postProcessResponse(response, messageType);

// 대화 저장 - 사용자 메시지와 봇 응답을 각각 저장
saveConversation(requestDto, response);

return response;
// 대화 저장 - 사용자 메시지와 봇 응답을 각각 저장하고 저장된 봇 응답 반환
return saveConversation(requestDto, response);
}

/**
Expand All @@ -390,8 +397,9 @@ private String generateAIResponse(ChatRequestDto requestDto) {
public ChatResponseDto createLoadingMessage() {
return ChatResponseDto.builder()
.message("응답을 생성하는 중...")
.sender(MessageSender.CHATBOT)
.type(MessageType.LOADING)
.timestamp(LocalDateTime.now())
.createdAt(LocalDateTime.now())
.metaData(ChatResponseDto.MetaData.builder()
.isTyping(true)
.build())
Expand Down Expand Up @@ -435,12 +443,15 @@ private boolean isStepRecommendationTrigger(String message) {
* 일반 대화와 구분하여 추천에 특화된 응답 생성
*/
private ChatResponseDto generateAIResponseWithContext(ChatRequestDto requestDto, String mode) {
String response = generateAIResponse(requestDto);
ChatConversation savedResponse = generateAIResponse(requestDto);

return ChatResponseDto.builder()
.message(response)
.id(savedResponse.getId())
.userId(requestDto.getUserId())
.message(savedResponse.getMessage())
.sender(MessageSender.CHATBOT)
.type(MessageType.TEXT)
.timestamp(LocalDateTime.now())
.createdAt(savedResponse.getCreatedAt())
.metaData(ChatResponseDto.MetaData.builder()
.actionType(mode)
.currentStep(0)
Expand All @@ -455,8 +466,9 @@ private ChatResponseDto generateAIResponseWithContext(ChatRequestDto requestDto,
private ChatResponseDto createErrorResponse(String errorMessage) {
return ChatResponseDto.builder()
.message(errorMessage)
.sender(MessageSender.CHATBOT)
.type(MessageType.ERROR)
.timestamp(LocalDateTime.now())
.createdAt(LocalDateTime.now())
.build();
}

Expand Down Expand Up @@ -508,6 +520,24 @@ private ChatResponseDto handleStepRecommendation(ChatRequestDto requestDto) {
type = MessageType.RADIO_OPTIONS;
}

// 사용자 메시지 저장 (단계별 추천 요청)
ChatConversation userMessage = ChatConversation.builder()
.userId(requestDto.getUserId())
.message(requestDto.getMessage())
.sender(MessageSender.USER)
.createdAt(LocalDateTime.now())
.build();
chatConversationRepository.save(userMessage);

// 봇 응답 저장
ChatConversation botResponse = ChatConversation.builder()
.userId(requestDto.getUserId())
.message(message)
.sender(MessageSender.CHATBOT)
.createdAt(LocalDateTime.now())
.build();
ChatConversation savedResponse = chatConversationRepository.save(botResponse);

// 메타데이터 포함
ChatResponseDto.MetaData metaData = ChatResponseDto.MetaData.builder()
.currentStep(currentStep)
Expand All @@ -517,11 +547,14 @@ private ChatResponseDto handleStepRecommendation(ChatRequestDto requestDto) {
.build();

return ChatResponseDto.builder()
.id(savedResponse.getId())
.userId(requestDto.getUserId())
.message(message)
.sender(MessageSender.CHATBOT)
.type(type)
.stepData(stepData)
.metaData(metaData)
.timestamp(LocalDateTime.now())
.createdAt(savedResponse.getCreatedAt())
.build();
}

Expand Down