From 2d3ac519fd711f5114752621c2c21c6c5aaa6688 Mon Sep 17 00:00:00 2001 From: Curry4182 Date: Mon, 18 Mar 2024 17:20:30 +0900 Subject: [PATCH 1/5] =?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,=20=EC=B1=84=ED=8C=85?= =?UTF-8?q?=EB=B0=A9=20=EC=B0=B8=EC=97=AC,=20=EC=B1=84=ED=8C=85=EB=B0=A9?= =?UTF-8?q?=20=EC=9D=B8=EC=9B=90=EC=88=98=20=EC=A1=B0=ED=9A=8C,=20?= =?UTF-8?q?=EC=B1=84=ED=8C=85=EB=B0=A9=20=EB=82=98=EA=B0=80=EA=B8=B0=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 --- .../chatroom/api/ChatRoomController.java | 63 +++++++++++++ .../dto/response/ChatRoomGetListResponse.java | 16 ++++ .../chatroom/application/ChatRoomService.java | 92 +++++++++++++++++++ .../ChatRoomGetServiceListResponse.java | 10 ++ .../com/programmers/lime/error/ErrorCode.java | 13 ++- .../domains/chatroom/domain/ChatRoom.java | 70 ++++++++++++++ .../chatroom/domain/ChatRoomMember.java | 36 ++++++++ .../ChatRoomMemberAppender.java | 23 +++++ .../implementation/ChatRoomMemberReader.java | 28 ++++++ .../implementation/ChatRoomMemberRemover.java | 23 +++++ .../implementation/ChatRoomReader.java | 25 +++++ .../domains/chatroom/model/ChatRoomInfo.java | 12 +++ .../chatroom/model/ChatRoomStatus.java | 16 ++++ .../domains/chatroom/model/ChatRoomType.java | 16 ++++ .../repository/ChatRoomMemberRepository.java | 20 ++++ .../chatroom/repository/ChatRoomQueryDsl.java | 12 +++ .../repository/ChatRoomQueryDslImpl.java | 71 ++++++++++++++ .../repository/ChatRoomRepository.java | 12 +++ 18 files changed, 557 insertions(+), 1 deletion(-) create mode 100644 lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/ChatRoomController.java create mode 100644 lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/dto/response/ChatRoomGetListResponse.java create mode 100644 lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java create mode 100644 lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/dto/response/ChatRoomGetServiceListResponse.java create mode 100644 lime-domain/src/main/java/com/programmers/lime/domains/chatroom/domain/ChatRoom.java create mode 100644 lime-domain/src/main/java/com/programmers/lime/domains/chatroom/domain/ChatRoomMember.java create mode 100644 lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomMemberAppender.java create mode 100644 lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomMemberReader.java create mode 100644 lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomMemberRemover.java create mode 100644 lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomReader.java create mode 100644 lime-domain/src/main/java/com/programmers/lime/domains/chatroom/model/ChatRoomInfo.java create mode 100644 lime-domain/src/main/java/com/programmers/lime/domains/chatroom/model/ChatRoomStatus.java create mode 100644 lime-domain/src/main/java/com/programmers/lime/domains/chatroom/model/ChatRoomType.java create mode 100644 lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomMemberRepository.java create mode 100644 lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomQueryDsl.java create mode 100644 lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomQueryDslImpl.java create mode 100644 lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomRepository.java diff --git a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/ChatRoomController.java b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/ChatRoomController.java new file mode 100644 index 000000000..00ed62b08 --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/ChatRoomController.java @@ -0,0 +1,63 @@ +package com.programmers.lime.domains.chatroom.api; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +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.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.programmers.lime.domains.chatroom.api.dto.response.ChatRoomGetListResponse; +import com.programmers.lime.domains.chatroom.application.ChatRoomService; +import com.programmers.lime.domains.chatroom.application.dto.response.ChatRoomGetServiceListResponse; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; + +@Tag(name = "chat-room", description = "채팅방 API") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/chatrooms") +public class ChatRoomController { + + private final ChatRoomService chatRoomService; + + //private final ChatService chatService; + + @Operation(summary = "채티방 전체 조회", description = "채팅방을 조회합니다.") + @GetMapping + public ResponseEntity getChatRooms() { + ChatRoomGetServiceListResponse serviceResponse = chatRoomService.getAvailableChatRooms(); + ChatRoomGetListResponse response = ChatRoomGetListResponse.from(serviceResponse); + + return ResponseEntity.ok( + response + ); + } + + @Operation(summary = "채팅방 참여", description = "채팅방에 참여합니다.") + @PostMapping("/{chatRoomId}/join") + public ResponseEntity joinChatRoom(@PathVariable final Long chatRoomId) { + chatRoomService.joinChatRoom(chatRoomId); + //chatService.joinChatRoom(chatRoomId); + return ResponseEntity.ok().build(); + } + + @Operation(summary = "채팅방 인원수 조회", description = "채팅방의 인원수를 조회합니다.") + @GetMapping("/{chatRoomId}/members/count") + public ResponseEntity countChatRoomMembers(@PathVariable final Long chatRoomId) { + return ResponseEntity.ok( + chatRoomService.countChatRoomMembersByChatRoomId(chatRoomId) + ); + } + + @Operation(summary = "채팅방 나가기", description = "채팅방에서 나갑니다.") + @DeleteMapping("/{chatRoomId}/exit") + public ResponseEntity exitChatRoom(@PathVariable final Long chatRoomId) { + chatRoomService.exitChatRoom(chatRoomId); + //chatService.sendExitMessageToChatRoom(chatRoomId); + return ResponseEntity.ok().build(); + } +} diff --git a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/dto/response/ChatRoomGetListResponse.java b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/dto/response/ChatRoomGetListResponse.java new file mode 100644 index 000000000..98144c7f6 --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/dto/response/ChatRoomGetListResponse.java @@ -0,0 +1,16 @@ +package com.programmers.lime.domains.chatroom.api.dto.response; + +import java.util.List; + +import com.programmers.lime.domains.chatroom.application.dto.response.ChatRoomGetServiceListResponse; +import com.programmers.lime.domains.chatroom.model.ChatRoomInfo; + +public record ChatRoomGetListResponse( + List chatRoomInfos +) { + public static ChatRoomGetListResponse from(ChatRoomGetServiceListResponse chatRoomGetServiceListResponse) { + return new ChatRoomGetListResponse( + chatRoomGetServiceListResponse.chatRoomInfos() + ); + } +} diff --git a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java new file mode 100644 index 000000000..cbd438b0c --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java @@ -0,0 +1,92 @@ +package com.programmers.lime.domains.chatroom.application; + +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import org.springframework.stereotype.Service; + +import com.programmers.lime.domains.chatroom.application.dto.response.ChatRoomGetServiceListResponse; +import com.programmers.lime.domains.chatroom.implementation.ChatRoomMemberAppender; +import com.programmers.lime.domains.chatroom.implementation.ChatRoomMemberReader; +import com.programmers.lime.domains.chatroom.implementation.ChatRoomMemberRemover; +import com.programmers.lime.domains.chatroom.implementation.ChatRoomReader; +import com.programmers.lime.domains.chatroom.model.ChatRoomInfo; +import com.programmers.lime.error.BusinessException; +import com.programmers.lime.error.ErrorCode; +import com.programmers.lime.global.config.chat.WebSocketSessionManager; +import com.programmers.lime.global.config.security.SecurityUtils; +import com.programmers.lime.redis.chat.ChatSessionRedisManager; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class ChatRoomService { + + private final ChatRoomMemberReader chatRoomMemberReader; + + private final ChatRoomMemberAppender chatRoomMemberAppender; + + private final ChatRoomMemberRemover chatRoomMemberRemover; + + private final ChatRoomReader chatRoomReader; + + private final WebSocketSessionManager webSocketSessionManager; + + private final ChatSessionRedisManager chatSessionRedisManager; + + public ChatRoomGetServiceListResponse getAvailableChatRooms() { + Long memberId = SecurityUtils.getCurrentMemberId(); + + List chatRoomInfos = null; + + if(Objects.isNull(memberId)) { + chatRoomInfos = chatRoomReader.readOpenChatRooms(); + } else { + chatRoomInfos = chatRoomReader.readOpenChatRoomsByMemberId(memberId); + } + + return new ChatRoomGetServiceListResponse( + chatRoomInfos + ); + } + + public void joinChatRoom(Long chatRoomId) { + + Long memberId = SecurityUtils.getCurrentMemberId(); + + if(Objects.isNull(memberId)) { + throw new BusinessException(ErrorCode.MEMBER_ANONYMOUS); + } + + if(chatRoomMemberReader.existMemberByMemberIdAndRoomId(chatRoomId, memberId)) { + throw new BusinessException(ErrorCode.CHATROOM_ALREADY_JOIN); + } + + chatRoomMemberAppender.appendChatRoomMember(chatRoomId, memberId); + } + + public int countChatRoomMembersByChatRoomId(Long chatRoomId) { + return chatRoomMemberReader.countChatRoomMembersByChatRoomId(chatRoomId); + } + + public void exitChatRoom(Long chatRoomId) { + Long memberId = SecurityUtils.getCurrentMemberId(); + + Set sessionIdsByMemberAndRoom = chatSessionRedisManager.getSessionIdsByMemberAndRoom( + memberId, + chatRoomId + ); + + for(String memberSessionId : sessionIdsByMemberAndRoom) { + try { + webSocketSessionManager.closeSession(memberSessionId); + } catch (Exception e) { + throw new BusinessException(ErrorCode.CHAT_SESSION_NOT_FOUND); + } + } + + chatRoomMemberRemover.removeChatRoomMember(chatRoomId, memberId); + } +} diff --git a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/dto/response/ChatRoomGetServiceListResponse.java b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/dto/response/ChatRoomGetServiceListResponse.java new file mode 100644 index 000000000..7115a9578 --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/dto/response/ChatRoomGetServiceListResponse.java @@ -0,0 +1,10 @@ +package com.programmers.lime.domains.chatroom.application.dto.response; + +import java.util.List; + +import com.programmers.lime.domains.chatroom.model.ChatRoomInfo; + +public record ChatRoomGetServiceListResponse( + List chatRoomInfos +) { +} diff --git a/lime-common/src/main/java/com/programmers/lime/error/ErrorCode.java b/lime-common/src/main/java/com/programmers/lime/error/ErrorCode.java index be4af9ca9..52175e1e4 100644 --- a/lime-common/src/main/java/com/programmers/lime/error/ErrorCode.java +++ b/lime-common/src/main/java/com/programmers/lime/error/ErrorCode.java @@ -30,6 +30,9 @@ public enum ErrorCode { S3_UPLOAD_FAIL("COMMON_014", "S3 업로드에 실패했습니다."), S3_DELETE_FAIL("COMMON_015", "S3 삭제에 실패했습니다."), BAD_REVIEW_IMAGE_URL("COMMON_016", "잘못된 리뷰 이미지 URL 입니다."), + INVALID_SUBSCRIPTION_DESTINATION("COMMON_017", "유효하지 않은 구독 대상입니다."), + MESSAGE_DOMAIN_TYPE_NOT_FOUND("COMMON_018", "메시지 도메인 타입을 찾을 수 없습니다."), + SUBSCRIPTION_DESTINATION_NOT_FOUND("COMMON_019", "구독 대상을 찾을 수 없습니다."), // Member @@ -134,7 +137,15 @@ public enum ErrorCode { // Favorite FAVORITE_TYPE_BAD_REQUEST("FAVORITE_001", "잘못된 favoriteType 파라미터 값입니다."), - ; + + // ChatRoom + CHATROOM_MAX_MEMBER_COUNT_ERROR("CHATROOM_001","최소 2명 이상의 사용자가 필요합니다." ), + CHATROOM_ALREADY_JOIN("CHATROOM_002","이미 참여한 채팅방 입니다." ), + CHATROOM_NOT_PERMISSION("CHATROOM_003","채팅방에 참여할 권한이 없습니다." ), + + // Chat + CHAT_NOT_PERMISSION("CHAT_001","채팅 권한이 없습니다." ), + CHAT_SESSION_NOT_FOUND("CHAT_002","채팅 세션을 찾을 수 없습니다." ); private static final Map ERROR_CODE_MAP; diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/domain/ChatRoom.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/domain/ChatRoom.java new file mode 100644 index 000000000..40593d689 --- /dev/null +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/domain/ChatRoom.java @@ -0,0 +1,70 @@ +package com.programmers.lime.domains.chatroom.domain; + +import java.util.Objects; + +import com.programmers.lime.domains.BaseEntity; +import com.programmers.lime.domains.chatroom.model.ChatRoomStatus; +import com.programmers.lime.domains.chatroom.model.ChatRoomType; +import com.programmers.lime.error.BusinessException; +import com.programmers.lime.error.ErrorCode; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Entity +@Table(name = "chat_rooms") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ChatRoom extends BaseEntity { + + private static final int MIN_ROOM_MAX_MEMBER_COUNT = 2; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "room_name", nullable = false) + private String roomName; + + @Enumerated(EnumType.STRING) + @Column(name = "room_type", nullable = false) + private ChatRoomType chatRoomType; + + @Enumerated(EnumType.STRING) + @Column(name = "room_status", nullable = false) + private ChatRoomStatus chatRoomStatus; + + @Column(name = "room_max_member_count", nullable = false) + private int roomMaxMemberCount; + + @Builder + public ChatRoom( + final String roomName, + final ChatRoomType chatRoomType, + final ChatRoomStatus chatRoomStatus, + final int roomMaxMemberCount + ) { + validRoomMaxMemberCount(roomMaxMemberCount); + this.roomName = Objects.requireNonNull(roomName); + this.chatRoomType = Objects.requireNonNull(chatRoomType); + this.chatRoomStatus = Objects.requireNonNull(chatRoomStatus); + this.roomMaxMemberCount = roomMaxMemberCount; + } + + private void validRoomMaxMemberCount(int roomMaxMemberCount) { + if (roomMaxMemberCount < MIN_ROOM_MAX_MEMBER_COUNT) { + throw new BusinessException(ErrorCode.CHATROOM_MAX_MEMBER_COUNT_ERROR); + } + } +} diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/domain/ChatRoomMember.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/domain/ChatRoomMember.java new file mode 100644 index 000000000..b1bc75bbb --- /dev/null +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/domain/ChatRoomMember.java @@ -0,0 +1,36 @@ +package com.programmers.lime.domains.chatroom.domain; + +import java.util.Objects; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Entity +@Table(name = "chat_room_members") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ChatRoomMember { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "chat_room_id", nullable = false) + private Long chatRoomId; + + @Column(name = "member_id", nullable = false) + private Long memberId; + + public ChatRoomMember(final Long chatRoomId, final Long memberId) { + this.chatRoomId = Objects.requireNonNull(chatRoomId); + this.memberId = Objects.requireNonNull(memberId); + } +} diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomMemberAppender.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomMemberAppender.java new file mode 100644 index 000000000..6d9be0b8e --- /dev/null +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomMemberAppender.java @@ -0,0 +1,23 @@ +package com.programmers.lime.domains.chatroom.implementation; + +import org.springframework.stereotype.Component; + +import com.programmers.lime.domains.chatroom.domain.ChatRoomMember; +import com.programmers.lime.domains.chatroom.repository.ChatRoomMemberRepository; + +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class ChatRoomMemberAppender { + + private final ChatRoomMemberRepository chatRoomMemberRepository; + + public void appendChatRoomMember( + final Long chatRoomId, + final Long memberId + ) { + ChatRoomMember chatRoomMember = new ChatRoomMember(chatRoomId, memberId); + chatRoomMemberRepository.save(chatRoomMember); + } +} diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomMemberReader.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomMemberReader.java new file mode 100644 index 000000000..7654527a9 --- /dev/null +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomMemberReader.java @@ -0,0 +1,28 @@ +package com.programmers.lime.domains.chatroom.implementation; + + +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import com.programmers.lime.domains.chatroom.repository.ChatRoomMemberRepository; + +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class ChatRoomMemberReader { + + private final ChatRoomMemberRepository chatRoomMemberRepository; + + public int countChatRoomMembersByChatRoomId(final Long chatRoomId) { + return chatRoomMemberRepository.countChatRoomMembersByChatRoomId(chatRoomId); + } + + public boolean existMemberByMemberIdAndRoomId( + final Long chatRoomId, + final Long memberId + ) { + return chatRoomMemberRepository.existsAllByChatRoomIdAndMemberId(chatRoomId, memberId); + } +} diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomMemberRemover.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomMemberRemover.java new file mode 100644 index 000000000..69881885a --- /dev/null +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomMemberRemover.java @@ -0,0 +1,23 @@ +package com.programmers.lime.domains.chatroom.implementation; + +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import com.programmers.lime.domains.chatroom.repository.ChatRoomMemberRepository; + +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class ChatRoomMemberRemover { + + private final ChatRoomMemberRepository chatRoomMemberRepository; + + @Transactional + public void removeChatRoomMember( + final Long chatRoomId, + final Long memberId + ) { + chatRoomMemberRepository.deleteByChatRoomIdAndMemberId(chatRoomId, memberId); + } +} diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomReader.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomReader.java new file mode 100644 index 000000000..eb2832c82 --- /dev/null +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomReader.java @@ -0,0 +1,25 @@ +package com.programmers.lime.domains.chatroom.implementation; + +import java.util.List; + +import org.springframework.stereotype.Component; + +import com.programmers.lime.domains.chatroom.model.ChatRoomInfo; +import com.programmers.lime.domains.chatroom.repository.ChatRoomRepository; + +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class ChatRoomReader { + + private final ChatRoomRepository chatRoomRepository; + + public List readOpenChatRoomsByMemberId(Long memberId) { + return chatRoomRepository.findOpenChatRoomsIncludingWithoutMembers(memberId); + } + + public List readOpenChatRooms() { + return chatRoomRepository.findOpenChatRooms(); + } +} diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/model/ChatRoomInfo.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/model/ChatRoomInfo.java new file mode 100644 index 000000000..7d0199b67 --- /dev/null +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/model/ChatRoomInfo.java @@ -0,0 +1,12 @@ +package com.programmers.lime.domains.chatroom.model; + +public record ChatRoomInfo( + Long chatRoomId, + String chatRoomName, + ChatRoomType chatRoomType, + ChatRoomStatus chatRoomStatus, + int roomMaxMemberCount, + boolean isJoined, + Long currentMemberCount +) { +} diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/model/ChatRoomStatus.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/model/ChatRoomStatus.java new file mode 100644 index 000000000..016ce64d1 --- /dev/null +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/model/ChatRoomStatus.java @@ -0,0 +1,16 @@ +package com.programmers.lime.domains.chatroom.model; + +public enum ChatRoomStatus { + + OPEN("열림"), + CLOSE("닫힘"); + private final String description; + + ChatRoomStatus(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } +} diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/model/ChatRoomType.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/model/ChatRoomType.java new file mode 100644 index 000000000..f00bf2d66 --- /dev/null +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/model/ChatRoomType.java @@ -0,0 +1,16 @@ +package com.programmers.lime.domains.chatroom.model; + +public enum ChatRoomType { + + PRIVATE("비공개"), + PUBLIC("공개"); + private final String description; + + ChatRoomType(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } +} diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomMemberRepository.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomMemberRepository.java new file mode 100644 index 000000000..8130248f8 --- /dev/null +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomMemberRepository.java @@ -0,0 +1,20 @@ +package com.programmers.lime.domains.chatroom.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.programmers.lime.domains.chatroom.domain.ChatRoomMember; + +public interface ChatRoomMemberRepository extends JpaRepository { + + int countChatRoomMembersByChatRoomId(final Long chatRoomId); + + boolean existsAllByChatRoomIdAndMemberId( + final Long chatRoomId, + final Long memberId + ); + + void deleteByChatRoomIdAndMemberId( + final Long chatRoomId, + final Long memberId + ); +} diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomQueryDsl.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomQueryDsl.java new file mode 100644 index 000000000..a6ab271b2 --- /dev/null +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomQueryDsl.java @@ -0,0 +1,12 @@ +package com.programmers.lime.domains.chatroom.repository; + +import java.util.List; + +import com.programmers.lime.domains.chatroom.model.ChatRoomInfo; + +public interface ChatRoomQueryDsl { + + List findOpenChatRoomsIncludingWithoutMembers(Long memberId); + + List findOpenChatRooms(); +} diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomQueryDslImpl.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomQueryDslImpl.java new file mode 100644 index 000000000..fbf8b9254 --- /dev/null +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomQueryDslImpl.java @@ -0,0 +1,71 @@ +package com.programmers.lime.domains.chatroom.repository; + +import java.util.List; + +import static com.programmers.lime.domains.chatroom.domain.QChatRoom.*; +import static com.programmers.lime.domains.chatroom.domain.QChatRoomMember.*; +import static com.querydsl.core.types.ExpressionUtils.*; + +import com.programmers.lime.domains.chatroom.model.ChatRoomInfo; +import com.programmers.lime.domains.chatroom.model.ChatRoomStatus; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.jpa.JPAExpressions; +import com.querydsl.jpa.impl.JPAQueryFactory; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class ChatRoomQueryDslImpl implements ChatRoomQueryDsl { + + private final JPAQueryFactory jpaQueryFactory; + + @Override + public List findOpenChatRoomsIncludingWithoutMembers(final Long memberId) { + return jpaQueryFactory + .select(Projections.constructor(ChatRoomInfo.class, + chatRoom.id.as("chatRoomId"), + chatRoom.roomName.as("chatRoomName"), + chatRoom.chatRoomType.as("chatRoomType"), + chatRoom.chatRoomStatus.as("chatRoomStatus"), + chatRoom.roomMaxMemberCount.as("roomMaxMemberCount"), + chatRoomMember.memberId.coalesce(0L).goe(1L).as("isJoined"), + JPAExpressions + .select(count(chatRoomMember.chatRoomId)) + .from(chatRoomMember) + .where( + chatRoom.id.eq(chatRoomMember.chatRoomId) + ) + )) + .from(chatRoom) + .leftJoin(chatRoomMember).on(chatRoom.id.eq(chatRoomMember.chatRoomId) + .and(chatRoomMember.memberId.eq(memberId))) + .where(chatRoom.chatRoomStatus.eq(ChatRoomStatus.OPEN)) + .groupBy(chatRoom.id) + .fetch(); + } + + @Override + public List findOpenChatRooms() { + return jpaQueryFactory + .select(Projections.constructor(ChatRoomInfo.class, + chatRoom.id.as("chatRoomId"), + chatRoom.roomName.as("chatRoomName"), + chatRoom.chatRoomType.as("chatRoomType"), + chatRoom.chatRoomStatus.as("chatRoomStatus"), + chatRoom.roomMaxMemberCount.as("roomMaxMemberCount"), + Expressions.constant(false), + JPAExpressions + .select(count(chatRoomMember.chatRoomId)) + .from(chatRoomMember) + .where( + chatRoom.id.eq(chatRoomMember.chatRoomId) + ) + )) + .from(chatRoom) + .where(chatRoom.chatRoomStatus.eq(ChatRoomStatus.OPEN)) + .fetch(); + } + + +} diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomRepository.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomRepository.java new file mode 100644 index 000000000..34380390e --- /dev/null +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/repository/ChatRoomRepository.java @@ -0,0 +1,12 @@ +package com.programmers.lime.domains.chatroom.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.programmers.lime.domains.chatroom.domain.ChatRoom; + + +public interface ChatRoomRepository extends JpaRepository, ChatRoomQueryDsl{ + + + +} From d675452413cca5fd14a855df12006bbf8dc47913 Mon Sep 17 00:00:00 2001 From: Curry4182 Date: Fri, 22 Mar 2024 18:34:15 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=EB=B9=84=EC=A6=88=EB=8B=88?= =?UTF-8?q?=EC=8A=A4=20=EB=A1=9C=EC=A7=81=EC=9D=B4=20=EC=95=84=EB=8B=88?= =?UTF-8?q?=EB=9D=BC=EB=A9=B4=20=EA=B5=AC=ED=98=84=20=EA=B3=84=EC=B8=B5?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EA=B5=AC=ED=98=84=ED=95=A0=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8F=84=EB=A1=9D=20=EA=B8=B0=EB=8A=A5=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domains/chatroom/application/ChatRoomService.java | 9 +-------- .../domains/chatroom/implementation/ChatRoomReader.java | 7 +++---- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java index cbd438b0c..44c737d74 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java @@ -39,14 +39,7 @@ public class ChatRoomService { public ChatRoomGetServiceListResponse getAvailableChatRooms() { Long memberId = SecurityUtils.getCurrentMemberId(); - List chatRoomInfos = null; - - if(Objects.isNull(memberId)) { - chatRoomInfos = chatRoomReader.readOpenChatRooms(); - } else { - chatRoomInfos = chatRoomReader.readOpenChatRoomsByMemberId(memberId); - } - + List chatRoomInfos = chatRoomReader.readOpenChatRoomsByMemberId(memberId); return new ChatRoomGetServiceListResponse( chatRoomInfos ); diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomReader.java b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomReader.java index eb2832c82..d9915a81e 100644 --- a/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomReader.java +++ b/lime-domain/src/main/java/com/programmers/lime/domains/chatroom/implementation/ChatRoomReader.java @@ -16,10 +16,9 @@ public class ChatRoomReader { private final ChatRoomRepository chatRoomRepository; public List readOpenChatRoomsByMemberId(Long memberId) { - return chatRoomRepository.findOpenChatRoomsIncludingWithoutMembers(memberId); - } - - public List readOpenChatRooms() { + if(memberId != null) { + return chatRoomRepository.findOpenChatRoomsIncludingWithoutMembers(memberId); + } return chatRoomRepository.findOpenChatRooms(); } } From 98cfbd5f17ffef253ff3c85678d592425a139f7b Mon Sep 17 00:00:00 2001 From: Curry4182 Date: Fri, 22 Mar 2024 18:34:41 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20final=20=ED=82=A4=EC=9B=8C=EB=93=9C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatroom/api/dto/response/ChatRoomGetListResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/dto/response/ChatRoomGetListResponse.java b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/dto/response/ChatRoomGetListResponse.java index 98144c7f6..99ac0128d 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/dto/response/ChatRoomGetListResponse.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/dto/response/ChatRoomGetListResponse.java @@ -8,7 +8,7 @@ public record ChatRoomGetListResponse( List chatRoomInfos ) { - public static ChatRoomGetListResponse from(ChatRoomGetServiceListResponse chatRoomGetServiceListResponse) { + public static ChatRoomGetListResponse from(final ChatRoomGetServiceListResponse chatRoomGetServiceListResponse) { return new ChatRoomGetListResponse( chatRoomGetServiceListResponse.chatRoomInfos() ); From d3d1cfaa3e7613f455a6266d87a9e5bf8faa3b78 Mon Sep 17 00:00:00 2001 From: Curry4182 Date: Fri, 22 Mar 2024 18:37:38 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20ChatRoomService=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EC=97=90=20final=20=ED=82=A4=EC=9B=8C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lime/domains/chatroom/application/ChatRoomService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java index 44c737d74..68aabf247 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java @@ -45,7 +45,7 @@ public ChatRoomGetServiceListResponse getAvailableChatRooms() { ); } - public void joinChatRoom(Long chatRoomId) { + public void joinChatRoom(final Long chatRoomId) { Long memberId = SecurityUtils.getCurrentMemberId(); @@ -64,7 +64,7 @@ public int countChatRoomMembersByChatRoomId(Long chatRoomId) { return chatRoomMemberReader.countChatRoomMembersByChatRoomId(chatRoomId); } - public void exitChatRoom(Long chatRoomId) { + public void exitChatRoom(final Long chatRoomId) { Long memberId = SecurityUtils.getCurrentMemberId(); Set sessionIdsByMemberAndRoom = chatSessionRedisManager.getSessionIdsByMemberAndRoom( From 2bcd9c65eb9b289922a3d748b83ee209cf1da886 Mon Sep 17 00:00:00 2001 From: Curry4182 Date: Fri, 22 Mar 2024 20:14:21 +0900 Subject: [PATCH 5/5] =?UTF-8?q?refactor:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=8A=A4=EC=9B=A8=EA=B1=B0=20=EC=84=A4=EB=AA=85=20=ED=95=9C?= =?UTF-8?q?=EA=B8=80=20=EC=98=A4=ED=83=88=EC=9E=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lime/domains/chatroom/api/ChatRoomController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/ChatRoomController.java b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/ChatRoomController.java index 00ed62b08..20edd9ac3 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/ChatRoomController.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/api/ChatRoomController.java @@ -26,7 +26,7 @@ public class ChatRoomController { //private final ChatService chatService; - @Operation(summary = "채티방 전체 조회", description = "채팅방을 조회합니다.") + @Operation(summary = "채팅방 전체 조회", description = "채팅방을 조회합니다.") @GetMapping public ResponseEntity getChatRooms() { ChatRoomGetServiceListResponse serviceResponse = chatRoomService.getAvailableChatRooms();