From ffbac7269fcbc58f305d81423bc20f30321a8a4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=8B=AC=EC=9E=AC=EC=97=BD?= <jysim0326@ajou.ac.kr>
Date: Tue, 19 Nov 2024 18:18:55 +0900
Subject: [PATCH] =?UTF-8?q?feat:=20=EB=B2=88=EA=B0=9C=EB=AA=A8=EC=9E=84=20?=
 =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=EC=9E=91?=
 =?UTF-8?q?=EC=84=B1=20(#9)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 services/meetingService.js | 159 +++++++++++++++++++++++++++++++++++++
 1 file changed, 159 insertions(+)
 create mode 100644 services/meetingService.js

diff --git a/services/meetingService.js b/services/meetingService.js
new file mode 100644
index 0000000..912a120
--- /dev/null
+++ b/services/meetingService.js
@@ -0,0 +1,159 @@
+const { v4: uuidv4 } = require('uuid');
+const { Meeting, MeetingParticipant, User } = require('../models');
+const ChatRoom = require('../models/chatRooms');
+const chatController = require('../controllers/chatController');
+const MeetingResponse = require('../dtos/MeetingResponse');
+const MeetingDetailResponse = require('../dtos/MeetingDetailResponse');
+
+class MeetingService {
+  async createMeeting(meetingData) {
+    const { title, description, start_time, end_time, location, deadline, type, created_by } = meetingData;
+
+    const user = await User.findOne({ where: { id: created_by } });
+    if (!user) {
+      throw new Error('사용자를 찾을 수 없습니다.');
+    }
+
+    const chatRoomData = {
+      participants: [user.name],
+    };
+    const chatRoomResponse = await chatController.createChatRoomInternal(chatRoomData);
+
+    if (!chatRoomResponse.success) {
+      throw new Error('채팅방 생성 실패');
+    }
+
+    const chatRoomId = chatRoomResponse.chatRoomId;
+
+    const newMeeting = await Meeting.create({
+      title,
+      description,
+      start_time,
+      end_time,
+      location,
+      deadline,
+      type,
+      created_by,
+      chatRoomId,
+    });
+
+    await MeetingParticipant.create({
+      meeting_id: newMeeting.id,
+      user_id: created_by,
+    });
+
+    return { meeting_id: newMeeting.id, chatRoomId: chatRoomResponse.chatRoomId };
+  }
+
+  async getMeetings(userId) {
+    const meetings = await Meeting.findAll({
+      attributes: ['id', 'title', 'description', 'start_time', 'end_time', 'location', 'deadline', 'type'],
+      include: [
+        {
+          model: User,
+          as: 'creator',
+          attributes: ['name'],
+        },
+        {
+          model: MeetingParticipant,
+          as: 'participants',
+          attributes: ['user_id'],
+        },
+      ],
+    });
+
+    return meetings.map((meeting) => {
+      const creatorName = meeting.creator ? meeting.creator.name : 'Unknown';
+      const isParticipant = meeting.participants.some(participant => participant.user_id === parseInt(userId, 10));
+
+      return new MeetingResponse(
+        meeting,
+        isParticipant,
+        false,
+        creatorName
+      );
+    });
+  }
+
+  async closeMeeting(meetingId) {
+    const meeting = await Meeting.findByPk(meetingId);
+    if (!meeting) {
+      throw new Error('모임을 찾을 수 없습니다.');
+    }
+
+    if (meeting.type === 'CLOSE') {
+      throw new Error('이미 마감된 모임입니다.');
+    }
+
+    meeting.type = 'CLOSE';
+    await meeting.save();
+    return meeting;
+  }
+
+  async joinMeeting(meetingId, userId) {
+    const meeting = await Meeting.findByPk(meetingId);
+    if (!meeting) {
+      throw new Error('모임을 찾을 수 없습니다.');
+    }
+
+    if(meeting.type === 'CLOSE') {
+      throw new Error('이미 마감된 모임입니다.');
+    }
+
+    if (new Date() > new Date(meeting.deadline)) {
+      throw new Error('참가 신청이 마감되었습니다.');
+    }
+
+    const existingParticipant = await MeetingParticipant.findOne({ 
+      where: { meeting_id: meetingId, user_id: userId } 
+    });
+    
+    if (existingParticipant) {
+      throw new Error('이미 참가한 사용자입니다.');
+    }
+
+    await MeetingParticipant.create({ meeting_id: meetingId, user_id: userId });
+
+    const user = await User.findOne({ where: { id: userId } });
+    const chatRoom = await ChatRoom.findOne({ meeting_id: meetingId });
+
+    if (chatRoom && !chatRoom.participants.includes(user.name)) {
+      chatRoom.participants.push(user.name);
+      chatRoom.isOnline.set(user.name, true);
+      chatRoom.lastReadAt.set(user.name, new Date());
+      chatRoom.lastReadLogId.set(user.name, null);
+      await chatRoom.save();
+    }
+  }
+
+  async getMeetingDetail(meetingId) {
+    const meeting = await Meeting.findByPk(meetingId, {
+      include: [
+        {
+          model: User,
+          as: 'creator',
+          attributes: ['name']
+        },
+        {
+          model: MeetingParticipant,
+          as: 'participants',
+          include: [
+            {
+              model: User,
+              as: 'participantUser',
+              attributes: ['name', 'email']
+            }
+          ]
+        }
+      ]
+    });
+
+    if (!meeting) {
+      throw new Error('모임을 찾을 수 없습니다.');
+    }
+
+    return new MeetingDetailResponse(meeting);
+  }
+}
+
+module.exports = new MeetingService();
-- 
GitLab