From 4b483eea2df2adcd53fa8a5312d067bc65bda6f3 Mon Sep 17 00:00:00 2001 From: yulmam Date: Mon, 22 Jul 2024 17:32:23 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20chatController=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../board/controller/BoardController.java | 18 +++-- .../board/service/BoardServiceImpl.java | 17 ++-- .../ws/controller/ChatController.java | 81 +++++++++++++++++++ .../edufocus/ws/entity/dto/HelloDto.java | 13 +++ .../edufocus/ws/entity/dto/MessageDto.java | 11 +++ .../edufocus/ws/entity/dto/QuizDto.java | 13 +++ .../ws/entity/dto/ResponseChatUserDto.java | 6 ++ .../edufocus/ws/entity/vo/ChatUser.java | 25 ++++++ .../edufocus/ws/service/ChatService.java | 10 +++ .../edufocus/ws/service/ChatServiceImpl.java | 9 +++ 10 files changed, 187 insertions(+), 16 deletions(-) create mode 100644 backend/src/main/java/com/edufocus/edufocus/ws/controller/ChatController.java create mode 100644 backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/HelloDto.java create mode 100644 backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/MessageDto.java create mode 100644 backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/QuizDto.java create mode 100644 backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/ResponseChatUserDto.java create mode 100644 backend/src/main/java/com/edufocus/edufocus/ws/entity/vo/ChatUser.java create mode 100644 backend/src/main/java/com/edufocus/edufocus/ws/service/ChatService.java create mode 100644 backend/src/main/java/com/edufocus/edufocus/ws/service/ChatServiceImpl.java diff --git a/backend/src/main/java/com/edufocus/edufocus/board/controller/BoardController.java b/backend/src/main/java/com/edufocus/edufocus/board/controller/BoardController.java index d25d940..a1ead74 100644 --- a/backend/src/main/java/com/edufocus/edufocus/board/controller/BoardController.java +++ b/backend/src/main/java/com/edufocus/edufocus/board/controller/BoardController.java @@ -30,22 +30,18 @@ public class BoardController { } @GetMapping() - public ResponseEntity searchBoards( + public ResponseEntity> searchBoards( @RequestParam(value = "category", required = false, defaultValue = "announcement") String category, - @RequestParam(value = "lectureId", required = true) long lectureId, + @RequestParam(value = "lectureId") long lectureId, @RequestParam(value = "pageNo", required = false, defaultValue = "0") int pageNo ){ List boardSummaries = boardService.findBoards(pageNo, category, lectureId); - if(boardSummaries.isEmpty()){ - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - return new ResponseEntity<>(boardSummaries, HttpStatus.OK); } @GetMapping(value = "/{boardId}") - public ResponseEntity getBoardDetail( + public ResponseEntity getBoardDetail( @PathVariable int boardId ){ ResponseBoardDetailDto responseBoardDetailDto = boardService.findBoardDetail(boardId); @@ -87,7 +83,7 @@ public class BoardController { } @GetMapping(value = "/comment/{boardId}") - public ResponseEntity getComments( + public ResponseEntity> getComments( @PathVariable int boardId ){ List comments = boardService.findComments(boardId); @@ -127,4 +123,10 @@ public class BoardController { return new ResponseEntity<>(HttpStatus.OK); } + + + @ExceptionHandler() + public ResponseEntity NoContentException(Exception exception){ + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } } diff --git a/backend/src/main/java/com/edufocus/edufocus/board/service/BoardServiceImpl.java b/backend/src/main/java/com/edufocus/edufocus/board/service/BoardServiceImpl.java index 29c5006..10426fb 100644 --- a/backend/src/main/java/com/edufocus/edufocus/board/service/BoardServiceImpl.java +++ b/backend/src/main/java/com/edufocus/edufocus/board/service/BoardServiceImpl.java @@ -16,6 +16,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.NoSuchElementException; import java.util.stream.Collectors; @Service @@ -49,14 +50,14 @@ public class BoardServiceImpl implements BoardService { @Transactional public ResponseBoardDetailDto findBoardDetail(long boardId) { return boardRepository.findById(boardId) - .orElseThrow() + .orElseThrow(NoSuchElementException::new) .makeDetailDto(); } @Transactional public void createBoard(long userId, RequestBoardDto requestBoardDto) { User user = userRepository.findById(userId).orElseThrow(); - Lecture lecture = lectureRepository.findById(requestBoardDto.getLectureId()).get(); + Lecture lecture = lectureRepository.findById(requestBoardDto.getLectureId()).orElseThrow(IllegalArgumentException::new); Board board = Board.builder() .title(requestBoardDto.getTitle()) @@ -71,7 +72,7 @@ public class BoardServiceImpl implements BoardService { @Transactional public void updateBoard(long boardId, RequestBoardUpdateDto requestBoardUpdateDto) { - Board board = boardRepository.findById(boardId).get(); + Board board = boardRepository.findById(boardId).orElseThrow(IllegalArgumentException::new); board.setTitle(requestBoardUpdateDto.getTitle()); board.setContent(requestBoardUpdateDto.getContent()); @@ -82,7 +83,7 @@ public class BoardServiceImpl implements BoardService { @Transactional public void deleteBoard(long boardId) { - Board board = boardRepository.findById(boardId).get(); + Board board = boardRepository.findById(boardId).orElseThrow(IllegalArgumentException::new); boardRepository.delete(board); } @@ -96,8 +97,8 @@ public class BoardServiceImpl implements BoardService { @Transactional public void createComment(long userId, long boardId, RequestCommentDto requestCommentDto) { - User user = userRepository.findById(userId).get(); - Board board = boardRepository.findById(boardId).get(); + User user = userRepository.findById(userId).orElseThrow(IllegalArgumentException::new); + Board board = boardRepository.findById(boardId).orElseThrow(IllegalArgumentException::new); Comment comment = Comment.builder() .content(requestCommentDto.getContent()) @@ -112,7 +113,7 @@ public class BoardServiceImpl implements BoardService { @Transactional public void updateComment(long commentId, RequestCommentDto requestCommentDto) { - Comment comment = commentRepository.findById(commentId).get(); + Comment comment = commentRepository.findById(commentId).orElseThrow(IllegalArgumentException::new); comment.setContent(requestCommentDto.getContent()); @@ -121,7 +122,7 @@ public class BoardServiceImpl implements BoardService { @Transactional public void deleteComment(long commentId) { - Comment comment = commentRepository.findById(commentId).get(); + Comment comment = commentRepository.findById(commentId).orElseThrow(NoSuchElementException::new); commentRepository.delete(comment); } diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/controller/ChatController.java b/backend/src/main/java/com/edufocus/edufocus/ws/controller/ChatController.java new file mode 100644 index 0000000..30af11a --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/controller/ChatController.java @@ -0,0 +1,81 @@ +package com.edufocus.edufocus.ws.controller; + + +import com.edufocus.edufocus.user.util.JWTUtil; +import com.edufocus.edufocus.ws.entity.dto.HelloDto; +import com.edufocus.edufocus.ws.entity.dto.MessageDto; +import com.edufocus.edufocus.ws.entity.dto.QuizDto; +import com.edufocus.edufocus.ws.entity.dto.ResponseChatUserDto; +import com.edufocus.edufocus.ws.service.ChatService; +import jakarta.websocket.Session; +import org.springframework.context.event.EventListener; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.messaging.Message; +import org.springframework.messaging.handler.annotation.DestinationVariable; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.SendTo; +import org.springframework.messaging.simp.SimpMessageHeaderAccessor; +import org.springframework.messaging.simp.SimpMessageSendingOperations; +import org.springframework.messaging.simp.stomp.StompHeaderAccessor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.socket.messaging.SessionDisconnectEvent; + +import java.util.List; + +@RestController +public class ChatController { + + private final SimpMessageSendingOperations simpMessageSendingOperations; + + private final ChatService chatService; + + private final JWTUtil jwtUtil; + + public ChatController(SimpMessageSendingOperations simpMessageSendingOperations, ChatService chatService, JWTUtil jwtUtil){ + this.simpMessageSendingOperations = simpMessageSendingOperations; + this.chatService = chatService; + this.jwtUtil = jwtUtil; + } + + @GetMapping("/chat/enter/{lectureId}") + public ResponseEntity enter(@PathVariable long lectureId){ + List chatUsers = chatService.findChatUsers(lectureId); + return new ResponseEntity<>(chatUsers, HttpStatus.OK); + } + + + @MessageMapping("/hello/{channelId}") + @SendTo("/sub/channel/{channelId}") + public ResponseChatUserDto hello(@DestinationVariable long channelId, SimpMessageHeaderAccessor simpMessageHeaderAccessor, @Header("Authorization") String token){ + String sessionId = simpMessageHeaderAccessor.getSessionId(); + + long userId = Long.parseLong(jwtUtil.getUserId(token)); + + chatService.saveChatUserInfo(userId, channelId, sessionId); + + return chatService.getChatUserInfo(userId); + } + + @MessageMapping("/message/{lectureId}") + @SendTo("/sub/channel/{lectureId}") + public MessageDto sendMessage(@DestinationVariable long lectureId, MessageDto messageDto){return messageDto;} + + @MessageMapping("/quiz/{lectureId}") + @SendTo("/sub/channel/{lectureId}") + public QuizDto quizStart(@DestinationVariable long lectureId, QuizDto quizDto){ + return quizDto; + } + + @EventListener + public void handleWebSocketDisconnectListener(SessionDisconnectEvent event){ + StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage()); + String sessionId = headerAccessor.getSessionId(); + long channelId = chatService.getChannelId(sessionId); + simpMessageSendingOperations.convertAndSend("/sub/channel/" + channelId); + } +} + diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/HelloDto.java b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/HelloDto.java new file mode 100644 index 0000000..55a6c4f --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/HelloDto.java @@ -0,0 +1,13 @@ +package com.edufocus.edufocus.ws.entity.dto; + + +import lombok.*; + +@Builder +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class HelloDto { + long channelId; + String name; +} diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/MessageDto.java b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/MessageDto.java new file mode 100644 index 0000000..17522a9 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/MessageDto.java @@ -0,0 +1,11 @@ +package com.edufocus.edufocus.ws.entity.dto; + + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class MessageDto { + int channelId; +} diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/QuizDto.java b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/QuizDto.java new file mode 100644 index 0000000..1900b3d --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/QuizDto.java @@ -0,0 +1,13 @@ +package com.edufocus.edufocus.ws.entity.dto; + + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class QuizDto { + int channelId; + int userId; + int quizSetId; +} diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/ResponseChatUserDto.java b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/ResponseChatUserDto.java new file mode 100644 index 0000000..f418b8f --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/ResponseChatUserDto.java @@ -0,0 +1,6 @@ +package com.edufocus.edufocus.ws.entity.dto; + +public class ResponseChatUserDto { + int userId; + int name; +} diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/entity/vo/ChatUser.java b/backend/src/main/java/com/edufocus/edufocus/ws/entity/vo/ChatUser.java new file mode 100644 index 0000000..7a5422a --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/entity/vo/ChatUser.java @@ -0,0 +1,25 @@ +package com.edufocus.edufocus.ws.entity.vo; + +import com.edufocus.edufocus.lecture.entity.Lecture; +import com.edufocus.edufocus.user.model.entity.User; +import jakarta.persistence.*; +import lombok.*; + + +@Entity +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ChatUser { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) // 자동 증가 설정 + int id; + @Column + String sessionId; + @OneToOne + User user; + @ManyToOne + Lecture lecture; +} \ No newline at end of file diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/service/ChatService.java b/backend/src/main/java/com/edufocus/edufocus/ws/service/ChatService.java new file mode 100644 index 0000000..765ddc1 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/service/ChatService.java @@ -0,0 +1,10 @@ +package com.edufocus.edufocus.ws.service; + +import com.edufocus.edufocus.ws.entity.dto.ResponseChatUserDto; + +public interface ChatService { + public void saveChatUserInfo(long userId, long channelId, String sessionId); + public ResponseChatUserDto getChatUserInfo(long userId); + + +} diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/service/ChatServiceImpl.java b/backend/src/main/java/com/edufocus/edufocus/ws/service/ChatServiceImpl.java new file mode 100644 index 0000000..8baccca --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/service/ChatServiceImpl.java @@ -0,0 +1,9 @@ +package com.edufocus.edufocus.ws.service; + + +import org.springframework.stereotype.Service; + +@Service +public class ChatServiceImpl implements ChatService{ + +}