Skip to content

Commit 298db9f

Browse files
committed
Feat: chat 채팅방 생성
1 parent eb8f89e commit 298db9f

File tree

17 files changed

+364
-10
lines changed

17 files changed

+364
-10
lines changed

build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ dependencies {
6969

7070
// WebClient
7171
implementation ("org.springframework.boot:spring-boot-starter-webflux")
72+
73+
// Spring Security OAuth2
74+
implementation ("org.springframework.security:spring-security-oauth2-client:6.4.2") // Or the version you're using
75+
implementation ("org.springframework.security:spring-security-oauth2-core:6.4.2") // Or the version you're using
76+
7277
}
7378

7479
tasks.withType<Test> {

src/main/java/cmf/commitField/domain/chat/chatMessage/controller/ChatController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ public class ChatController {
2323
private final ChatMessageRepository chatMessageRepository;
2424
private final ChatRoomRepository chatRoomRepository;
2525
private final UserRepository userRepository;
26-
private final SimpMessagingTemplate messagingTemplate; // 특정 채널로 메시지를 보내기 위함
26+
private final SimpMessagingTemplate messagingTemplate;
2727

28-
@MessageMapping("/chat.sendMessage")
28+
@MessageMapping("/chat.sendMessage") // 클라이언트에서 "/app/chat.sendMessage"로 보낼 때 처리됨
2929
public void sendMessage(ChatMessage chatMessage) {
3030
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
3131

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package cmf.commitField.domain.chat.chatRoom.controller;
2+
3+
import cmf.commitField.domain.chat.chatRoom.controller.request.ChatRoomRequest;
4+
import cmf.commitField.domain.chat.chatRoom.service.ChatRoomService;
5+
import cmf.commitField.domain.user.entity.CustomOAuth2User;
6+
import cmf.commitField.global.globalDto.GlobalResponse;
7+
import jakarta.validation.Valid;
8+
import lombok.RequiredArgsConstructor;
9+
import org.springframework.security.core.Authentication;
10+
import org.springframework.security.core.context.SecurityContextHolder;
11+
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
12+
import org.springframework.web.bind.annotation.*;
13+
14+
@RestController
15+
@RequiredArgsConstructor
16+
@RequestMapping("/chat")
17+
public class ChatRoomController {
18+
private final ChatRoomService chatRoomService;
19+
20+
@PostMapping("/room")
21+
public GlobalResponse<Object> createRoom(
22+
@RequestBody @Valid ChatRoomRequest chatRoomRequest) {
23+
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
24+
25+
if (authentication instanceof OAuth2AuthenticationToken) {
26+
CustomOAuth2User principal = (CustomOAuth2User) authentication.getPrincipal();
27+
Long userId = principal.getId(); // getId()를 통해 userId를 추출
28+
chatRoomService.createRoom(chatRoomRequest, userId); // userId를 전달
29+
return GlobalResponse.success();
30+
} else {
31+
throw new IllegalArgumentException("User not logged in.");
32+
}
33+
}
34+
35+
@PostMapping("/room/join/{roomId}")
36+
public GlobalResponse<Object> joinRoom(@PathVariable Long roomId) {
37+
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
38+
39+
if (authentication instanceof OAuth2AuthenticationToken) {
40+
CustomOAuth2User principal = (CustomOAuth2User) authentication.getPrincipal();
41+
Long userId = principal.getId(); // getId()를 통해 userId를 추출
42+
chatRoomService.joinRoom(roomId, userId); // userId를 전달
43+
return GlobalResponse.success();
44+
} else {
45+
throw new IllegalArgumentException("User not logged in.");
46+
}
47+
}
48+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package cmf.commitField.domain.chat.chatRoom.controller.request;
2+
3+
import jakarta.validation.constraints.Max;
4+
import jakarta.validation.constraints.NotEmpty;
5+
import jakarta.validation.constraints.NotNull;
6+
import lombok.AllArgsConstructor;
7+
import lombok.Getter;
8+
import lombok.NoArgsConstructor;
9+
import org.hibernate.validator.constraints.Length;
10+
11+
@Getter
12+
@AllArgsConstructor
13+
@NoArgsConstructor
14+
public class ChatRoomRequest {
15+
16+
@NotEmpty
17+
@Length(min = 2, max = 20)
18+
private String title;
19+
20+
@NotNull
21+
@Max(100)
22+
private Integer userCountMax;
23+
24+
25+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package cmf.commitField.domain.chat.chatRoom.controller.response;
2+
3+
public class ChatRoomResponse {
4+
}

src/main/java/cmf/commitField/domain/chat/chatRoom/entity/ChatRoom.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import lombok.*;
99
import lombok.experimental.SuperBuilder;
1010

11-
import java.time.LocalDateTime;
1211
import java.util.List;
1312

1413
@Entity
@@ -21,8 +20,11 @@ public class ChatRoom extends BaseEntity {
2120

2221
private String title;
2322
private String tier;
23+
private Long roomCreator;
24+
//최대 인원 100명
25+
private Integer userCountMax;
2426

25-
private LocalDateTime deletedAt;
27+
// private LocalDateTime deletedAt;
2628

2729
@ManyToOne(fetch = FetchType.LAZY)
2830
@JoinColumn(name = "user_id")
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
package cmf.commitField.domain.chat.chatRoom.repository;
22

33
import cmf.commitField.domain.chat.chatRoom.entity.ChatRoom;
4+
import jakarta.persistence.LockModeType;
5+
import jakarta.persistence.QueryHint;
46
import org.springframework.data.jpa.repository.JpaRepository;
7+
import org.springframework.data.jpa.repository.Lock;
8+
import org.springframework.data.jpa.repository.QueryHints;
59
import org.springframework.stereotype.Repository;
610

11+
import java.util.Optional;
12+
713
@Repository
814
public interface ChatRoomRepository extends JpaRepository<ChatRoom, Long> {
15+
16+
@Lock(LockModeType.PESSIMISTIC_WRITE)
17+
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="1000")})
18+
Optional<ChatRoom> findById(Long aLong);
919
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package cmf.commitField.domain.chat.chatRoom.service;
2+
3+
import cmf.commitField.domain.chat.chatRoom.controller.request.ChatRoomRequest;
4+
5+
public interface ChatRoomService {
6+
7+
void createRoom(ChatRoomRequest chatRoomRequest, Long userId); // userId를 받도록 수정
8+
9+
void joinRoom(Long roomId, Long userId); // userId를 받도록 수정
10+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package cmf.commitField.domain.chat.chatRoom.service;
2+
3+
import cmf.commitField.domain.chat.chatRoom.controller.request.ChatRoomRequest;
4+
import cmf.commitField.domain.chat.chatRoom.entity.ChatRoom;
5+
import cmf.commitField.domain.chat.chatRoom.repository.ChatRoomRepository;
6+
import cmf.commitField.domain.chat.userChatRoom.entity.UserChatRoom;
7+
import cmf.commitField.domain.chat.userChatRoom.repository.UserChatRoomRepository;
8+
import cmf.commitField.domain.user.entity.User;
9+
import cmf.commitField.domain.user.repository.UserRepository;
10+
import cmf.commitField.global.error.ErrorCode;
11+
import cmf.commitField.global.exception.CustomException;
12+
import jakarta.transaction.Transactional;
13+
import lombok.RequiredArgsConstructor;
14+
import org.springframework.stereotype.Service;
15+
16+
import java.time.LocalDateTime;
17+
18+
@Service
19+
@RequiredArgsConstructor
20+
public class ChatRoomServiceImpl implements ChatRoomService {
21+
22+
private final ChatRoomRepository chatRoomRepository;
23+
private final UserRepository userRepository;
24+
private final UserChatRoomRepository userChatRoomRepository;
25+
26+
@Override
27+
@Transactional
28+
public void createRoom(ChatRoomRequest chatRoomRequest, Long userId) {
29+
// 유저정보 조회
30+
User findUser = userRepository.findById(userId)
31+
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_USER));
32+
33+
// ChatRoom 생성
34+
ChatRoom chatRoom = ChatRoom.builder()
35+
.roomCreator(findUser.getId())
36+
.title(chatRoomRequest.getTitle())
37+
.userCountMax(chatRoomRequest.getUserCountMax())
38+
.createdAt(LocalDateTime.now())
39+
.modifiedAt(LocalDateTime.now())
40+
.build();
41+
ChatRoom savedChatRoom = chatRoomRepository.save(chatRoom);
42+
43+
// 연관관계 user_chat room 생성
44+
UserChatRoom userChatRoom = UserChatRoom.builder()
45+
.user(findUser)
46+
.chatRoom(savedChatRoom)
47+
.build();
48+
userChatRoomRepository.save(userChatRoom);
49+
}
50+
51+
@Override
52+
@Transactional
53+
public void joinRoom(Long roomId, Long userId) {
54+
// 유저 조회
55+
User findUser = userRepository.findById(userId)
56+
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_USER));
57+
58+
// room 조회
59+
ChatRoom chatRoom = chatRoomRepository.findById(roomId)
60+
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_ROOM));
61+
62+
// 현재 인원 수 조회
63+
Long currentUserCount = userChatRoomRepository.countByChatRoomId(roomId);
64+
65+
// 채팅방이 꽉 찼을 경우 예외 처리
66+
if (currentUserCount >= chatRoom.getUserCountMax()) {
67+
throw new CustomException(ErrorCode.ROOM_USER_FULL);
68+
}
69+
70+
// user_chatroom 관계 생성
71+
UserChatRoom userChatRoom = UserChatRoom.builder()
72+
.user(findUser)
73+
.chatRoom(chatRoom)
74+
.build();
75+
userChatRoomRepository.save(userChatRoom);
76+
}
77+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package cmf.commitField.domain.chat.chatRoom.service;
2+
3+
public class ChatRoomServiceImplTest {
4+
}

0 commit comments

Comments
 (0)