diff --git a/package-lock.json b/package-lock.json index a0c3fb0..dd094cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "bcrypt": "^5.1.1", "class-transformer": "^0.5.1", "class-validator": "^0.14.1", + "date-fns": "^3.3.1", "jsonwebtoken": "^9.0.2", "multer": "^1.4.5-lts.1", "multer-s3": "^3.0.1", @@ -5526,6 +5527,15 @@ "node": ">= 8" } }, + "node_modules/date-fns": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.3.1.tgz", + "integrity": "sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/dayjs": { "version": "1.11.10", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", diff --git a/package.json b/package.json index 5a1931f..d3f9017 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "bcrypt": "^5.1.1", "class-transformer": "^0.5.1", "class-validator": "^0.14.1", + "date-fns": "^3.3.1", "jsonwebtoken": "^9.0.2", "multer": "^1.4.5-lts.1", "multer-s3": "^3.0.1", diff --git a/src/journey/journey.service.ts b/src/journey/journey.service.ts index 0581f93..9ad7247 100644 --- a/src/journey/journey.service.ts +++ b/src/journey/journey.service.ts @@ -4,6 +4,7 @@ import { Injectable, NotFoundException, } from '@nestjs/common'; +import { addDays, isAfter } from 'date-fns'; import { JourneyEntity } from './model/journey.entity'; import { errResponse, response } from 'src/response/response'; import { BaseResponse } from 'src/response/response.status'; @@ -29,20 +30,38 @@ export class JourneyService { const journey = await JourneyEntity.createJourney(user, createJourneyDto); //일정 배너 생성하기 : (startDate - endDate + 1)개 - let currentDate = new Date(createJourneyDto.startDate); - const lastDate = new Date(createJourneyDto.endDate); - - while (currentDate <= lastDate) { - const schedule = await ScheduleEntity.createSchedule( - journey, - currentDate, - ); - currentDate = new Date(currentDate); - currentDate.setDate(currentDate.getDate() + 1); - } + //일정 배너 생성하기 : (startDate - endDate + 1)개 + const startDate = new Date(createJourneyDto.startDate); + const endDate = new Date(createJourneyDto.endDate); + + const schedules = await this.createSchedules(journey, startDate, endDate); return errResponse(BaseResponse.JOURNEY_CREATED); } + private async createSchedules( + journey: JourneyEntity, + startDate: Date, + endDate: Date, + ) { + let currentDate = startDate; + const schedules = []; + + // endDate가 startDate 이후인지 확인 + if (isAfter(endDate, startDate)) { + while (currentDate <= endDate) { + const schedule = await ScheduleEntity.createSchedule( + journey, + currentDate, + ); + schedules.push(schedule); + currentDate = addDays(currentDate, 1); // 다음 날짜로 이동 + } + } else { + throw new Error('endDate는 startDate보다 이후여야 합니다.'); + } + + return schedules; + } //여정 수정하기 async updateJourney(user, journeyId: number, title: string) { diff --git a/src/journey/model/journey.entity.ts b/src/journey/model/journey.entity.ts index 32d773e..1c546fb 100644 --- a/src/journey/model/journey.entity.ts +++ b/src/journey/model/journey.entity.ts @@ -14,7 +14,7 @@ import { LessThanOrEqual, MoreThanOrEqual, } from 'typeorm'; - +import { startOfMonth, endOfMonth, isWithinInterval } from 'date-fns'; import { ScheduleEntity } from 'src/schedule/schedule.entity'; import { UserEntity } from 'src/user/user.entity'; import { MonthInfoDto } from 'src/map/month-info.dto'; @@ -119,11 +119,18 @@ export class JourneyEntity extends BaseEntity { const journeys: JourneyEntity[] = await JourneyEntity.find({ where: { user: { id: userId }, - startDate: Between(new Date(0), date), - endDate: Between(date, new Date('9999-12-31')), }, }); - return journeys; + + // 매개변수로 받은 날짜가 어느 여정에 포함되어 있는지 확인 + const matchingJourney = journeys.find((journey) => { + return isWithinInterval(date, { + start: journey.startDate, + end: journey.endDate, + }); + }); + + return matchingJourney; } //사용자의 월별 여정 조회 diff --git a/src/map/map.service.ts b/src/map/map.service.ts index 5e7a1a4..e54c86d 100644 --- a/src/map/map.service.ts +++ b/src/map/map.service.ts @@ -23,56 +23,54 @@ export class MapService { options: CursorBasedPaginationRequestDto, ) { const user = await UserEntity.findExistUser(userId); - const journeys = await JourneyEntity.findExistJourneyByDate(user.id, date); - - // 커서 값에 해당하는 배너들을 가져옴 - const paginatedJourneys = journeys.slice( - options.cursor, - options.cursor + options.pageSize, + const journey = await JourneyEntity.findExistJourneyByDate(user.id, date); + const schedules = await ScheduleEntity.findExistSchedulesByJourneyId( + journey.id, ); - if (paginatedJourneys.length === 0) { - return { - data: response(BaseResponse.SCHEDULE_NOT_FOUND, { nextCursor: null }), - }; - } - const result = await Promise.all( - paginatedJourneys.map(async (journey) => { - const schedules = await ScheduleEntity.findExistSchedulesByJourneyId( - journey.id, - ); - const scheduleList = await Promise.all( - schedules.map(async (schedule) => { - const locations = await this.getLocationList([schedule]); // getLocationList에 schedule 배열을 전달 - const detailSchedules = await this.getDetailScheduleList([ - schedule, - ]); // getDetailScheduleList에 schedule 배열을 전달 - const diary = await this.getDiaryStatus([schedule]); // getDiaryStatus에 schedule 배열을 전달 - - return { - scheduleId: schedule.id, - title: schedule.title, - date: schedule.date, - location: locations, - detailSchedules: detailSchedules, - diary: diary, - }; - }), - ); + const journeyInfo = { + userId: user.id, + journeyId: journey.id, + startDate: journey.startDate, + endDate: journey.endDate, + }; + const scheduleList = await Promise.all( + schedules.map(async (schedule) => { + const locations = await this.getLocationList([schedule]); // getLocationList에 schedule 배열을 전달 + const detailSchedules = await this.getDetailScheduleList([schedule]); // getDetailScheduleList에 schedule 배열을 전달 + const diary = await this.getDiaryStatus([schedule]); // getDiaryStatus에 schedule 배열을 전달 return { - userId: user.id, - journeyId: journey.id, - startDate: journey.startDate, - endDate: journey.endDate, - scheduleList: scheduleList, + scheduleId: schedule.id, + title: schedule.title, + date: schedule.date, + location: locations, + detailSchedules: detailSchedules, + diary: diary, }; }), ); + // return { + // userId: user.id, + // journeyId: journey.id, + // startDate: journey.startDate, + // endDate: journey.endDate, + // scheduleList: scheduleList, + // }; + + // 페이징 처리 + const paginatedSchedules = scheduleList.slice( + options.cursor, + options.cursor + options.pageSize, + ); + // 다음 페이지를 위한 커서 값 계산 const nextCursor = Number(options.cursor) + Number(options.pageSize); return { - data: response(BaseResponse.GET_SCHEDULE_SUCCESS, result), + data: response(BaseResponse.GET_SCHEDULE_SUCCESS, { + journeyInfo, + scheduleList, + }), nextCursor: nextCursor, }; } diff --git a/src/schedule/schedule.entity.ts b/src/schedule/schedule.entity.ts index 47d0a37..9c9db63 100644 --- a/src/schedule/schedule.entity.ts +++ b/src/schedule/schedule.entity.ts @@ -12,6 +12,7 @@ import { Between, } from 'typeorm'; import { NotFoundException } from '@nestjs/common'; +import { startOfMonth, endOfMonth } from 'date-fns'; import { BaseResponse } from 'src/response/response.status'; import { DetailScheduleEntity } from '../detail-schedule/detail-schedule.entity'; import { LocationEntity } from 'src/location/location.entity'; @@ -61,7 +62,7 @@ export class ScheduleEntity extends BaseEntity { //일정 작성하기 static async createSchedule(journey: JourneyEntity, currentDate) { const schedule = new ScheduleEntity(); - schedule.date = currentDate.toISOString().split('T')[0]; + schedule.date = currentDate; schedule.journey = journey; return await schedule.save(); }