Igloo-Club / Igloo-Club-BE

1 stars 1 forks source link

[feat] 채팅 기능 일부 미완부 구현 #29

Closed ryuseunghan closed 8 months ago

ryuseunghan commented 8 months ago

🔥 Related Issues

💜 작업 내용

✅ PR Point

  1. 일주일 뒤에 채팅방 삭제

    • 해당 기능을 위해 ChatRoom 엔티티에 expiredAt 필드 추가, create도 맞춰서 수정
      
      private LocalDateTime expiredAt;

    // == 생성 메서드 == // public static ChatRoom create(Member receiver, Member sender) { return ChatRoom.builder() .sender(sender) .receiver(receiver) .createdAt(LocalDateTime.now()) .expiredAt(LocalDateTime.now().plusDays(7)) .build(); }

    - cascadeType을 사용하는건 위험하지만 부모 자식간의 관계가 명확하고 참조무결성 조약을 위반할 일이 없다 판단하여 cascadeType.ALL 선언
    - cascadeType을 통해 불필요한 코드를 효과적으로 줄일 수 있음

    @Builder.Default @OneToMany(mappedBy = "chatRoom", cascade = CascadeType.ALL, orphanRemoval = true) List chatMessageList = new ArrayList();

    _before_

    public void deleteExpiredChatRoom() { LocalDateTime now = LocalDateTime.now(); List chatRoomList = chatRoomRepository.findByExpiredAtBefore(now); for (ChatRoom chatRoom : chatRoomList) { chatRoomRepository.delete(chatRoom); chatMessageList = chatMessageRepository.findByChatRoom(chatRoom); for(ChatMessage chatMessage : chatMessageList){ chatMessageRepository.delete(chatMessage); } }

    _after_

    public void deleteExpiredChatRoom() { LocalDateTime now = LocalDateTime.now(); List chatRoomList = chatRoomRepository.findByExpiredAtBefore(now); for (ChatRoom chatRoom : chatRoomList) { chatRoomRepository.delete(chatRoom); } }

  2. 특정 사용자에게 연결된 모든 채팅방 목록 조회

    • 사용자 스스로의 멤버객체를 이용해 조회
    • 사용자 멤버 객체가 속한 모든 chatRoom을 리스트로 받아온 이후 각 chatRoom의 상대방을 opponent로 지정
    • opponent 객체를 통해 1. 상대방 동물상, 2. 상대방 닉네임 매핑
    • chatRoom객체를 통해 3. 최근 채팅 메시지 (상대방/본인 상관 없음, null일 시 "지금 연락을 시작하세요!"), 4. 채팅방 ID 매핑
    • PageRequest의 sort 정렬조건을 Sort.Direction.DESC, "createdAt"로 설정해 가장 최근 메시지 생성순으로 정렬, 이때 메시지가 없을 시 채팅룸 생성 일시를 createAt 값으로 사용

      
      public Slice<ChatRoomListResponse> getChatRoomSlice(Member member,PageRequest pageRequest){
      Slice<ChatRoom> chatRoomSlice = chatRoomRepository.findBySenderOrReceiver(member, member, pageRequest);
      
      return chatRoomSlice.map(chatRoom -> {
          Member opponent = chatRoom.getSender().equals(member) ? chatRoom.getReceiver() : chatRoom.getSender();
          ChatMessage lastMessage = chatRoom.getChatMessageList().isEmpty() ? null : chatRoom.getChatMessageList().get(chatRoom.getChatMessageList().size() - 1);
          String content = lastMessage != null ? lastMessage.getContent() : "지금 연락을 시작하세요!";
          LocalDateTime createdAt = lastMessage != null ? lastMessage.getCreatedAt() : chatRoom.getCreatedAt();
          return new ChatRoomListResponse(
                  opponent.getAnimalFace(), // 상대방의 AnimalFace
                  opponent.getNickname(), // 상대방 닉네임
                  content, // 마지막 메시지 내용
                  createdAt, // 마지막 메시지 생성 시간
                  chatRoom.getId() // 채팅방 ID
          );
      });
      }

## 😡 Trouble Shooting

## ☀ 스크린샷 / GIF / 화면 녹화
![image](https://github.com/Igloo-Club/Igloo-Club-BE/assets/106146847/32369151-f0fb-4266-8a04-34dacc64afa7)

## 📚 Reference

- [(https://tecoble.techcourse.co.kr/post/2023-08-14-JPA-Cascade/)