From 24a27c34f7f15518f114c8ed69d01f644844b3a3 Mon Sep 17 00:00:00 2001 From: jinny-l Date: Tue, 26 Sep 2023 23:49:20 +0900 Subject: [PATCH 1/8] =?UTF-8?q?chore:=20build.gradle=EC=97=90=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- be/build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/be/build.gradle b/be/build.gradle index e3fe6fccd..eea7e7d63 100644 --- a/be/build.gradle +++ b/be/build.gradle @@ -56,6 +56,8 @@ dependencies { testImplementation "org.testcontainers:mysql:1.19.0" testImplementation 'io.rest-assured:rest-assured' + // chat + implementation 'org.springframework.boot:spring-boot-starter-websocket' } From b8c6f8009075239ebcf6f1e8ec3903a681a66601 Mon Sep 17 00:00:00 2001 From: jinny-l Date: Tue, 26 Sep 2023 23:49:48 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=EC=9B=B9=EC=86=8C=EC=BC=93=20Confi?= =?UTF-8?q?g=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/chat/config/WebSocketConfig.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 be/src/main/java/kr/codesquad/secondhand/api/chat/config/WebSocketConfig.java diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/config/WebSocketConfig.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/config/WebSocketConfig.java new file mode 100644 index 000000000..2d3ea71d4 --- /dev/null +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/config/WebSocketConfig.java @@ -0,0 +1,25 @@ +package kr.codesquad.secondhand.api.chat.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +@Configuration +@EnableWebSocketMessageBroker +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/ws") + .setAllowedOriginPatterns("*") + .withSockJS(); // APIC으로 STOMP 테스트 시 해당 옵션 주석 처리 필요 + } + + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.setApplicationDestinationPrefixes("/pub"); + registry.enableSimpleBroker("/sub"); + } +} From 3236791911f8f97387055e79ca765f8d5717f39c Mon Sep 17 00:00:00 2001 From: jinny-l Date: Wed, 27 Sep 2023 14:53:22 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=9A=94=EC=B2=AD=20API=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/controller/ChatRoomController.java | 31 ++++++++++++++ .../secondhand/api/chat/domain/ChatRoom.java | 41 +++++++++++++++++++ .../api/chat/dto/ChatRoomCreateDto.java | 39 ++++++++++++++++++ .../repository/ChatRoomRepositoryImpl.java | 7 ++++ .../api/chat/service/ChatFacadeService.java | 29 +++++++++++++ .../api/chat/service/ChatService.java | 22 ++++++++++ 6 files changed, 169 insertions(+) create mode 100644 be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java create mode 100644 be/src/main/java/kr/codesquad/secondhand/api/chat/domain/ChatRoom.java create mode 100644 be/src/main/java/kr/codesquad/secondhand/api/chat/dto/ChatRoomCreateDto.java create mode 100644 be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java create mode 100644 be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java create mode 100644 be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java new file mode 100644 index 000000000..4dc523dca --- /dev/null +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java @@ -0,0 +1,31 @@ +package kr.codesquad.secondhand.api.chat.controller; + +import static kr.codesquad.secondhand.global.util.HttpAuthorizationUtils.extractMemberId; + +import javax.servlet.http.HttpServletRequest; +import kr.codesquad.secondhand.api.chat.dto.ChatRoomCreateDto; +import kr.codesquad.secondhand.api.chat.service.ChatFacadeService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class ChatRoomController { + + private final ChatFacadeService chatService; + + @PostMapping("/api/chat/room") + public ResponseEntity createChatRoom(HttpServletRequest httpServletRequest, + @Validated @RequestBody ChatRoomCreateDto.Request request) { + Long memberId = extractMemberId(httpServletRequest); + ChatRoomCreateDto.Response response = chatService.createChatRoom(memberId, request.getProductId()); + return ResponseEntity + .status(HttpStatus.CREATED) + .body(response); + } +} diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/domain/ChatRoom.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/domain/ChatRoom.java new file mode 100644 index 000000000..f0c2a4b7b --- /dev/null +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/domain/ChatRoom.java @@ -0,0 +1,41 @@ +package kr.codesquad.secondhand.api.chat.domain; + +import java.util.UUID; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import kr.codesquad.secondhand.api.member.domain.Member; +import kr.codesquad.secondhand.api.product.domain.Product; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ChatRoom { + + @Id + private String id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "product_id") + private Product product; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + private ChatRoom(String id, Product product, Member member) { + this.id = id; + this.product = product; + this.member = member; + } + + public static ChatRoom create(Product product, Member member) { + String id = UUID.randomUUID().toString(); + return new ChatRoom(id, product, member); + } +} diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/ChatRoomCreateDto.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/ChatRoomCreateDto.java new file mode 100644 index 000000000..db0d850b9 --- /dev/null +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/ChatRoomCreateDto.java @@ -0,0 +1,39 @@ +package kr.codesquad.secondhand.api.chat.dto; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import lombok.Getter; + +public class ChatRoomCreateDto { + + @Getter + public static class Request { + + @NotNull(message = "생성할 채팅방의 상품 정보가 비어있습니다.") + private Long productId; + + @Valid + private MessageDTO message; + } + + @Getter + private static class MessageDTO { + + @NotNull(message = "생성할 채팅방의 senderId가 비어있습니다.") + private Long senderId; + + @NotBlank(message = "생성할 채팅방의 메시지 내용이 없습니다.") + private String content; + } + + @Getter + public static class Response { + + private final String roomId; + + public Response(String roomId) { + this.roomId = roomId; + } + } +} diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java new file mode 100644 index 000000000..ec4cd4502 --- /dev/null +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java @@ -0,0 +1,7 @@ +package kr.codesquad.secondhand.api.chat.repository; + +import kr.codesquad.secondhand.api.chat.domain.ChatRoom; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ChatRoomRepositoryImpl extends JpaRepository { +} diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java new file mode 100644 index 000000000..8316275da --- /dev/null +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java @@ -0,0 +1,29 @@ +package kr.codesquad.secondhand.api.chat.service; + +import kr.codesquad.secondhand.api.chat.domain.ChatRoom; +import kr.codesquad.secondhand.api.chat.dto.ChatRoomCreateDto; +import kr.codesquad.secondhand.api.member.domain.Member; +import kr.codesquad.secondhand.api.member.service.MemberService; +import kr.codesquad.secondhand.api.product.domain.Product; +import kr.codesquad.secondhand.api.product.service.ProductService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class ChatFacadeService { + + private final ChatService chatService; + private final ProductService productService; + private final MemberService memberService; + + public ChatRoomCreateDto.Response createChatRoom(Long memberId, Long productId) { + Member member = memberService.getMemberReferenceById(memberId); // 없는 경우에 무슨 예외 터지는지 확인 + Product product = productService.findById(productId); + ChatRoom chatRoom = chatService.createChatRoom(product, member); + + // TODO request의 첫 메시지 관련 처리 필요 + return new ChatRoomCreateDto.Response(chatRoom.getId()); + } + +} diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java new file mode 100644 index 000000000..c4c6d623a --- /dev/null +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java @@ -0,0 +1,22 @@ +package kr.codesquad.secondhand.api.chat.service; + +import kr.codesquad.secondhand.api.chat.domain.ChatRoom; +import kr.codesquad.secondhand.api.chat.repository.ChatRoomRepositoryImpl; +import kr.codesquad.secondhand.api.member.domain.Member; +import kr.codesquad.secondhand.api.product.domain.Product; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class ChatService { + + private final ChatRoomRepositoryImpl chatRoomRepository; + + public ChatRoom createChatRoom(Product product, Member member) { + ChatRoom chatRoom = ChatRoom.create(product, member); + chatRoomRepository.save(chatRoom); + return chatRoom; + } + +} From 7ea5a6872c46e1860aa6a31e017613e2a71a42cd Mon Sep 17 00:00:00 2001 From: jinny-l Date: Wed, 27 Sep 2023 15:32:32 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=A1=B4=EC=9E=AC=20=EC=97=AC=EB=B6=80=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20API=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/chat/controller/ChatRoomController.java | 13 +++++++++++++ .../dto/reponse/ChatRoomExistenceCheckResponse.java | 13 +++++++++++++ .../api/chat/repository/ChatRoomRepositoryImpl.java | 4 ++++ .../api/chat/service/ChatFacadeService.java | 8 +++++++- .../secondhand/api/chat/service/ChatService.java | 5 +++++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 be/src/main/java/kr/codesquad/secondhand/api/chat/dto/reponse/ChatRoomExistenceCheckResponse.java diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java index 4dc523dca..2e3185c6c 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java @@ -4,11 +4,14 @@ import javax.servlet.http.HttpServletRequest; import kr.codesquad.secondhand.api.chat.dto.ChatRoomCreateDto; +import kr.codesquad.secondhand.api.chat.dto.reponse.ChatRoomExistenceCheckResponse; import kr.codesquad.secondhand.api.chat.service.ChatFacadeService; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @@ -28,4 +31,14 @@ public ResponseEntity createChatRoom(HttpServletRequ .status(HttpStatus.CREATED) .body(response); } + + @GetMapping("/api/chat-room/{productId}") + public ResponseEntity checkChatRoomExistence(HttpServletRequest httpServletRequest, + @PathVariable Long productId) { + Long memberId = extractMemberId(httpServletRequest); + ChatRoomExistenceCheckResponse response = chatService.checkChatRoomExistence(memberId, productId); + return ResponseEntity + .status(HttpStatus.CREATED) + .body(response); + } } diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/reponse/ChatRoomExistenceCheckResponse.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/reponse/ChatRoomExistenceCheckResponse.java new file mode 100644 index 000000000..e4310184a --- /dev/null +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/reponse/ChatRoomExistenceCheckResponse.java @@ -0,0 +1,13 @@ +package kr.codesquad.secondhand.api.chat.dto.reponse; + +import lombok.Getter; + +@Getter +public class ChatRoomExistenceCheckResponse { + + private final String roomId; + + public ChatRoomExistenceCheckResponse(String roomId) { + this.roomId = roomId; + } +} diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java index ec4cd4502..06c506581 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java @@ -1,7 +1,11 @@ package kr.codesquad.secondhand.api.chat.repository; +import java.util.Optional; import kr.codesquad.secondhand.api.chat.domain.ChatRoom; import org.springframework.data.jpa.repository.JpaRepository; public interface ChatRoomRepositoryImpl extends JpaRepository { + + Optional findByMemberIdAndProductId(Long member_id, Long product_id); + } diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java index 8316275da..6670ac6cf 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java @@ -2,6 +2,7 @@ import kr.codesquad.secondhand.api.chat.domain.ChatRoom; import kr.codesquad.secondhand.api.chat.dto.ChatRoomCreateDto; +import kr.codesquad.secondhand.api.chat.dto.reponse.ChatRoomExistenceCheckResponse; import kr.codesquad.secondhand.api.member.domain.Member; import kr.codesquad.secondhand.api.member.service.MemberService; import kr.codesquad.secondhand.api.product.domain.Product; @@ -18,7 +19,7 @@ public class ChatFacadeService { private final MemberService memberService; public ChatRoomCreateDto.Response createChatRoom(Long memberId, Long productId) { - Member member = memberService.getMemberReferenceById(memberId); // 없는 경우에 무슨 예외 터지는지 확인 + Member member = memberService.getMemberReferenceById(memberId); Product product = productService.findById(productId); ChatRoom chatRoom = chatService.createChatRoom(product, member); @@ -26,4 +27,9 @@ public ChatRoomCreateDto.Response createChatRoom(Long memberId, Long productId) return new ChatRoomCreateDto.Response(chatRoom.getId()); } + public ChatRoomExistenceCheckResponse checkChatRoomExistence(Long memberId, Long productId) { + return chatService.findChatRoomByMemberIdAndProductId(memberId, productId) + .map(chatRoom -> new ChatRoomExistenceCheckResponse(chatRoom.getId())) + .orElse(new ChatRoomExistenceCheckResponse(null)); + } } diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java index c4c6d623a..8b1f9fdc4 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java @@ -1,5 +1,6 @@ package kr.codesquad.secondhand.api.chat.service; +import java.util.Optional; import kr.codesquad.secondhand.api.chat.domain.ChatRoom; import kr.codesquad.secondhand.api.chat.repository.ChatRoomRepositoryImpl; import kr.codesquad.secondhand.api.member.domain.Member; @@ -14,9 +15,13 @@ public class ChatService { private final ChatRoomRepositoryImpl chatRoomRepository; public ChatRoom createChatRoom(Product product, Member member) { + // TODO 채팅방이 이미 존재할 경우, 예외 처리 필요 ChatRoom chatRoom = ChatRoom.create(product, member); chatRoomRepository.save(chatRoom); return chatRoom; } + public Optional findChatRoomByMemberIdAndProductId(Long memberId, Long productId) { + return chatRoomRepository.findByMemberIdAndProductId(memberId, productId); + } } From 064c281f1a66c2e4d4cb7c2118b15c03b690f224 Mon Sep 17 00:00:00 2001 From: jinny-l Date: Sun, 1 Oct 2023 17:24:31 +0900 Subject: [PATCH 5/8] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=8B=9C=20=EC=B2=AB=EB=B2=88=EC=A7=B8=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=82=B4=EC=9A=A9=EC=9D=84=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/controller/ChatRoomController.java | 2 +- .../api/chat/domain/ChatMessage.java | 42 +++++++++++++++++++ .../secondhand/api/chat/domain/ChatRoom.java | 31 +++++++++++--- .../api/chat/dto/ChatRoomCreateDto.java | 2 +- .../repository/ChatMessageRepositoryImpl.java | 7 ++++ .../repository/ChatRoomRepositoryImpl.java | 3 +- .../api/chat/service/ChatFacadeService.java | 13 +++--- .../api/chat/service/ChatService.java | 26 +++++++++++- 8 files changed, 109 insertions(+), 17 deletions(-) create mode 100644 be/src/main/java/kr/codesquad/secondhand/api/chat/domain/ChatMessage.java create mode 100644 be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatMessageRepositoryImpl.java diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java index 2e3185c6c..d0bf178ce 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java @@ -26,7 +26,7 @@ public class ChatRoomController { public ResponseEntity createChatRoom(HttpServletRequest httpServletRequest, @Validated @RequestBody ChatRoomCreateDto.Request request) { Long memberId = extractMemberId(httpServletRequest); - ChatRoomCreateDto.Response response = chatService.createChatRoom(memberId, request.getProductId()); + ChatRoomCreateDto.Response response = chatService.createChatRoom(memberId, request); return ResponseEntity .status(HttpStatus.CREATED) .body(response); diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/domain/ChatMessage.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/domain/ChatMessage.java new file mode 100644 index 000000000..8e7279d45 --- /dev/null +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/domain/ChatMessage.java @@ -0,0 +1,42 @@ +package kr.codesquad.secondhand.api.chat.domain; + +import java.time.Instant; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import kr.codesquad.secondhand.api.member.domain.Member; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.CreationTimestamp; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ChatMessage { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String roomId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "sender_id") + private Member sender; + + private String message; + + @CreationTimestamp + private Instant sentTime; + + public ChatMessage(String roomId, Member sender, String message) { + this.roomId = roomId; + this.sender = sender; + this.message = message; + } +} diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/domain/ChatRoom.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/domain/ChatRoom.java index f0c2a4b7b..c754c3dbe 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/domain/ChatRoom.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/domain/ChatRoom.java @@ -1,16 +1,21 @@ package kr.codesquad.secondhand.api.chat.domain; +import java.time.Instant; import java.util.UUID; import javax.persistence.Entity; import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.OneToOne; import kr.codesquad.secondhand.api.member.domain.Member; import kr.codesquad.secondhand.api.product.domain.Product; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import org.hibernate.annotations.CreationTimestamp; @Entity @Getter @@ -18,24 +23,38 @@ public class ChatRoom { @Id - private String id; + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String roomId; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "product_id") private Product product; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; + @JoinColumn(name = "buyer_id") + private Member buyer; + + @OneToOne + @JoinColumn(name = "last_message_id") + private ChatMessage lastMessage; + + @CreationTimestamp + private Instant createdTime; - private ChatRoom(String id, Product product, Member member) { - this.id = id; + private ChatRoom(String roomId, Product product, Member buyer) { + this.roomId = roomId; this.product = product; - this.member = member; + this.buyer = buyer; } public static ChatRoom create(Product product, Member member) { String id = UUID.randomUUID().toString(); return new ChatRoom(id, product, member); } + + public void updateLastMessage(ChatMessage chatMessage) { + this.lastMessage = chatMessage; + } } diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/ChatRoomCreateDto.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/ChatRoomCreateDto.java index db0d850b9..c4d1aa01c 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/ChatRoomCreateDto.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/ChatRoomCreateDto.java @@ -18,7 +18,7 @@ public static class Request { } @Getter - private static class MessageDTO { + public static class MessageDTO { @NotNull(message = "생성할 채팅방의 senderId가 비어있습니다.") private Long senderId; diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatMessageRepositoryImpl.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatMessageRepositoryImpl.java new file mode 100644 index 000000000..e34b0dcca --- /dev/null +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatMessageRepositoryImpl.java @@ -0,0 +1,7 @@ +package kr.codesquad.secondhand.api.chat.repository; + +import kr.codesquad.secondhand.api.chat.domain.ChatMessage; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ChatMessageRepositoryImpl extends JpaRepository { +} diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java index 06c506581..916150a63 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java @@ -6,6 +6,7 @@ public interface ChatRoomRepositoryImpl extends JpaRepository { - Optional findByMemberIdAndProductId(Long member_id, Long product_id); + Optional findByBuyerIdAndProductId(Long buyerId, Long productId); + ChatRoom findByRoomId(String roomId); } diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java index 6670ac6cf..211198cd6 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java @@ -9,6 +9,7 @@ import kr.codesquad.secondhand.api.product.service.ProductService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @@ -18,18 +19,18 @@ public class ChatFacadeService { private final ProductService productService; private final MemberService memberService; - public ChatRoomCreateDto.Response createChatRoom(Long memberId, Long productId) { + @Transactional + public ChatRoomCreateDto.Response createChatRoom(Long memberId, ChatRoomCreateDto.Request request) { Member member = memberService.getMemberReferenceById(memberId); - Product product = productService.findById(productId); - ChatRoom chatRoom = chatService.createChatRoom(product, member); + Product product = productService.findById(request.getProductId()); + ChatRoom chatRoom = chatService.createChatRoom(product, member, request.getMessage().getContent()); - // TODO request의 첫 메시지 관련 처리 필요 - return new ChatRoomCreateDto.Response(chatRoom.getId()); + return new ChatRoomCreateDto.Response(chatRoom.getRoomId()); } public ChatRoomExistenceCheckResponse checkChatRoomExistence(Long memberId, Long productId) { return chatService.findChatRoomByMemberIdAndProductId(memberId, productId) - .map(chatRoom -> new ChatRoomExistenceCheckResponse(chatRoom.getId())) + .map(chatRoom -> new ChatRoomExistenceCheckResponse(chatRoom.getRoomId())) .orElse(new ChatRoomExistenceCheckResponse(null)); } } diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java index 8b1f9fdc4..08a2ad5e3 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java @@ -1,7 +1,9 @@ package kr.codesquad.secondhand.api.chat.service; import java.util.Optional; +import kr.codesquad.secondhand.api.chat.domain.ChatMessage; import kr.codesquad.secondhand.api.chat.domain.ChatRoom; +import kr.codesquad.secondhand.api.chat.repository.ChatMessageRepositoryImpl; import kr.codesquad.secondhand.api.chat.repository.ChatRoomRepositoryImpl; import kr.codesquad.secondhand.api.member.domain.Member; import kr.codesquad.secondhand.api.product.domain.Product; @@ -13,15 +15,35 @@ public class ChatService { private final ChatRoomRepositoryImpl chatRoomRepository; + private final ChatMessageRepositoryImpl chatMessageRepository; - public ChatRoom createChatRoom(Product product, Member member) { + public ChatRoom createChatRoom(Product product, Member member, String message) { // TODO 채팅방이 이미 존재할 경우, 예외 처리 필요 + ChatRoom chatRoom = saveChatRoom(product, member); + ChatMessage chatMessage = saveChatMessage(message, member, chatRoom.getRoomId()); + updateLastMessage(chatRoom.getRoomId(), chatMessage); + + return chatRoom; + } + + private ChatRoom saveChatRoom(Product product, Member member) { ChatRoom chatRoom = ChatRoom.create(product, member); chatRoomRepository.save(chatRoom); return chatRoom; } + private ChatMessage saveChatMessage(String message, Member sender, String roomId) { + ChatMessage chatMessage = new ChatMessage(roomId, sender, message); + return chatMessageRepository.save(chatMessage); + } + + private void updateLastMessage(String roomId, ChatMessage chatMessage) { + // TODO save 후 바로 업데이트가 되지 않아서 save -> find -> update 하고 있는데 쿼리 개선 필요 + ChatRoom chatRoom = chatRoomRepository.findByRoomId(roomId); + chatRoom.updateLastMessage(chatMessage); + } + public Optional findChatRoomByMemberIdAndProductId(Long memberId, Long productId) { - return chatRoomRepository.findByMemberIdAndProductId(memberId, productId); + return chatRoomRepository.findByBuyerIdAndProductId(memberId, productId); } } From 937d668221757ce2df8213a876754ea0e76a4201 Mon Sep 17 00:00:00 2001 From: jinny-l Date: Sun, 1 Oct 2023 23:13:44 +0900 Subject: [PATCH 6/8] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20API=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * unreadMessageCount 계산하는 기능 제외 --- .../chat/controller/ChatRoomController.java | 13 ++- .../dto/reponse/ChatRoomReadResponse.java | 102 ++++++++++++++++++ .../repository/ChatRoomRepositoryImpl.java | 4 + .../api/chat/service/ChatFacadeService.java | 18 ++++ .../api/chat/service/ChatService.java | 23 ++++ .../api/product/domain/Product.java | 4 + 6 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 be/src/main/java/kr/codesquad/secondhand/api/chat/dto/reponse/ChatRoomReadResponse.java diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java index d0bf178ce..deef0e12e 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java @@ -2,9 +2,11 @@ import static kr.codesquad.secondhand.global.util.HttpAuthorizationUtils.extractMemberId; +import java.util.List; import javax.servlet.http.HttpServletRequest; import kr.codesquad.secondhand.api.chat.dto.ChatRoomCreateDto; import kr.codesquad.secondhand.api.chat.dto.reponse.ChatRoomExistenceCheckResponse; +import kr.codesquad.secondhand.api.chat.dto.reponse.ChatRoomReadResponse; import kr.codesquad.secondhand.api.chat.service.ChatFacadeService; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; @@ -37,8 +39,13 @@ public ResponseEntity checkChatRoomExistence(Htt @PathVariable Long productId) { Long memberId = extractMemberId(httpServletRequest); ChatRoomExistenceCheckResponse response = chatService.checkChatRoomExistence(memberId, productId); - return ResponseEntity - .status(HttpStatus.CREATED) - .body(response); + return ResponseEntity.ok(response); + } + + @GetMapping("/api/chat-room") + public ResponseEntity> readChatRooms(HttpServletRequest httpServletRequest) { + Long memberId = extractMemberId(httpServletRequest); + List response = chatService.findAllChatRoomsBy(memberId); + return ResponseEntity.ok(response); } } diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/reponse/ChatRoomReadResponse.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/reponse/ChatRoomReadResponse.java new file mode 100644 index 000000000..f506a11e9 --- /dev/null +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/reponse/ChatRoomReadResponse.java @@ -0,0 +1,102 @@ +package kr.codesquad.secondhand.api.chat.dto.reponse; + +import java.net.URL; +import java.time.Instant; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import kr.codesquad.secondhand.api.chat.domain.ChatRoom; +import kr.codesquad.secondhand.api.member.domain.Member; +import kr.codesquad.secondhand.api.member.dto.response.MemberProfileResponse; +import kr.codesquad.secondhand.api.product.domain.Product; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class ChatRoomReadResponse { + + private final ChatRoomDto chatRoom; + private final ProductDto product; + + private ChatRoomReadResponse(ChatRoom chatRoom, Member otherMember) { + this.chatRoom = ChatRoomDto.from(chatRoom, otherMember); + this.product = ProductDto.from(chatRoom.getProduct()); + } + + public static List from(List chatRooms, Map otherMembers) { + return chatRooms.stream() + .map(chatRoom -> { + Member otherMember = otherMembers.get(chatRoom.getRoomId()); + return new ChatRoomReadResponse(chatRoom, otherMember); + }) + .collect(Collectors.toList()); + } + + @Getter + private static class ChatRoomDto { + + private final MemberProfileResponse otherMember; + private final MessageDto message; + // TODO 안 읽은 메시지 개수 + + private ChatRoomDto(MemberProfileResponse otherMember, MessageDto message) { + this.otherMember = otherMember; + this.message = message; + } + + private static ChatRoomDto from(ChatRoom chatRoom, Member otherMember) { + return new ChatRoomDto( + MemberProfileResponse.from(otherMember), + MessageDto.from(chatRoom) + ); + } + } + + @Getter + private static class MessageDto { + + private final String lastMessage; + private final Instant lastSentTime; + + private MessageDto(String lastMessage, Instant lastSentTime) { + this.lastMessage = lastMessage; + this.lastSentTime = lastSentTime; + } + + private static MessageDto from(ChatRoom chatRoom) { + return new MessageDto( + chatRoom.getLastMessage().getMessage(), + chatRoom.getLastMessage().getSentTime() + ); + } + } + + @Getter + private static class ProductDto { + + private final Long productId; + private final String title; + private final URL thumbnailUrl; + private final Long price; + private final Integer status; + + @Builder + private ProductDto(Long productId, String title, URL thumbnailUrl, Long price, Integer status) { + this.productId = productId; + this.title = title; + this.thumbnailUrl = thumbnailUrl; + this.price = price; + this.status = status; + } + + private static ProductDto from(Product product) { + return ProductDto.builder() + .productId(product.getId()) + .title(product.getTitle()) + .thumbnailUrl(product.getThumbnailImgUrl()) + .price(product.getPrice()) + .status(product.getStatusId()) + .build(); + } + } +} diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java index 916150a63..8695fc028 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatRoomRepositoryImpl.java @@ -1,7 +1,9 @@ package kr.codesquad.secondhand.api.chat.repository; +import java.util.List; import java.util.Optional; import kr.codesquad.secondhand.api.chat.domain.ChatRoom; +import kr.codesquad.secondhand.api.member.domain.Member; import org.springframework.data.jpa.repository.JpaRepository; public interface ChatRoomRepositoryImpl extends JpaRepository { @@ -9,4 +11,6 @@ public interface ChatRoomRepositoryImpl extends JpaRepository Optional findByBuyerIdAndProductId(Long buyerId, Long productId); ChatRoom findByRoomId(String roomId); + + Optional> findByProductSellerOrBuyer(Member seller, Member buyer); } diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java index 211198cd6..10b09f416 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java @@ -1,8 +1,13 @@ package kr.codesquad.secondhand.api.chat.service; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; import kr.codesquad.secondhand.api.chat.domain.ChatRoom; import kr.codesquad.secondhand.api.chat.dto.ChatRoomCreateDto; import kr.codesquad.secondhand.api.chat.dto.reponse.ChatRoomExistenceCheckResponse; +import kr.codesquad.secondhand.api.chat.dto.reponse.ChatRoomReadResponse; import kr.codesquad.secondhand.api.member.domain.Member; import kr.codesquad.secondhand.api.member.service.MemberService; import kr.codesquad.secondhand.api.product.domain.Product; @@ -33,4 +38,17 @@ public ChatRoomExistenceCheckResponse checkChatRoomExistence(Long memberId, Long .map(chatRoom -> new ChatRoomExistenceCheckResponse(chatRoom.getRoomId())) .orElse(new ChatRoomExistenceCheckResponse(null)); } + + @Transactional + public List findAllChatRoomsBy(Long memberId) { + Member loginMember = memberService.getMemberReferenceById(memberId); + Optional> chatRooms = chatService.findAllChatRoomsBy(loginMember); + + if (chatRooms.isEmpty()) { + return Collections.emptyList(); + } + + Map otherMembers = chatService.findOtherMembers(chatRooms.get(), loginMember); + return ChatRoomReadResponse.from(chatRooms.get(), otherMembers); + } } diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java index 08a2ad5e3..70d0e19d0 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java @@ -1,6 +1,9 @@ package kr.codesquad.secondhand.api.chat.service; +import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import kr.codesquad.secondhand.api.chat.domain.ChatMessage; import kr.codesquad.secondhand.api.chat.domain.ChatRoom; import kr.codesquad.secondhand.api.chat.repository.ChatMessageRepositoryImpl; @@ -46,4 +49,24 @@ private void updateLastMessage(String roomId, ChatMessage chatMessage) { public Optional findChatRoomByMemberIdAndProductId(Long memberId, Long productId) { return chatRoomRepository.findByBuyerIdAndProductId(memberId, productId); } + + public Optional> findAllChatRoomsBy(Member member) { + return chatRoomRepository.findByProductSellerOrBuyer(member, member); + } + + /** + * @return RoomId에 매핑된 otherMember + */ + public Map findOtherMembers(List chatRooms, Member loginMember) { + return chatRooms.stream() + .collect(Collectors.toUnmodifiableMap( + ChatRoom::getRoomId, + chatRoom -> { + if (chatRoom.getProduct().isSeller(loginMember)) { + return chatRoom.getBuyer(); + } + return chatRoom.getProduct().getSeller(); + } + )); + } } diff --git a/be/src/main/java/kr/codesquad/secondhand/api/product/domain/Product.java b/be/src/main/java/kr/codesquad/secondhand/api/product/domain/Product.java index 8d30a80ac..56f64508e 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/product/domain/Product.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/product/domain/Product.java @@ -75,4 +75,8 @@ public void updateProduct(String title, String content, Long price, Address addr public void updateStatus(ProductStatus productStatus) { this.statusId = productStatus.getId(); } + + public boolean isSeller(Member member) { + return seller.getId().equals(member.getId()); + } } From 08afc97fcca42a9dce4532a5b5e41c765021921d Mon Sep 17 00:00:00 2001 From: jinny-l Date: Sun, 1 Oct 2023 23:52:35 +0900 Subject: [PATCH 7/8] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=A1=B0=ED=9A=8C=20API=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/controller/ChatRoomController.java | 8 +++++ .../reponse/ChatRoomMessagesReadResponse.java | 35 +++++++++++++++++++ .../repository/ChatMessageRepositoryImpl.java | 5 +++ .../api/chat/service/ChatFacadeService.java | 7 ++++ .../api/chat/service/ChatService.java | 4 +++ 5 files changed, 59 insertions(+) create mode 100644 be/src/main/java/kr/codesquad/secondhand/api/chat/dto/reponse/ChatRoomMessagesReadResponse.java diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java index deef0e12e..2dae5d404 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/controller/ChatRoomController.java @@ -6,6 +6,7 @@ import javax.servlet.http.HttpServletRequest; import kr.codesquad.secondhand.api.chat.dto.ChatRoomCreateDto; import kr.codesquad.secondhand.api.chat.dto.reponse.ChatRoomExistenceCheckResponse; +import kr.codesquad.secondhand.api.chat.dto.reponse.ChatRoomMessagesReadResponse; import kr.codesquad.secondhand.api.chat.dto.reponse.ChatRoomReadResponse; import kr.codesquad.secondhand.api.chat.service.ChatFacadeService; import lombok.RequiredArgsConstructor; @@ -16,6 +17,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @@ -48,4 +50,10 @@ public ResponseEntity> readChatRooms(HttpServletReque List response = chatService.findAllChatRoomsBy(memberId); return ResponseEntity.ok(response); } + + @GetMapping("/api/chat-room/messages") + public ResponseEntity> readChatRoomMessages(@RequestParam String roomId) { + List response = chatService.findChatRoomMessagesBy(roomId); + return ResponseEntity.ok(response); + } } diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/reponse/ChatRoomMessagesReadResponse.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/reponse/ChatRoomMessagesReadResponse.java new file mode 100644 index 000000000..7e6464c56 --- /dev/null +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/reponse/ChatRoomMessagesReadResponse.java @@ -0,0 +1,35 @@ +package kr.codesquad.secondhand.api.chat.dto.reponse; + +import java.time.Instant; +import java.util.List; +import java.util.stream.Collectors; +import kr.codesquad.secondhand.api.chat.domain.ChatMessage; +import lombok.Getter; + +@Getter +public class ChatRoomMessagesReadResponse { + + private final Long senderId; + private final String content; + private final Instant sentTime; + + private ChatRoomMessagesReadResponse(Long senderId, String content, Instant sentTime) { + this.senderId = senderId; + this.content = content; + this.sentTime = sentTime; + } + + private static ChatRoomMessagesReadResponse from(ChatMessage chatMessage) { + return new ChatRoomMessagesReadResponse( + chatMessage.getSender().getId(), + chatMessage.getMessage(), + chatMessage.getSentTime() + ); + } + + public static List from(List chatMessages) { + return chatMessages.stream() + .map(ChatRoomMessagesReadResponse::from) + .collect(Collectors.toUnmodifiableList()); + } +} diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatMessageRepositoryImpl.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatMessageRepositoryImpl.java index e34b0dcca..ed17eb06e 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatMessageRepositoryImpl.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/repository/ChatMessageRepositoryImpl.java @@ -1,7 +1,12 @@ package kr.codesquad.secondhand.api.chat.repository; +import java.util.List; import kr.codesquad.secondhand.api.chat.domain.ChatMessage; import org.springframework.data.jpa.repository.JpaRepository; public interface ChatMessageRepositoryImpl extends JpaRepository { + + // TODO 슬라이싱 하면 sentTime 기준 DESC로 정렬 필요 + List findAllByRoomId(String roomId); + } diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java index 10b09f416..752fba4c6 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java @@ -4,9 +4,11 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import kr.codesquad.secondhand.api.chat.domain.ChatMessage; import kr.codesquad.secondhand.api.chat.domain.ChatRoom; import kr.codesquad.secondhand.api.chat.dto.ChatRoomCreateDto; import kr.codesquad.secondhand.api.chat.dto.reponse.ChatRoomExistenceCheckResponse; +import kr.codesquad.secondhand.api.chat.dto.reponse.ChatRoomMessagesReadResponse; import kr.codesquad.secondhand.api.chat.dto.reponse.ChatRoomReadResponse; import kr.codesquad.secondhand.api.member.domain.Member; import kr.codesquad.secondhand.api.member.service.MemberService; @@ -51,4 +53,9 @@ public List findAllChatRoomsBy(Long memberId) { Map otherMembers = chatService.findOtherMembers(chatRooms.get(), loginMember); return ChatRoomReadResponse.from(chatRooms.get(), otherMembers); } + + public List findChatRoomMessagesBy(String roomId) { + List messages = chatService.findChatMessagesBy(roomId); + return ChatRoomMessagesReadResponse.from(messages); + } } diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java index 70d0e19d0..0e68ee847 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatService.java @@ -69,4 +69,8 @@ public Map findOtherMembers(List chatRooms, Member log } )); } + + public List findChatMessagesBy(String roomId) { + return chatMessageRepository.findAllByRoomId(roomId); + } } From 969e90564ebf7a19b2af9b62de6115ad287499c7 Mon Sep 17 00:00:00 2001 From: jinny-l Date: Wed, 4 Oct 2023 11:44:27 +0900 Subject: [PATCH 8/8] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=9A=94=EC=B2=AD=20API=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=ED=98=95=ED=83=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../secondhand/api/chat/dto/ChatRoomCreateDto.java | 13 +------------ .../api/chat/service/ChatFacadeService.java | 2 +- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/ChatRoomCreateDto.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/ChatRoomCreateDto.java index c4d1aa01c..090cf554d 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/ChatRoomCreateDto.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/dto/ChatRoomCreateDto.java @@ -1,6 +1,5 @@ package kr.codesquad.secondhand.api.chat.dto; -import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import lombok.Getter; @@ -13,18 +12,8 @@ public static class Request { @NotNull(message = "생성할 채팅방의 상품 정보가 비어있습니다.") private Long productId; - @Valid - private MessageDTO message; - } - - @Getter - public static class MessageDTO { - - @NotNull(message = "생성할 채팅방의 senderId가 비어있습니다.") - private Long senderId; - @NotBlank(message = "생성할 채팅방의 메시지 내용이 없습니다.") - private String content; + private String message; } @Getter diff --git a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java index 752fba4c6..cbcd9cc9c 100644 --- a/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java +++ b/be/src/main/java/kr/codesquad/secondhand/api/chat/service/ChatFacadeService.java @@ -30,7 +30,7 @@ public class ChatFacadeService { public ChatRoomCreateDto.Response createChatRoom(Long memberId, ChatRoomCreateDto.Request request) { Member member = memberService.getMemberReferenceById(memberId); Product product = productService.findById(request.getProductId()); - ChatRoom chatRoom = chatService.createChatRoom(product, member, request.getMessage().getContent()); + ChatRoom chatRoom = chatService.createChatRoom(product, member, request.getMessage()); return new ChatRoomCreateDto.Response(chatRoom.getRoomId()); }