Skip to content

Commit 1fcdc46

Browse files
authored
Merge pull request #223 from prgrms-web-devcourse-final-project/chore#197
[chore] 메인 브랜치 병합 테스트
2 parents 1c818b9 + 2cdd242 commit 1fcdc46

File tree

72 files changed

+3487
-638
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+3487
-638
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ dependencies {
5050

5151
// AWS S3
5252
implementation("io.awspring.cloud:spring-cloud-aws-starter-s3:3.4.0")
53+
implementation("com.amazonaws:aws-java-sdk-s3:1.12.777")
5354

5455
runtimeOnly("com.h2database:h2")
5556
runtimeOnly("com.mysql:mysql-connector-j")

src/main/java/com/back/domain/chatbot/controller/ChatbotController.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
import com.back.domain.chatbot.dto.ChatRequestDto;
44
import com.back.domain.chatbot.dto.ChatResponseDto;
5+
import com.back.domain.chatbot.dto.SaveBotMessageDto;
56
import com.back.domain.chatbot.entity.ChatConversation;
67
import com.back.domain.chatbot.service.ChatbotService;
78
import com.back.global.rsData.RsData;
9+
import io.swagger.v3.oas.annotations.Operation;
810
import jakarta.validation.Valid;
911
import lombok.RequiredArgsConstructor;
1012
import lombok.extern.slf4j.Slf4j;
@@ -22,6 +24,7 @@ public class ChatbotController {
2224
private final ChatbotService chatbotService;
2325

2426
@PostMapping("/chat")
27+
@Operation(summary = "채팅 메시지 보내기", description = "자율형 대화 및 단계별 추천 두가지 모드 지원")
2528
public ResponseEntity<RsData<ChatResponseDto>> sendMessage(@Valid @RequestBody ChatRequestDto requestDto) {
2629
try {
2730
ChatResponseDto response = chatbotService.sendMessage(requestDto);
@@ -34,6 +37,7 @@ public ResponseEntity<RsData<ChatResponseDto>> sendMessage(@Valid @RequestBody C
3437
}
3538

3639
@GetMapping("/history/user/{userId}")
40+
@Operation(summary = "유저 대화 히스토리", description = "사용자 채팅 기록 조회")
3741
public ResponseEntity<RsData<List<ChatConversation>>> getUserChatHistory(@PathVariable Long userId) {
3842
try {
3943
List<ChatConversation> history = chatbotService.getUserChatHistory(userId);
@@ -44,4 +48,31 @@ public ResponseEntity<RsData<List<ChatConversation>>> getUserChatHistory(@PathVa
4448
.body(RsData.failOf("서버 오류가 발생했습니다."));
4549
}
4650
}
51+
52+
@PostMapping("/bot-message")
53+
@Operation(summary = "봇 메시지 저장", description = "FE에서 생성한 봇 메시지(인사말 등)를 DB에 저장")
54+
public ResponseEntity<RsData<ChatConversation>> saveBotMessage(@Valid @RequestBody SaveBotMessageDto requestDto) {
55+
try {
56+
ChatConversation savedMessage = chatbotService.saveBotMessage(requestDto);
57+
return ResponseEntity.ok(RsData.successOf(savedMessage));
58+
} catch (Exception e) {
59+
log.error("봇 메시지 저장 중 오류 발생: ", e);
60+
return ResponseEntity.internalServerError()
61+
.body(RsData.failOf("서버 오류가 발생했습니다."));
62+
}
63+
}
64+
65+
@PostMapping("/greeting/{userId}")
66+
@Operation(summary = "인사말 생성", description = "사용자가 채팅을 시작할 때 기본 인사말을 생성하고 저장")
67+
public ResponseEntity<RsData<ChatResponseDto>> createGreeting(@PathVariable Long userId) {
68+
try {
69+
ChatResponseDto greeting = chatbotService.createGreetingMessage(userId);
70+
return ResponseEntity.ok(RsData.successOf(greeting));
71+
} catch (Exception e) {
72+
log.error("인사말 생성 중 오류 발생: ", e);
73+
return ResponseEntity.internalServerError()
74+
.body(RsData.failOf("서버 오류가 발생했습니다."));
75+
}
76+
}
77+
4778
}

src/main/java/com/back/domain/chatbot/dto/ChatRequestDto.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ public class ChatRequestDto {
1313
@NotBlank(message = "메시지는 필수입니다.")
1414
private String message;
1515

16-
1716
private Long userId;
17+
18+
// 단계별 추천 관련 필드들
19+
private boolean isStepRecommendation = false;
20+
private Integer currentStep;
21+
private String selectedAlcoholStrength; // "ALL" 처리를 위해 스텝 3개 String으로 변경
22+
private String selectedAlcoholBaseType;
23+
private String selectedCocktailType;
1824
}
Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.back.domain.chatbot.dto;
22

3+
import com.back.domain.chatbot.enums.MessageType;
34
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
46
import lombok.Getter;
57
import lombok.NoArgsConstructor;
68
import lombok.Setter;
@@ -11,13 +13,56 @@
1113
@Setter
1214
@NoArgsConstructor
1315
@AllArgsConstructor
16+
@Builder
1417
public class ChatResponseDto {
1518

16-
private String response;
19+
private String message; // 텍스트 메시지
20+
private MessageType type; // 메시지 표시 타입
1721
private LocalDateTime timestamp;
1822

19-
public ChatResponseDto(String response) {
20-
this.response = response;
23+
// 단계별 추천 관련 데이터 (type이 RADIO_OPTIONS 또는 CARD_LIST일 때 사용)
24+
private StepRecommendationResponseDto stepData;
25+
26+
// 추가 메타데이터
27+
private MetaData metaData;
28+
29+
// 생성자들
30+
public ChatResponseDto(String message) {
31+
this.message = message;
32+
this.type = MessageType.TEXT;
33+
this.timestamp = LocalDateTime.now();
34+
}
35+
36+
public ChatResponseDto(String message, StepRecommendationResponseDto stepData) {
37+
this.message = message;
2138
this.timestamp = LocalDateTime.now();
39+
this.stepData = stepData;
40+
41+
// stepData 내용에 따라 type 자동 설정
42+
if (stepData != null) {
43+
if (stepData.getOptions() != null && !stepData.getOptions().isEmpty()) {
44+
this.type = MessageType.RADIO_OPTIONS;
45+
} else if (stepData.getRecommendations() != null && !stepData.getRecommendations().isEmpty()) {
46+
this.type = MessageType.CARD_LIST;
47+
} else {
48+
this.type = MessageType.TEXT;
49+
}
50+
} else {
51+
this.type = MessageType.TEXT;
52+
}
53+
}
54+
55+
// 메타데이터 내부 클래스
56+
@Getter
57+
@Setter
58+
@NoArgsConstructor
59+
@AllArgsConstructor
60+
@Builder
61+
public static class MetaData {
62+
private Integer currentStep; // 현재 단계 (단계별 추천)
63+
private Integer totalSteps; // 전체 단계 수
64+
private Boolean isTyping; // 타이핑 애니메이션 표시 여부
65+
private Integer delay; // 메시지 표시 지연 시간(ms)
66+
private String actionType; // 버튼 액션 타입
2267
}
2368
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
package com.back.domain.chatbot.dto;
3+
4+
import jakarta.validation.constraints.NotBlank;
5+
import jakarta.validation.constraints.NotNull;
6+
import lombok.AllArgsConstructor;
7+
import lombok.Getter;
8+
import lombok.NoArgsConstructor;
9+
import lombok.Setter;
10+
11+
@Getter
12+
@Setter
13+
@NoArgsConstructor
14+
@AllArgsConstructor
15+
public class SaveBotMessageDto {
16+
17+
@NotNull(message = "사용자 ID는 필수입니다.")
18+
private Long userId;
19+
20+
@NotBlank(message = "메시지 내용은 필수입니다.")
21+
private String message;
22+
23+
// 선택적: 메시지 타입 (GREETING, HELP, ERROR 등)
24+
private String messageType;
25+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.back.domain.chatbot.dto;
2+
3+
import com.back.domain.cocktail.dto.CocktailSummaryResponseDto;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
7+
import lombok.Setter;
8+
9+
import java.util.List;
10+
11+
@Getter
12+
@Setter
13+
@NoArgsConstructor
14+
@AllArgsConstructor
15+
public class StepRecommendationResponseDto {
16+
17+
private Integer currentStep; // 현재 단계
18+
private String stepTitle; // 단계 제목 (예: "원하시는 도수를 선택해주세요!")
19+
private List<StepOption> options; // 선택 옵션들
20+
private List<CocktailSummaryResponseDto> recommendations; // 최종 추천 칵테일 (4단계에서만)
21+
private boolean isCompleted; // 추천이 완료되었는지 여부
22+
23+
@Getter
24+
@Setter
25+
@NoArgsConstructor
26+
@AllArgsConstructor
27+
public static class StepOption {
28+
private String value; // enum 값 (예: "NON_ALCOHOLIC")
29+
private String label; // 화면에 표시될 텍스트 (예: "논알콜 (0%)")
30+
private String description; // 부가 설명 (선택사항)
31+
}
32+
}

src/main/java/com/back/domain/chatbot/entity/ChatConversation.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.back.domain.chatbot.entity;
22

3+
import com.back.domain.chatbot.enums.MessageSender;
34
import jakarta.persistence.*;
45
import lombok.*;
6+
import org.springframework.data.annotation.CreatedDate;
57

68
import java.time.LocalDateTime;
79

@@ -19,18 +21,17 @@ public class ChatConversation {
1921
@GeneratedValue(strategy = IDENTITY)
2022
private Long id;
2123

24+
@Column(nullable = false)
2225
private Long userId;
2326

24-
@Column(columnDefinition = "TEXT")
25-
private String userMessage;
27+
@Column(columnDefinition = "TEXT", nullable = false)
28+
private String message;
2629

27-
@Column(columnDefinition = "TEXT")
28-
private String botResponse;
30+
@Enumerated(EnumType.STRING)
31+
@Column(nullable = false, length = 20)
32+
@Builder.Default
33+
private MessageSender sender = MessageSender.USER;
2934

35+
@CreatedDate
3036
private LocalDateTime createdAt;
31-
32-
@PrePersist
33-
protected void onCreate() {
34-
createdAt = LocalDateTime.now();
35-
}
3637
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.back.domain.chatbot.enums;
2+
3+
public enum MessageSender {
4+
USER("사용자"),
5+
CHATBOT("챗봇");
6+
7+
private final String description;
8+
9+
MessageSender(String description) {
10+
this.description = description;
11+
}
12+
13+
public String getDescription() {
14+
return description;
15+
}
16+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.back.domain.chatbot.enums;
2+
3+
public enum MessageType {
4+
TEXT("텍스트"), // 일반 텍스트 메시지
5+
RADIO_OPTIONS("라디오옵션"), // 라디오 버튼 선택지
6+
CARD_LIST("카드리스트"), // 칵테일 추천 카드 리스트
7+
LOADING("로딩중"), // 로딩 메시지
8+
ERROR("에러"); // 에러 메시지
9+
10+
private final String description;
11+
12+
MessageType(String description) {
13+
this.description = description;
14+
}
15+
16+
public String getDescription() {
17+
return description;
18+
}
19+
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package com.back.domain.chatbot.repository;
22

33
import com.back.domain.chatbot.entity.ChatConversation;
4-
import org.springframework.data.domain.Page;
5-
import org.springframework.data.domain.Pageable;
64
import org.springframework.data.jpa.repository.JpaRepository;
75
import org.springframework.stereotype.Repository;
86

@@ -11,7 +9,9 @@
119
@Repository
1210
public interface ChatConversationRepository extends JpaRepository<ChatConversation, Long> {
1311

14-
Page<ChatConversation> findByUserIdOrderByCreatedAtDesc(Long userId, Pageable pageable);
12+
List<ChatConversation> findByUserIdOrderByCreatedAtDesc(Long userId);
1513

16-
List<ChatConversation> findTop5ByUserIdOrderByCreatedAtDesc(Long userId);
14+
List<ChatConversation> findTop20ByUserIdOrderByCreatedAtDesc(Long userId);
15+
16+
boolean existsByUserIdAndMessage(Long userId, String message);
1717
}

0 commit comments

Comments
 (0)