Skip to content

Commit 361bd92

Browse files
authored
Merge pull request #174 from prgrms-web-devcourse-final-project/feature/EA3-111-groupchat
[EA3-111] feature : dto/서비스 리팩토링 및 그룹 채팅 테스트를 위한 임시 html 파일 생성
2 parents 32748dd + c80ba9b commit 361bd92

File tree

8 files changed

+127
-104
lines changed

8 files changed

+127
-104
lines changed
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package grep.neogul_coder.domain.groupchat.controller.dto.requset;
22

3+
import grep.neogul_coder.domain.groupchat.entity.GroupChatMessage;
4+
import grep.neogul_coder.domain.groupchat.entity.GroupChatRoom;
35
import io.swagger.v3.oas.annotations.Hidden;
6+
import java.time.LocalDateTime;
47
import lombok.Getter;
58

69
@Hidden
@@ -18,15 +21,12 @@ public GroupChatMessageRequestDto(Long roomId, Long senderId, String message) {
1821
this.message = message;
1922
}
2023

21-
public void setRoomId(Long roomId) {
22-
this.roomId = roomId;
23-
}
24-
25-
public void setSenderId(Long senderId) {
26-
this.senderId = senderId;
27-
}
28-
29-
public void setMessage(String message) {
30-
this.message = message;
24+
public GroupChatMessage toEntity(GroupChatRoom room, Long senderId) {
25+
return new GroupChatMessage(
26+
room,
27+
senderId,
28+
this.message,
29+
LocalDateTime.now()
30+
);
3131
}
3232
}

src/main/java/grep/neogul_coder/domain/groupchat/controller/dto/requset/GroupChatSwaggerRequest.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,4 @@ public class GroupChatSwaggerRequest {
1515

1616
@Schema(description = "보낼 메시지", example = "안녕하세요!")
1717
private String message;
18-
19-
20-
public void setSenderId(Long senderId) { this.senderId = senderId; }
21-
22-
public void setRoomId(Long roomId) { this.roomId = roomId; }
23-
24-
public void setMessage(String message) { this.message = message; }
2518
}
Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package grep.neogul_coder.domain.groupchat.controller.dto.response;
22

