Newer
Older
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
const { v4: uuidv4 } = require('uuid');
class ChatService {
// 채팅방 생성
async createChatRoom({ meeting_id, participants }) {
try {
const chatRoomId = uuidv4();
const newRoom = new ChatRoom({
chatRoomId: chatRoomId,
meeting_id,
participants,
messages: [],
lastReadAt: participants.reduce((acc, user) => {
acc[user] = new Date();
return acc;
}, {}),
lastReadLogId: participants.reduce((acc, user) => {
acc[user] = null;
return acc;
}, {}),
isOnline: participants.reduce((acc, user) => {
acc[user] = true;
return acc;
}, {}),
});
const joinMessage = {
message: `${participants[0]}님이 번개 모임을 생성했습니다.`,
timestamp: new Date(),
type: 'join',
};
newRoom.messages.push(joinMessage);
await newRoom.save();
return { success: true, chatRoomId };
} catch (err) {
console.error('Error creating chat room:', err);
throw new Error('Failed to create chat room');
}
}
// 채팅방 목록 조회
async getChatRooms() {
const rooms = await ChatRoom.find({}, { chatRoomId: 1, messages: { $slice: -1 } });
return rooms.map(room => {
const lastMessage = room.messages[0] || {};
return {
chatRoomId: room.chatRoomId,
lastMessage: {
sender: lastMessage.sender || '없음',
message: lastMessage.message || '메시지 없음',
timestamp: lastMessage.timestamp || null,
}
};
});
}
// 사용자 상태 업데이트
async updateStatus(chatRoomId, nickname, isOnline) {
await ChatRoom.updateOne(
{ chatRoomId },
{ $set: { [`isOnline.${nickname}`]: isOnline } }
);
}
// 읽음 상태 업데이트
async updateReadStatus(chatRoomId, nickname) {
const now = new Date();
await ChatRoom.updateOne(
{ chatRoomId },
{ $set: { [`lastReadAt.${nickname}`]: now } }
);
}
// 읽지 않은 메시지 조회
async getUnreadMessages(nickname) {
const chatRooms = await ChatRoom.find({ participants: nickname });
return await Promise.all(chatRooms.map(async (chatRoom) => {
const lastReadAt = chatRoom.lastReadAt.get(nickname) || new Date(0);
const unreadMessagesCount = chatRoom.messages.filter(message =>
message.timestamp > lastReadAt
).length;
return {
chatRoomId: chatRoom.chatRoomId,
unreadCount: unreadMessagesCount,
};
}));
}
// 읽지 않은 메시지 수 조회
async getUnreadCount(chatRoomId) {
const chatRoom = await ChatRoom.findOne({ chatRoomId });
if (!chatRoom) {
throw new Error('Chat room not found');
}
const unreadCounts = chatRoom.participants
.filter(user => chatRoom.lastReadLogId.get(user))
.map(user => chatRoom.lastReadLogId.get(user))
.reduce((acc, logId) => {
acc[logId] = (acc[logId] || 0) + 1;
return acc;
}, {});
let count = 0;
return Object.entries(unreadCounts)
.sort(([logId1], [logId2]) => logId1.localeCompare(logId2))
.reduce((acc, [logId, value]) => {
count += value;
acc[count] = logId;
return acc;
}, {});
}
// 읽은 메시지 로그 ID 업데이트
async updateReadLogId(chatRoomId, nickname, logId) {
await ChatRoom.updateOne(
{ chatRoomId },
{ $set: { [`lastReadLogId.${nickname}`]: logId } }
);
}
// 상태와 로그 ID 동시 업데이트
async updateStatusAndLogId(chatRoomId, nickname, isOnline, logId) {
let finalLogId = logId;
if (!isOnline && logId === null) {
const chatRoom = await ChatRoom.findOne({ chatRoomId });
if (chatRoom && chatRoom.messages.length > 0) {
finalLogId = chatRoom.messages[chatRoom.messages.length - 1]._id;
}
}
await ChatRoom.updateOne(
{ chatRoomId },
{
$set: {
[`isOnline.${nickname}`]: isOnline,
[`lastReadLogId.${nickname}`]: isOnline ? null : finalLogId,
},
}
);
}
}
module.exports = new ChatService();