From 8ac69f54227d2a60d29993b5eb33b21d2fdb21fa Mon Sep 17 00:00:00 2001 From: sunninz Date: Mon, 15 Sep 2025 16:04:56 +0900 Subject: [PATCH] =?UTF-8?q?:sparkles:=20(#314)=20=EC=9D=B4=EC=A0=84=20?= =?UTF-8?q?=EC=B1=84=ED=8C=85=20=EB=82=B4=EC=9A=A9=20=EB=B6=88=EB=9F=AC?= =?UTF-8?q?=EC=98=A4=EA=B8=B0=20=EB=A1=9C=EC=A7=81=20=EC=84=A4=EA=B3=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/QuestionController.java | 7 ++++ .../dto/response/QuestionResponseDTO.java | 11 ++++++ .../question/exception/QuestionErrorCode.java | 3 +- .../question/service/QuestionService.java | 2 + .../question/service/QuestionServiceImpl.java | 37 +++++++++++++++++++ 5 files changed, 59 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/org/example/backend/domain/question/controller/QuestionController.java b/backend/src/main/java/org/example/backend/domain/question/controller/QuestionController.java index 26ed0aed..df392dca 100644 --- a/backend/src/main/java/org/example/backend/domain/question/controller/QuestionController.java +++ b/backend/src/main/java/org/example/backend/domain/question/controller/QuestionController.java @@ -38,4 +38,11 @@ public ApiResponse getQuestions(@PathVariable("lectureId") UUID lectureId) { return ApiResponse.onSuccess(result); } } + + // 이전 내용 불러오기 + @GetMapping("/chatting/before/{lectureId}") + public ApiResponse> getBeforeChatting(@PathVariable("lectureId") UUID lectureId) { + List result = questionService.getBeforeChatting(lectureId); + return ApiResponse.onSuccess(result); + } } diff --git a/backend/src/main/java/org/example/backend/domain/question/dto/response/QuestionResponseDTO.java b/backend/src/main/java/org/example/backend/domain/question/dto/response/QuestionResponseDTO.java index db8788d7..6ea620f0 100644 --- a/backend/src/main/java/org/example/backend/domain/question/dto/response/QuestionResponseDTO.java +++ b/backend/src/main/java/org/example/backend/domain/question/dto/response/QuestionResponseDTO.java @@ -4,6 +4,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.example.backend.domain.user.entity.Role; import java.time.LocalDateTime; import java.util.UUID; @@ -33,4 +34,14 @@ public static class student { private String content; } + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class beforeChatting { + private String content; + private LocalDateTime timestamp; + private Role role; + } + } diff --git a/backend/src/main/java/org/example/backend/domain/question/exception/QuestionErrorCode.java b/backend/src/main/java/org/example/backend/domain/question/exception/QuestionErrorCode.java index 28232cab..400b2d81 100644 --- a/backend/src/main/java/org/example/backend/domain/question/exception/QuestionErrorCode.java +++ b/backend/src/main/java/org/example/backend/domain/question/exception/QuestionErrorCode.java @@ -9,7 +9,8 @@ @Getter @AllArgsConstructor public enum QuestionErrorCode implements BaseErrorCode { - _FORBIDDEN_LECTURE_ACCESS(HttpStatus.FORBIDDEN,"QUESTION403_1","해당 강의를 수강중인 학생만 조회가능합니다."); + _FORBIDDEN_LECTURE_ACCESS(HttpStatus.FORBIDDEN,"QUESTION403_1","해당 강의를 수강중인 학생만 조회가능합니다."), + _INVALID_JSON_FORMAT(HttpStatus.BAD_REQUEST,"QUESTION400_1","저장된 채팅 데이터를 읽는 데 실패했습니다."); private final HttpStatus httpStatus; private final String code; diff --git a/backend/src/main/java/org/example/backend/domain/question/service/QuestionService.java b/backend/src/main/java/org/example/backend/domain/question/service/QuestionService.java index 6f834e16..0af69859 100644 --- a/backend/src/main/java/org/example/backend/domain/question/service/QuestionService.java +++ b/backend/src/main/java/org/example/backend/domain/question/service/QuestionService.java @@ -11,4 +11,6 @@ public interface QuestionService { List getTeacherQuestions(UUID lectureId, User user); //학생용 질문 조회 List getStudentQuestions(UUID lectureId, User user); + // 이전 채팅 내용 불러오개 + List getBeforeChatting(UUID lectureId); } diff --git a/backend/src/main/java/org/example/backend/domain/question/service/QuestionServiceImpl.java b/backend/src/main/java/org/example/backend/domain/question/service/QuestionServiceImpl.java index 4ded896f..02717cfb 100644 --- a/backend/src/main/java/org/example/backend/domain/question/service/QuestionServiceImpl.java +++ b/backend/src/main/java/org/example/backend/domain/question/service/QuestionServiceImpl.java @@ -1,5 +1,7 @@ package org.example.backend.domain.question.service; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import org.example.backend.domain.question.converter.QuestionConverter; import org.example.backend.domain.question.dto.response.QuestionResponseDTO; @@ -8,8 +10,11 @@ import org.example.backend.domain.question.repository.QuestionRepository; import org.example.backend.domain.studentClass.repository.StudentClassRepository; import org.example.backend.domain.user.entity.User; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.UUID; @@ -20,6 +25,8 @@ public class QuestionServiceImpl implements QuestionService { private final QuestionRepository questionRepository; private final StudentClassRepository studentClassRepository; private final QuestionConverter questionConverter; + private final RedisTemplate redisTemplate; + private final ObjectMapper objectMapper; @Override public List getTeacherQuestions(UUID lectureId, User user ) { @@ -41,4 +48,34 @@ public List getStudentQuestions(UUID lectureId, Use .map(questionConverter::toStudentQuestions) .toList(); } + + // 이전 내용 불러오기 + @Override + public List getBeforeChatting(UUID lectureId) { + String redisKey = "chat:lecture:" + lectureId; + + List rawMessages = redisTemplate.opsForList().range(redisKey, 0, -1); + + // 이전 내용이 없다면 빈배열 반환 + if(rawMessages == null || rawMessages.isEmpty()){ + return Collections.emptyList(); + } + + // 반환리스트 + List chatList = new ArrayList<>(); + + // 최신 메시지가 먼저 저장됨 -> 역순으로 순회 + for(int i=rawMessages.size()-1;i>=0;i--){ + try{ + // JSON 문자열 -> DTO 변환 + QuestionResponseDTO.beforeChatting dto = objectMapper.readValue(rawMessages.get(i), QuestionResponseDTO.beforeChatting.class); + chatList.add(dto); + } + catch (JsonProcessingException e){ + // 파싱 실패 + throw new QuestionException(QuestionErrorCode._INVALID_JSON_FORMAT); + } + } + return chatList; + } }