3+
import grep.neogul_coder.domain.groupchat.entity.GroupChatMessage;
4+
import grep.neogul_coder.domain.users.entity.User;
35
import io.swagger.v3.oas.annotations.Hidden;
46
import java.time.LocalDateTime;
57
import lombok.Getter;
@@ -16,10 +18,7 @@ public class GroupChatMessageResponseDto {
1618
private String message; // 메시지 내용
1719
private LocalDateTime sentAt; // 보낸 시간
1820

19-
public GroupChatMessageResponseDto() {
20-
}
21-
22-
public GroupChatMessageResponseDto(Long id, Long roomId, Long senderId,
21+
private GroupChatMessageResponseDto(Long id, Long roomId, Long senderId,
2322
String senderNickname, String profileImageUrl,
2423
String message, LocalDateTime sentAt) {
2524
this.id = id;
@@ -31,31 +30,15 @@ public GroupChatMessageResponseDto(Long id, Long roomId, Long senderId,
3130
this.sentAt = sentAt;
3231
}
3332

34-
public void setId(Long id) {
35-
this.id = id;
36-
}
37-
38-
public void setRoomId(Long roomId) {
39-
this.roomId = roomId;
40-
}
41-
42-
public void setSenderId(Long senderId) {
43-
this.senderId = senderId;
44-
}
45-
46-
public void setSenderNickname(String senderNickname) {
47-
this.senderNickname = senderNickname;
48-
}
49-
50-
public void setProfileImageUrl(String profileImageUrl) {
51-
this.profileImageUrl = profileImageUrl;
52-
}
53-
54-
public void setMessage(String message) {
55-
this.message = message;
56-
}
57-
58-
public void setSentAt(LocalDateTime sentAt) {
59-
this.sentAt = sentAt;
33+
public static GroupChatMessageResponseDto from(GroupChatMessage message, User sender) {
34+
return new GroupChatMessageResponseDto(
35+
message.getMessageId(),
36+
message.getGroupChatRoom().getRoomId(),
37+
sender.getId(),
38+
sender.getNickname(),
39+
sender.getProfileImageUrl(),
40+
message.getMessage(),
41+
message.getSentAt()
42+
);
6043
}
6144
}

src/main/java/grep/neogul_coder/domain/groupchat/entity/GroupChatMessage.java

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,14 @@ public class GroupChatMessage extends BaseEntity {
2727

2828
private LocalDateTime sentAt;
2929

30-
public void setMessageId(Long messageId) {
31-
this.messageId = messageId;
32-
}
33-
34-
public void setGroupChatRoom(GroupChatRoom groupChatRoom) {
35-
this.groupChatRoom = groupChatRoom;
36-
}
37-
38-
public void setUserId(Long userId) {
30+
public GroupChatMessage(GroupChatRoom room, Long userId, String message, LocalDateTime sentAt) {
31+
this.groupChatRoom = room;
3932
this.userId = userId;
40-
}
41-
42-
public void setMessage(String message) {
4333
this.message = message;
34+
this.sentAt = sentAt;
4435
}
4536

46-
public void setSentAt(LocalDateTime sentAt) {
47-
this.sentAt = sentAt;
37+
protected GroupChatMessage() {
38+
4839
}
4940
}

src/main/java/grep/neogul_coder/domain/groupchat/repository/GroupChatMessageRepository.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@
99

1010
public interface GroupChatMessageRepository extends JpaRepository<GroupChatMessage, Long> {
1111

12-
1312
// 채팅방(roomId)에 속한 메시지를 전송 시간 내림차순으로 페이징 조회
1413
@Query("SELECT m FROM GroupChatMessage m " +
1514
"WHERE m.groupChatRoom.roomId = :roomId " +
1615
"ORDER BY m.sentAt ASC")
1716
Page<GroupChatMessage> findMessagesByRoomIdAsc(@Param("roomId") Long roomId, Pageable pageable);
1817

19-
}
18+
}

src/main/java/grep/neogul_coder/domain/groupchat/service/GroupChatService.java

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
import grep.neogul_coder.domain.users.entity.User;
1111
import grep.neogul_coder.domain.users.repository.UserRepository;
1212
import grep.neogul_coder.global.response.PageResponse;
13+
import lombok.RequiredArgsConstructor;
1314
import org.springframework.data.domain.Page;
1415
import org.springframework.data.domain.PageRequest;
1516
import org.springframework.data.domain.Pageable;
1617
import org.springframework.data.domain.Sort;
1718
import org.springframework.stereotype.Service;
1819
import java.time.LocalDateTime;
1920

21+
@RequiredArgsConstructor
2022
@Service
2123
public class GroupChatService {
2224

@@ -25,17 +27,6 @@ public class GroupChatService {
2527
private final UserRepository userRepository;
2628
private final StudyMemberRepository studyMemberRepository;
2729

28-
// 생성자 주입을 통한 의존성 주입
29-
public GroupChatService(GroupChatMessageRepository messageRepository,
30-
GroupChatRoomRepository roomRepository,
31-
UserRepository userRepository,
32-
StudyMemberRepository studyMemberRepository) {
33-
this.messageRepository = messageRepository;
34-
this.roomRepository = roomRepository;
35-
this.userRepository = userRepository;
36-
this.studyMemberRepository = studyMemberRepository;
37-
}
38-
3930
public GroupChatMessageResponseDto saveMessage(GroupChatMessageRequestDto requestDto) {
4031
// 채팅방 존재 여부 확인
4132
GroupChatRoom room = roomRepository.findById(requestDto.getRoomId())
@@ -51,26 +42,14 @@ public GroupChatMessageResponseDto saveMessage(GroupChatMessageRequestDto reques
5142
throw new IllegalArgumentException("해당 스터디에 참가한 사용자만 채팅할 수 있습니다.");
5243
}
5344

54-
// 메시지 생성 및 저장
55-
GroupChatMessage message = new GroupChatMessage();
56-
message.setGroupChatRoom(room); // 엔티티에 있는 필드명 맞게 사용
57-
message.setUserId(sender.getId()); // 연관관계 없이 userId만 저장
58-
message.setMessage(requestDto.getMessage());
59-
message.setSentAt(LocalDateTime.now());
45+
// 메시지 생성
46+
GroupChatMessage message = requestDto.toEntity(room, sender.getId());
6047

6148
// 메시지 저장
6249
messageRepository.save(message);
6350

64-
// 저장된 메시지를 dto로 변환
65-
return new GroupChatMessageResponseDto(
66-
message.getMessageId(),
67-
message.getGroupChatRoom().getRoomId(), // ← roomId 필드가 필요하면 여기서 꺼내야 함
68-
sender.getId(),
69-
sender.getNickname(),
70-
sender.getProfileImageUrl(),
71-
message.getMessage(),
72-
message.getSentAt()
73-
);
51+
// 응답 dto 생성
52+
return GroupChatMessageResponseDto.from(message, sender);
7453
}
7554

7655
// 과거 채팅 메시지 페이징 조회 (무한 스크롤용)
@@ -86,15 +65,7 @@ public PageResponse<GroupChatMessageResponseDto> getMessages(Long roomId, int pa
8665
User sender = userRepository.findById(message.getUserId())
8766
.orElseThrow(() -> new IllegalArgumentException("사용자가 존재하지 않습니다."));
8867

89-
return new GroupChatMessageResponseDto(
90-
message.getMessageId(),
91-
message.getGroupChatRoom().getRoomId(),
92-
sender.getId(),
93-
sender.getNickname(),
94-
sender.getProfileImageUrl(),
95-
message.getMessage(),
96-
message.getSentAt()
97-
);
68+
return GroupChatMessageResponseDto.from(message, sender);
9869
});
9970

10071
// PageResponse로 감싸서 반환

src/main/resources/data.sql

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ INSERT INTO study_post (study_id, user_id, title, category, content) VALUES (4,
1616
INSERT INTO study_post (study_id, user_id, title, category, content) VALUES (2, 2, '개발 유튜브 공유', 'FREE', '재미니의 개발실무 ( 토스 ); 개발바닥');
1717
INSERT INTO study_post (study_id, user_id, title, category, content) VALUES (5, 5, '점심 메뉴 추천', 'FREE', '오늘 점심 뭐먹을지 추천 받습니다!');
1818

19-
INSERT INTO comment (post_id, user_id, content) VALUES (5, 4, '확인 했습니다!');
20-
INSERT INTO comment (post_id, user_id, content) VALUES (5, 4, '좋은 정보 감사합니다!');
21-
INSERT INTO comment (post_id, user_id, content) VALUES (3, 2, '관련된 블로그 공유 드립니다!');
22-
INSERT INTO comment (post_id, user_id, content) VALUES (2, 5, '정보 감사합니다!');
23-
INSERT INTO comment (post_id, user_id, content) VALUES (4, 1, '제육 돈까스');
19+
-- INSERT INTO comment (post_id, user_id, content) VALUES (5, 4, '확인 했습니다!');
20+
-- INSERT INTO comment (post_id, user_id, content) VALUES (5, 4, '좋은 정보 감사합니다!');
21+
-- INSERT INTO comment (post_id, user_id, content) VALUES (3, 2, '관련된 블로그 공유 드립니다!');
22+
-- INSERT INTO comment (post_id, user_id, content) VALUES (2, 5, '정보 감사합니다!');
23+
-- INSERT INTO comment (post_id, user_id, content) VALUES (4, 1, '제육 돈까스');
2424

2525
INSERT INTO study_member (study_id, user_id, role, participated) VALUES (1, 3, 'LEADER', FALSE);
2626
INSERT INTO study_member (study_id, user_id, role, participated) VALUES (1, 4, 'MEMBER', FALSE);
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<!DOCTYPE html>
2+
<html lang="ko">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>그룹 채팅 로컬 테스트</title>
6+
<script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.1/sockjs.min.js"></script>
7+
<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
8+
</head>
9+
<body>
10+
<h2>그룹 채팅 테스트 (로컬 서버)</h2>
11+
12+
<div>
13+
<label>Room ID: </label>
14+
<input type="number" id="roomId" value="1">
15+
<label>Sender ID: </label>
16+
<input type="number" id="senderId" value="10">
17+
<button onclick="connect()">연결하기</button>
18+
<button onclick="disconnect()">연결 해제</button>
19+
</div>
20+
21+
<hr>
22+
23+
<div>
24+
<input type="text" id="messageInput" placeholder="메시지를 입력하세요" style="width: 300px;">
25+
<button onclick="sendMessage()">전송</button>
26+
</div>
27+
28+
<h3>채팅 로그</h3>
29+
<ul id="chatList"></ul>
30+
31+
<script>
32+
let stompClient = null;
33+
let currentRoomId = null;
34+
35+
function connect() {
36+
const roomId = document.getElementById("roomId").value || 1;
37+
currentRoomId = roomId;
38+
39+
// 로컬 서버용 WebSocket 엔드포인트
40+
const socket = new SockJS("http://localhost:8083/ws-stomp");
41+
stompClient = Stomp.over(socket);
42+
43+
stompClient.connect({}, function (frame) {
44+
console.log("WebSocket 연결 성공:", frame);
45+
alert("채팅방 " + roomId + "에 연결되었습니다!");
46+
47+
// 채팅방 구독
48+
stompClient.subscribe(`/sub/chat/room/${roomId}`, function (message) {
49+
const chat = JSON.parse(message.body);
50+
showMessage(chat.senderNickname + ": " + chat.message);
51+
});
52+
});
53+
}
54+
55+
function sendMessage() {
56+
const messageContent = document.getElementById("messageInput").value;
57+
const senderId = document.getElementById("senderId").value || 10;
58+
59+
if (stompClient && stompClient.connected) {
60+
stompClient.send("/pub/chat/message", {}, JSON.stringify({
61+
roomId: currentRoomId,
62+
senderId: senderId,
63+
message: messageContent
64+
}));
65+
document.getElementById("messageInput").value = "";
66+
} else {
67+
alert("WebSocket이 연결되지 않았습니다.");
68+
}
69+
}
70+
71+
function disconnect() {
72+
if (stompClient) {
73+
stompClient.disconnect(() => {
74+
alert("연결이 해제되었습니다.");
75+
});
76+
}
77+
}
78+
79+
function showMessage(message) {
80+
const li = document.createElement("li");
81+
li.textContent = message;
82+
document.getElementById("chatList").appendChild(li);
83+
}
84+
</script>
85+
</body>
86+
</html>

0 commit comments

Comments
 (0)