Skip to content

Commit 2b6d592

Browse files
authored
Merge pull request #99 from TU-NEBULA/feature/SCRUM-241
SCRUM-241: 채팅 세션 메시지 조회 페이지네이션
2 parents c34c4d9 + 39d6502 commit 2b6d592

6 files changed

Lines changed: 96 additions & 25 deletions

File tree

src/main/java/com/team_nebula/nebula/domain/chatbot/api/ChatbotController.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package com.team_nebula.nebula.domain.chatbot.api;
22

3-
import java.util.List;
4-
53
import org.springframework.web.bind.annotation.GetMapping;
64
import org.springframework.web.bind.annotation.PathVariable;
75
import org.springframework.web.bind.annotation.PostMapping;
@@ -14,9 +12,10 @@
1412

1513
import com.team_nebula.nebula.domain.chatbot.dto.request.ChatRequestDTO;
1614
import com.team_nebula.nebula.domain.chatbot.dto.request.SessionRequestDTO;
17-
import com.team_nebula.nebula.domain.chatbot.dto.response.CharResponseDTO;
15+
import com.team_nebula.nebula.domain.chatbot.dto.response.ChatResponseDTO;
1816
import com.team_nebula.nebula.domain.chatbot.dto.response.SessionListResponseDTO;
1917
import com.team_nebula.nebula.domain.chatbot.dto.response.SessionResponseDTO;
18+
import com.team_nebula.nebula.domain.chatbot.dto.response.SessionsResponseDTO;
2019
import com.team_nebula.nebula.domain.chatbot.service.ChatbotService;
2120
import com.team_nebula.nebula.global.annotation.AuthUser;
2221
import com.team_nebula.nebula.global.apipayload.ApiResponse;
@@ -43,7 +42,7 @@ public ApiResponse<SessionResponseDTO> createSession(
4342

4443
@Operation(summary = "사용자 채팅 세션 목록 조회", description = "사용자 채팅 세션 목록을 조회하는 API")
4544
@GetMapping("/sessions")
46-
public ApiResponse<List<SessionListResponseDTO>> getSessions(
45+
public ApiResponse<SessionsResponseDTO> getSessions(
4746
@AuthUser Long userId,
4847
@RequestParam(name = "limit", defaultValue = "20") int limit,
4948
@RequestParam(name = "offset", defaultValue = "0") int offset) {
@@ -69,9 +68,11 @@ public SseEmitter chatStream(
6968

7069
@Operation(summary = "채팅 세션 메시지 조회", description = "채팅 세션의 메시지를 조회하는 API")
7170
@GetMapping("/sessions/{sessionId}/messages")
72-
public ApiResponse<List<CharResponseDTO>> getSessionMessages(
71+
public ApiResponse<ChatResponseDTO> getSessionMessages(
7372
@AuthUser Long userId,
74-
@PathVariable String sessionId) {
75-
return ApiResponse.onSuccess(chatbotService.getSessionMessages(userId, sessionId));
73+
@PathVariable String sessionId,
74+
@RequestParam(name = "page", defaultValue = "1") int page,
75+
@RequestParam(name = "size", defaultValue = "20") int size) {
76+
return ApiResponse.onSuccess(chatbotService.getSessionMessages(userId, sessionId, page, size));
7677
}
7778
}

src/main/java/com/team_nebula/nebula/domain/chatbot/dto/response/CharResponseDTO.java renamed to src/main/java/com/team_nebula/nebula/domain/chatbot/dto/response/ChatResponseDTO.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
@Builder
1212
@NoArgsConstructor
1313
@AllArgsConstructor
14-
public class CharResponseDTO {
14+
public class ChatResponseDTO {
1515
private String sessionId;
16+
1617
private List<MessageResponseDTO> messages;
1718

18-
}
19+
private PaginationResponseDTO pagination;
20+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.team_nebula.nebula.domain.chatbot.dto.response;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
7+
8+
@Getter
9+
@Builder
10+
@NoArgsConstructor
11+
@AllArgsConstructor
12+
public class PaginationResponseDTO {
13+
private int currentPage;
14+
15+
private int pageSize;
16+
17+
private int totalCount;
18+
19+
private int totalPages;
20+
21+
private boolean hasNext;
22+
23+
private boolean hasPrev;
24+
25+
private Integer nextPage;
26+
27+
private Integer prevPage;
28+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.team_nebula.nebula.domain.chatbot.dto.response;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
7+
8+
import java.util.List;
9+
10+
@Getter
11+
@Builder
12+
@NoArgsConstructor
13+
@AllArgsConstructor
14+
public class SessionsResponseDTO {
15+
private List<SessionListResponseDTO> sessions;
16+
private int total;
17+
}
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
package com.team_nebula.nebula.domain.chatbot.service;
22

3-
import java.util.List;
4-
53
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
64

75
import com.team_nebula.nebula.domain.chatbot.dto.request.ChatRequestDTO;
86
import com.team_nebula.nebula.domain.chatbot.dto.request.SessionRequestDTO;
9-
import com.team_nebula.nebula.domain.chatbot.dto.response.CharResponseDTO;
7+
import com.team_nebula.nebula.domain.chatbot.dto.response.ChatResponseDTO;
108
import com.team_nebula.nebula.domain.chatbot.dto.response.SessionListResponseDTO;
119
import com.team_nebula.nebula.domain.chatbot.dto.response.SessionResponseDTO;
10+
import com.team_nebula.nebula.domain.chatbot.dto.response.SessionsResponseDTO;
1211

1312
public interface ChatbotService {
1413
SseEmitter chatStream(Long userId, ChatRequestDTO request);
1514

16-
List<SessionListResponseDTO> getSessions(Long userId, int limit, int offset);
15+
SessionsResponseDTO getSessions(Long userId, int limit, int offset);
1716

1817
SessionListResponseDTO updateSession(Long userId, String sessionId, SessionRequestDTO request);
1918

2019
SessionResponseDTO createSession(Long userId, SessionRequestDTO request);
2120

22-
List<CharResponseDTO> getSessionMessages(Long userId, String sessionId);
21+
ChatResponseDTO getSessionMessages(Long userId, String sessionId, int page, int size);
2322
}

src/main/java/com/team_nebula/nebula/domain/chatbot/service/ChatbotServiceImpl.java

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
import com.fasterxml.jackson.databind.ObjectMapper;
1818
import com.team_nebula.nebula.domain.chatbot.dto.request.ChatRequestDTO;
1919
import com.team_nebula.nebula.domain.chatbot.dto.request.SessionRequestDTO;
20-
import com.team_nebula.nebula.domain.chatbot.dto.response.CharResponseDTO;
20+
import com.team_nebula.nebula.domain.chatbot.dto.response.ChatResponseDTO;
2121
import com.team_nebula.nebula.domain.chatbot.dto.response.MessageResponseDTO;
22+
import com.team_nebula.nebula.domain.chatbot.dto.response.PaginationResponseDTO;
2223
import com.team_nebula.nebula.domain.chatbot.dto.response.SessionListResponseDTO;
2324
import com.team_nebula.nebula.domain.chatbot.dto.response.SessionResponseDTO;
25+
import com.team_nebula.nebula.domain.chatbot.dto.response.SessionsResponseDTO;
2426
import com.team_nebula.nebula.global.apipayload.code.status.ErrorStatus;
2527
import com.team_nebula.nebula.global.apipayload.exception.GeneralException;
2628

@@ -79,7 +81,7 @@ private String extractSessionId(String responseBody) {
7981
}
8082

8183
@Override
82-
public List<SessionListResponseDTO> getSessions(Long userId, int limit, int offset) {
84+
public SessionsResponseDTO getSessions(Long userId, int limit, int offset) {
8385
try {
8486
String url = String.format("%s/chat/sessions?user_id=%d&limit=%d&offset=%d", aiChatUrl, userId, limit,
8587
offset);
@@ -101,16 +103,23 @@ public List<SessionListResponseDTO> getSessions(Long userId, int limit, int offs
101103
}
102104
}
103105

104-
private List<SessionListResponseDTO> parseSessionsFromResponse(String responseBody) {
106+
private SessionsResponseDTO parseSessionsFromResponse(String responseBody) {
105107
List<SessionListResponseDTO> sessions = new ArrayList<>();
108+
int total = 0;
106109

107110
try {
108111
JsonNode root = objectMapper.readTree(responseBody);
109-
JsonNode sessionsNode = root.path("data").path("sessions");
112+
JsonNode dataNode = root.path("data");
113+
JsonNode sessionsNode = dataNode.path("sessions");
114+
115+
total = dataNode.path("total").asInt(0);
110116

111117
if (!sessionsNode.isArray()) {
112118
log.warn("세션 목록이 배열이 아닙니다.");
113-
return sessions;
119+
return SessionsResponseDTO.builder()
120+
.sessions(sessions)
121+
.total(total)
122+
.build();
114123
}
115124

116125
for (JsonNode sessionNode : sessionsNode) {
@@ -129,7 +138,10 @@ private List<SessionListResponseDTO> parseSessionsFromResponse(String responseBo
129138
log.error("AI 세션 목록 JSON 파싱 실패", e);
130139
}
131140

132-
return sessions;
141+
return SessionsResponseDTO.builder()
142+
.sessions(sessions)
143+
.total(total)
144+
.build();
133145
}
134146

135147
private String getText(JsonNode node, String fieldName) {
@@ -224,9 +236,10 @@ private Map<String, Object> buildChatRequestBody(Long userId, ChatRequestDTO req
224236
}
225237

226238
@Override
227-
public List<CharResponseDTO> getSessionMessages(Long userId, String sessionId) {
239+
public ChatResponseDTO getSessionMessages(Long userId, String sessionId, int page, int size) {
228240
try {
229-
String url = String.format("%s/chat/sessions/%s/messages?user_id=%d", aiChatUrl, sessionId, userId);
241+
String url = String.format("%s/chat/sessions/%s/messages?user_id=%d&page=%d&size=%d",
242+
aiChatUrl, sessionId, userId, page, size);
230243

231244
HttpHeaders headers = new HttpHeaders();
232245
headers.setContentType(MediaType.APPLICATION_JSON);
@@ -245,6 +258,7 @@ public List<CharResponseDTO> getSessionMessages(Long userId, String sessionId) {
245258

246259
String receivedSessionId = getText(data, "session_id");
247260
JsonNode messagesNode = data.path("messages");
261+
JsonNode paginationNode = data.path("pagination");
248262

249263
List<MessageResponseDTO> messageList = new ArrayList<>();
250264

@@ -261,13 +275,23 @@ public List<CharResponseDTO> getSessionMessages(Long userId, String sessionId) {
261275
}
262276
}
263277

264-
CharResponseDTO responseDto = CharResponseDTO.builder()
278+
PaginationResponseDTO pagination = PaginationResponseDTO.builder()
279+
.currentPage(paginationNode.path("current_page").asInt(1))
280+
.pageSize(paginationNode.path("page_size").asInt(20))
281+
.totalCount(paginationNode.path("total_count").asInt(0))
282+
.totalPages(paginationNode.path("total_pages").asInt(0))
283+
.hasNext(paginationNode.path("has_next").asBoolean(false))
284+
.hasPrev(paginationNode.path("has_prev").asBoolean(false))
285+
.nextPage(paginationNode.path("next_page").isNull() ? null : paginationNode.path("next_page").asInt())
286+
.prevPage(paginationNode.path("prev_page").isNull() ? null : paginationNode.path("prev_page").asInt())
287+
.build();
288+
289+
return ChatResponseDTO.builder()
265290
.sessionId(receivedSessionId)
266291
.messages(messageList)
292+
.pagination(pagination)
267293
.build();
268294

269-
return List.of(responseDto);
270-
271295
} catch (Exception e) {
272296
log.error("세션 메시지 조회 중 오류 발생", e);
273297
throw new GeneralException(ErrorStatus._AI_CHATBOT_ERROR);

0 commit comments

Comments
 (0)