diff --git a/src/main/java/com/leets/X/domain/chat/controller/ChatRoomController.java b/src/main/java/com/leets/X/domain/chat/controller/ChatRoomController.java index fc011e6..490e828 100644 --- a/src/main/java/com/leets/X/domain/chat/controller/ChatRoomController.java +++ b/src/main/java/com/leets/X/domain/chat/controller/ChatRoomController.java @@ -1,10 +1,11 @@ package com.leets.X.domain.chat.controller; -import com.leets.X.domain.chat.dto.request.ChatRoomCheckRequstDto; import com.leets.X.domain.chat.dto.request.FindChatRoomRequestDto; import com.leets.X.domain.chat.dto.response.ChatRoomResponseDto; import com.leets.X.domain.chat.service.ChatRoomService; import com.leets.X.global.common.response.ResponseDto; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; @@ -13,6 +14,7 @@ import static com.leets.X.domain.chat.controller.ResponseMessage.*; +@Tag(name="ChatRoom") @Slf4j @RestController @RequestMapping("/api/v1/chatRoom") @@ -22,6 +24,7 @@ public class ChatRoomController { private final ChatRoomService chatRoomService; @PostMapping + @Operation(summary = "채팅 방 생성") public ResponseDto createChatRoom(@RequestBody @Valid FindChatRoomRequestDto findChatRoomRequestDto){ ChatRoomResponseDto response = chatRoomService.saveChatRoom(findChatRoomRequestDto); return ResponseDto.response(CHATROOM_CREATE_SUCCESS.getCode(), CHATROOM_CREATE_SUCCESS.getMessage(), response); @@ -31,13 +34,15 @@ public ResponseDto createChatRoom(@RequestBody @Valid FindC // user1Id와 user2Id의 채팅방이 있는 지 조회 @GetMapping("/{user1Id}/{user2Id}") + @Operation(summary = "채팅방 존재 여부 확인") public ResponseDto existChatRoom(@PathVariable Long user1Id, @PathVariable Long user2Id){ ChatRoomResponseDto response = chatRoomService.findUser1User2ChatRoom(user1Id , user2Id); - return ResponseDto.response(GET_ROOMID.getCode(), GET_ROOMID.getMessage(), response); + return ResponseDto.response(ROOMID_GET.getCode(), ROOMID_GET.getMessage(), response); } @PostMapping("/{roomId}") // addListener 테스트 용 + @Operation(summary = "채팅 방 addListener 테스트") public void addListener(@PathVariable @NotNull Long roomId) { chatRoomService.addListener(roomId); log.info(roomId+":addListener"); diff --git a/src/main/java/com/leets/X/domain/chat/controller/ChattingController.java b/src/main/java/com/leets/X/domain/chat/controller/ChattingController.java index 6132be4..cb6fdd9 100644 --- a/src/main/java/com/leets/X/domain/chat/controller/ChattingController.java +++ b/src/main/java/com/leets/X/domain/chat/controller/ChattingController.java @@ -1,20 +1,21 @@ package com.leets.X.domain.chat.controller; -import com.leets.X.domain.chat.dto.request.GetChatRoomRequestDto; import com.leets.X.domain.chat.dto.response.ChattingDto; import com.leets.X.domain.chat.dto.response.ChattingListResponseDto; import com.leets.X.domain.chat.service.ChattingService; import com.leets.X.global.common.response.ResponseDto; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import java.util.List; -import static com.leets.X.domain.chat.controller.ResponseMessage.GET_CHATROOM; -import static com.leets.X.domain.chat.controller.ResponseMessage.GET_CHATTING_LIST; +import static com.leets.X.domain.chat.controller.ResponseMessage.CHATROOM_GET; +import static com.leets.X.domain.chat.controller.ResponseMessage.CHATTINGLIST_GET; +@Tag(name="Chatting(ChatMessage)") @RestController @RequestMapping("/api/v1") @RequiredArgsConstructor @@ -22,18 +23,20 @@ public class ChattingController { private final ChattingService chattingService; - // 채팅방 하나를 조회해준다. (대화 내역을 돌려준다는 의미) @GetMapping("/chatting/{roomId}/{page}/{size}") - public ResponseDto findChatting(@PathVariable Long roomId, @PathVariable Integer page, @PathVariable Integer size) { - ChattingDto response = chattingService.getChatRoom(roomId, page, size); - return ResponseDto.response(GET_CHATROOM.getCode(), GET_CHATROOM.getMessage(), response); + @Operation(summary = "하나의 채팅방 + 해당 채팅 내역 조회") + public ResponseDto findChatting(@PathVariable Long roomId, @PathVariable Integer page, + @PathVariable Integer size, @AuthenticationPrincipal String email) { + ChattingDto response = chattingService.getChatRoom(roomId, page, size, email); + return ResponseDto.response(CHATROOM_GET.getCode(), CHATROOM_GET.getMessage(), response); } @GetMapping("/chattingList/{userId}") - public ResponseDto> findChattingList(@PathVariable Long userId){ - List response = chattingService.getChattingList(userId); - return ResponseDto.response(GET_CHATTING_LIST.getCode(), GET_CHATTING_LIST.getMessage(), response); + @Operation(summary = "유저가 속한 모든 채팅방 조회") + public ResponseDto> findChattingList(@PathVariable Long userId, @AuthenticationPrincipal String email){ + List response = chattingService.getChattingList(userId, email); + return ResponseDto.response(CHATTINGLIST_GET.getCode(), CHATTINGLIST_GET.getMessage(), response); } } diff --git a/src/main/java/com/leets/X/domain/chat/controller/ResponseMessage.java b/src/main/java/com/leets/X/domain/chat/controller/ResponseMessage.java index e5cd18f..e3a62c1 100644 --- a/src/main/java/com/leets/X/domain/chat/controller/ResponseMessage.java +++ b/src/main/java/com/leets/X/domain/chat/controller/ResponseMessage.java @@ -8,9 +8,9 @@ public enum ResponseMessage { CHATROOM_CREATE_SUCCESS(201,"채팅방 생성에 성공했습니다."), - GET_CHATROOM(200, "하나의 채팅방을 반환합니다."), - GET_ROOMID(200, "채팅방 번호를 반환합니다."), - GET_CHATTING_LIST(200, "모든 채팅방 목록을 반환합니다."); + CHATROOM_GET(200, "하나의 채팅방을 반환합니다."), + ROOMID_GET(200, "채팅방 번호를 반환합니다."), + CHATTINGLIST_GET(200, "모든 채팅방 목록을 반환합니다."); private final int code; private final String message; diff --git a/src/main/java/com/leets/X/domain/chat/dto/response/ChattingDto.java b/src/main/java/com/leets/X/domain/chat/dto/response/ChattingDto.java index ef4736f..1a53494 100644 --- a/src/main/java/com/leets/X/domain/chat/dto/response/ChattingDto.java +++ b/src/main/java/com/leets/X/domain/chat/dto/response/ChattingDto.java @@ -1,12 +1,26 @@ package com.leets.X.domain.chat.dto.response; +import com.leets.X.domain.user.domain.User; + import java.util.List; public record ChattingDto( - Long user1Id, - Long user2Id, - String user1Name, - String user2Name, + Long senderId, + String senderName, + + Long opponentId, + String opponentImageUrl, + String opponentName, + List chatMessageList ) { + + public static ChattingDto of(User sender, User opponent, List chatMessageList) { + return new ChattingDto( + sender.getId(), sender.getName(), + opponent.getId(), opponent.getName(), opponent.getImage().getUrl(), + chatMessageList + ); + } + } diff --git a/src/main/java/com/leets/X/domain/chat/dto/response/ChattingListResponseDto.java b/src/main/java/com/leets/X/domain/chat/dto/response/ChattingListResponseDto.java index 742ad39..2d4345a 100644 --- a/src/main/java/com/leets/X/domain/chat/dto/response/ChattingListResponseDto.java +++ b/src/main/java/com/leets/X/domain/chat/dto/response/ChattingListResponseDto.java @@ -1,22 +1,25 @@ package com.leets.X.domain.chat.dto.response; import com.leets.X.domain.chat.entity.ChatRoom; +import com.leets.X.domain.user.domain.User; public record ChattingListResponseDto( Long roomId, - Long user1Id, - Long user2Id, - String user1Name, - String user2Name, + + Long senderId, + String senderName, + + Long opponentId, + String opponentImageUrl, + String opponentName, + LatestMessageDto latestMessageDto ) { - public static ChattingListResponseDto of(ChatRoom chatRoom, LatestMessageDto latestMessageDto) { + public static ChattingListResponseDto of(Long roomId, User sender, User opponent, LatestMessageDto latestMessageDto) { return new ChattingListResponseDto( - chatRoom.getId(), - chatRoom.getUser1().getId(), - chatRoom.getUser2().getId(), - chatRoom.getUser1().getCustomId(), - chatRoom.getUser2().getCustomId(), + roomId, + sender.getId(), sender.getName(), + opponent.getId(), opponent.getName(), opponent.getImage().getUrl(), latestMessageDto ); } diff --git a/src/main/java/com/leets/X/domain/chat/entity/ChatRoom.java b/src/main/java/com/leets/X/domain/chat/entity/ChatRoom.java index 50075d3..daaaa73 100644 --- a/src/main/java/com/leets/X/domain/chat/entity/ChatRoom.java +++ b/src/main/java/com/leets/X/domain/chat/entity/ChatRoom.java @@ -27,14 +27,11 @@ public class ChatRoom extends BaseTimeEntity { @JoinColumn(name = "user2_id") private User user2; - private String lastMessage; - public static ChatRoom of(User user1, User user2) { return ChatRoom.builder() .user1(user1) .user2(user2) - .lastMessage("") .build(); } } diff --git a/src/main/java/com/leets/X/domain/chat/exception/ChatRoomExistException.java b/src/main/java/com/leets/X/domain/chat/exception/ChatRoomExistException.java new file mode 100644 index 0000000..9d9f3b0 --- /dev/null +++ b/src/main/java/com/leets/X/domain/chat/exception/ChatRoomExistException.java @@ -0,0 +1,11 @@ +package com.leets.X.domain.chat.exception; + +import com.leets.X.global.common.exception.BaseException; + +import static com.leets.X.domain.chat.exception.ErrorMessage.CHATROOM_EXIST; + +public class ChatRoomExistException extends BaseException { + public ChatRoomExistException() { + super(CHATROOM_EXIST.getCode(),CHATROOM_EXIST.getMessage()); + } +} diff --git a/src/main/java/com/leets/X/domain/chat/exception/ErrorMessage.java b/src/main/java/com/leets/X/domain/chat/exception/ErrorMessage.java index c0c91a0..584829a 100644 --- a/src/main/java/com/leets/X/domain/chat/exception/ErrorMessage.java +++ b/src/main/java/com/leets/X/domain/chat/exception/ErrorMessage.java @@ -8,7 +8,8 @@ @AllArgsConstructor public enum ErrorMessage { - NOT_FOUND_CHATROOM(400, "해당 채팅방을 찾을 수 없습니다."); + CHATROOM_NOT_FOUND(400, "해당 채팅방을 찾을 수 없습니다."), + CHATROOM_EXIST(400, "해당 채팅방이 이미 존재합니다"); private final int code; private final String message; diff --git a/src/main/java/com/leets/X/domain/chat/exception/NotFoundChatRoomException.java b/src/main/java/com/leets/X/domain/chat/exception/NotFoundChatRoomException.java index 0186cb4..634cef2 100644 --- a/src/main/java/com/leets/X/domain/chat/exception/NotFoundChatRoomException.java +++ b/src/main/java/com/leets/X/domain/chat/exception/NotFoundChatRoomException.java @@ -1,10 +1,10 @@ package com.leets.X.domain.chat.exception; import com.leets.X.global.common.exception.BaseException; -import static com.leets.X.domain.chat.exception.ErrorMessage.NOT_FOUND_CHATROOM; +import static com.leets.X.domain.chat.exception.ErrorMessage.CHATROOM_NOT_FOUND; public class NotFoundChatRoomException extends BaseException { public NotFoundChatRoomException() { - super(NOT_FOUND_CHATROOM.getCode(), NOT_FOUND_CHATROOM.getMessage()); + super(CHATROOM_NOT_FOUND.getCode(), CHATROOM_NOT_FOUND.getMessage()); } } diff --git a/src/main/java/com/leets/X/domain/chat/service/ChatRoomService.java b/src/main/java/com/leets/X/domain/chat/service/ChatRoomService.java index 0bb610f..7ee0807 100644 --- a/src/main/java/com/leets/X/domain/chat/service/ChatRoomService.java +++ b/src/main/java/com/leets/X/domain/chat/service/ChatRoomService.java @@ -4,6 +4,7 @@ import com.leets.X.domain.chat.dto.request.FindChatRoomRequestDto; import com.leets.X.domain.chat.dto.response.*; import com.leets.X.domain.chat.entity.ChatRoom; +import com.leets.X.domain.chat.exception.ChatRoomExistException; import com.leets.X.domain.chat.exception.NotFoundChatRoomException; import com.leets.X.domain.chat.redis.RedisListener; import com.leets.X.domain.chat.repository.ChatRoomRepository; @@ -29,17 +30,15 @@ public ChatRoomResponseDto saveChatRoom(FindChatRoomRequestDto findChatRoomReque User user1 = userService.find(findChatRoomRequestDto.user1Id()); User user2 = userService.find(findChatRoomRequestDto.user2Id()); + checkChatRoom(user1.getId(), user2.getId()); ChatRoom savedRoom = chatRoomRepository.save(ChatRoom.of(user1, user2)); // 채팅방 RDB에 저장 + redisMessageListener.adaptMessageListener(savedRoom.getId()); // 리스너 등록 return new ChatRoomResponseDto(savedRoom.getId()); } - - public ChatRoomResponseDto findUser1User2ChatRoom(Long user1Id , Long user2Id) { - Long result = chatRoomRepository.findRoomIdByUserIds(user1Id , user2Id) - .orElseThrow(NotFoundChatRoomException::new); - return new ChatRoomResponseDto(result); + return new ChatRoomResponseDto(findUsersChatRoom(user1Id, user2Id)); } // 테스트를 위해서 만들어둠. 추후 삭제 @@ -47,4 +46,16 @@ public void addListener(Long roomId) { redisMessageListener.adaptMessageListener(roomId); // 리스너 등록 } + + + private void checkChatRoom(Long user1Id, Long user2Id) { + chatRoomRepository.findRoomIdByUserIds(user1Id, user2Id).ifPresent(c->{ + throw new ChatRoomExistException(); + }); + } + + private Long findUsersChatRoom(Long user1Id, Long user2Id) { + return chatRoomRepository.findRoomIdByUserIds(user1Id, user2Id) + .orElseThrow(NotFoundChatRoomException::new); + } } diff --git a/src/main/java/com/leets/X/domain/chat/service/ChattingService.java b/src/main/java/com/leets/X/domain/chat/service/ChattingService.java index e7af8fa..9d44848 100644 --- a/src/main/java/com/leets/X/domain/chat/service/ChattingService.java +++ b/src/main/java/com/leets/X/domain/chat/service/ChattingService.java @@ -12,6 +12,7 @@ import com.leets.X.domain.chat.repository.ChatMessageRepository; import com.leets.X.domain.chat.repository.ChatRoomRepository; import com.leets.X.domain.user.domain.User; +import com.leets.X.domain.user.service.UserService; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; @@ -26,19 +27,19 @@ public class ChattingService { private final ChatRoomRepository chatRoomRepository; private final ChatMessageRepository chatMessageRepository; private final RedisListener redisMessageListener; + private final UserService userService; - public ChattingDto getChatRoom(Long roomId, Integer page, Integer size) { + public ChattingDto getChatRoom(Long roomId, Integer page, Integer size, String email) { ChatRoom findRoom = validateChatRoom(roomId); - User user1 = findRoom.getUser1(); - User user2 = findRoom.getUser2(); redisMessageListener.adaptMessageListener(findRoom.getId()); // 채팅방 내역 조회시 리스너 등록 추가 (운영 시 삭제) List chatMessageList = generateChatRoomMessages(roomId, page, size); - return new ChattingDto(user1.getId(), user2.getId(), user1.getCustomId(), user2.getCustomId(), chatMessageList); - } + User sender = userService.find(email); + return findOpponent(sender, findRoom.getUser1(), findRoom.getUser2(), chatMessageList); + } - public List getChattingList(Long userId) { // 추후 JWT 파싱으로 받아내기. + public List getChattingList(Long userId, String email) { // 추후 JWT 파싱으로 받아내기. List chatRooms = validateChatRommList(userId); return chatRooms.stream() @@ -46,11 +47,16 @@ public List getChattingList(Long userId) { // 추후 JW ChatMessage latestMessage = chatMessageRepository.findTopByRoomIdOrderByCreatedAtDesc(chatRoom.getId()).orElse(null); LatestMessageDto latestMessageDto = (latestMessage != null) ? LatestMessageDto.of(latestMessage) : new LatestMessageDto("", null); - return ChattingListResponseDto.of(chatRoom, latestMessageDto); + User sender = userService.find(email); + return findOpponentToAllChat(chatRoom, sender,chatRoom.getUser1(), chatRoom.getUser2(), latestMessageDto); }) .collect(Collectors.toList()); } + /* + * 리팩토링 + * */ + private List generateChatRoomMessages(Long roomId, Integer page, Integer size) { return chatMessageRepository.findByRoomIdOrderByCreatedAtDesc( roomId, PageRequest.of(page- 1, size)) @@ -60,6 +66,21 @@ private List generateChatRoomMessages(Long roomId, Integ .collect(Collectors.toList()); } + private static ChattingDto findOpponent(User sender, User user1, User user2, List chatMessageList) { + if(sender.equals(user1)) { // user1 이 본인 + return ChattingDto.of(user1, user2, chatMessageList); + }else{ + return ChattingDto.of(user2, user1, chatMessageList); + } + } + + private static ChattingListResponseDto findOpponentToAllChat(ChatRoom chatRoom, User sender,User user1, User user2, LatestMessageDto latestMessageDto) { + if(sender.equals(user1)) { // user1 이 본인 + return ChattingListResponseDto.of(chatRoom.getId(), user1, user2, latestMessageDto); + }else{ + return ChattingListResponseDto.of(chatRoom.getId(), user2, user1, latestMessageDto); + } + } private ChatRoom validateChatRoom(Long roomId) { return chatRoomRepository.findById(roomId)