Info
- ์ผ์ ๋ฐ์ดํฐ.
- class ํํ๋ก ๊ตฌํ.
- TIME/TASK ์ผ๋ก type์ด ๊ตฌ๋ถ๋จ.
- TIME: ๋ /์/์ผ/์/๋ถ ๋จ์๋ก ์ผ์ ์ ๊ด๋ฆฌ
- TASK: ๋ /์/์ผ ๋จ์๋ก ์ผ์ ์ ๊ด๋ฆฌ
Schedule
- DB์์ ๊ด๋ฆฌ๋๋ Schedule ๋ฐ์ดํฐ ์์ฒด.
- FE์์ ๋ค์ํ ํํ๋ก ์ฌ์ฉํ๊ธฐ ์ํด ์ต๋ํ ๊ธฐ๋ณธ ํํ๋ก ๊ตฌํ.
- ๋ ์ง ํ๋๋ string ํ์
์ผ๋ก "YYYY/MM/DD HH:mm:ss" ํํ
- ์ฌ์ฉ ์, dayjs๋ฅผ ์ฌ์ฉ ํ์ฌ, ํฌ๋ฉง ํ์.
Structure
- Schedule ๊ฐ์ฒด๋ ํฌ๊ด์ ์ธ ๋ ์ง ํํ๋ฅผ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ๊ฐ๊ฐ์ ๋ ์ง์ ๋ํ ์ผ์ ์ด ํ์ํ ๊ฒฝ์ฐ์๋ ScheduleOfDate ๊ฐ์ฒด๋ก ๋ณํ ํ์.
- Schedule ๋ด๋ถ์ getScheduleOfDateList() function์ ํตํด ScheduleOfDate๋ก ๋ณํ ๊ฐ๋ฅ
- getScheduleOfDateList()๋ ์ผ์ ์ด ๊ธธ์๋ก ์ฑ๋ฅ์ ์ํฅ์ ๋ฐ์. O(n)
import { ScheduleOfDate } from '@typings/ScheduleOfDate'
import dateFormatUtil from '@utils/date/dateFormatUtil'
import { scheduleType, ScheduleType } from '@typings/constants/ScheduleType'
// if date format DateFormat.ts -> use DateFormat
export class Schedule {
id: number
type: ScheduleType
startedAt: string
endedAt: string
title: string
contents: string
isImportant: boolean
createdAt: string
updatedAt: string
constructor(schedule: {
id: number | null
type?: ScheduleType
startedAt: string
endedAt: string
title: string
contents: string
isImportant?: boolean
createdAt: string
updatedAt: string
}) {
const { dateToString, getDate } = dateFormatUtil
const now = dateToString(getDate())
const {
id,
type = scheduleType.TIME,
startedAt,
endedAt,
title,
contents,
isImportant = false,
createdAt = now,
updatedAt = now,
} = schedule
this.id = id
this.type = type
this.startedAt = startedAt
this.endedAt = endedAt
this.title = title
this.contents = contents
this.createdAt = createdAt
this.updatedAt = updatedAt
this.isImportant = isImportant
}
getScheduleOfDateList(index: number) {
if (this._isOneDaySchedule()) {
const { stringToDate } = dateFormatUtil
const startedAt = stringToDate(this.startedAt)
const endedAt = stringToDate(this.endedAt)
return [
new ScheduleOfDate({
isMultiple: false,
id: this.id,
type: this.type,
year: startedAt.year(),
month: startedAt.month() + 1,
day: startedAt.date(),
startHour: startedAt.hour(),
startMinute: startedAt.minute(),
endHour: endedAt.hour(),
endMinute: endedAt.minute(),
title: this.title,
contents: this.contents,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
startedAt: this.startedAt,
endedAt: this.endedAt,
isImportant: this.isImportant,
}),
] as ScheduleOfDate[]
}
return this._calculateSchedule(index)
}
private _isOneDaySchedule: () => boolean = () => {
const { stringToDate } = dateFormatUtil
return stringToDate(this.startedAt).isSame(stringToDate(this.endedAt), 'date')
}
private _calculateSchedule: (index: number) => ScheduleOfDate[] = index => {
const scheduleOfDateList: ScheduleOfDate[] = []
const { stringToDate } = dateFormatUtil
const startedAt = stringToDate(this.startedAt)
const endedAt = stringToDate(this.endedAt)
let start = startedAt.clone()
const end = endedAt.clone().add(1, 'day')
while (!start.isSame(end, 'date')) {
let startHour: number
let startMinute: number
let endHour: number
let endMinute: number
if (start.isSame(endedAt, 'date')) {
startHour = 0
startMinute = 0
endHour = endedAt.hour()
endMinute = endedAt.minute()
} else if (start.isSame(startedAt, 'date')) {
startHour = startedAt.hour()
startMinute = startedAt.minute()
endHour = 23
endMinute = 59
} else {
startHour = 0
startMinute = 0
endHour = 23
endMinute = 59
}
scheduleOfDateList.push(
new ScheduleOfDate({
isMultiple: true,
id: this.id,
type: this.type,
year: start.year(),
month: start.month() + 1,
day: start.date(),
startHour: startHour,
startMinute: startMinute,
endHour: endHour,
endMinute: endMinute,
title: this.title,
contents: this.contents,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
startedAt: this.startedAt,
endedAt: this.endedAt,
isImportant: this.isImportant,
order: index,
}),
)
start = start.add(1, 'day')
}
if (scheduleOfDateList.length) {
scheduleOfDateList[0].isStart = true
scheduleOfDateList[scheduleOfDateList.length - 1].isEnd = true
}
return scheduleOfDateList
}
}
ScheduleOfDate
- ๊ฐ๊ฐ์ ๋ ์ง์ ํด๋นํ๋ Schedule ๋ฐ์ดํฐ.
- ์กฐํ ๋ชฉ์ ์ผ๋ก๋ง ์ฌ์ฉ๋จ. (์กฐํ ์ด์ธ์ ๋ชฉ์ ์๋ Schedule ์์ฒด๋ฅผ ๋ณ๊ฒฝํด์ผํจ.)
Structure
- ์์ ๋๋ ์ข ๋ฃ ๋ /์/์ผ/์/๋ถ ๊ฐ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฆฌํ์ฌ ํ๋๋ก ๊ด๋ฆฌ.
- Schedule ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ฐ์ ๋ ์ง์ ๋ฐ๋ผ ๋ถ๋ฆฌํ์์ผ๋ฉฐ, ๋ ์ง๋ ์ฌ๋ฌ ScheduleOfDate๋ฅผ ๊ฐ์ง ์ ์์. (์ค๋ณต X)
- Schedule ๊ธฐ๋ณธ ๋ฐ์ดํฐ์ ๊ด๊ณ์์ด ์ฌ์ฉ๋๋ ๋ด์ฉ๋ค์ get()์ ํตํด ๋ฐ๋ก ๋ถ๋ฆฌํ์ฌ ์ฌ์ฉ.
import { ScheduleType } from '@typings/constants/ScheduleType'
export class ScheduleOfDate {
id: number
type: ScheduleType
year: number
month: number
day: number
startHour: number
startMinute: number
endHour: number
endMinute: number
title: string
contents: string
order: number = 0
isMultiple: boolean
isStart: boolean = false
isEnd: boolean = false
isImportant: boolean = false
startedAt: string
endedAt: string
createdAt: string
updatedAt: string
constructor(schedule: {
id: number
type: ScheduleType
year: number
month: number
day: number
startHour: number
startMinute: number
endHour: number
endMinute: number
title: string
contents: string
isMultiple: boolean
createdAt: string
updatedAt: string
startedAt: string
endedAt: string
order?: number
isStart?: boolean
isEnd?: boolean
isImportant?: boolean
}) {
this.id = schedule.id
this.type = schedule.type
this.year = schedule.year
this.month = schedule.month
this.day = schedule.day
this.startHour = schedule.startHour
this.startMinute = schedule.startMinute
this.endHour = schedule.endHour
this.endMinute = schedule.endMinute
this.title = schedule.title
this.contents = schedule.contents
this.isMultiple = schedule.isMultiple
this.createdAt = schedule.createdAt
this.updatedAt = schedule.updatedAt
this.startedAt = schedule.startedAt
this.endedAt = schedule.endedAt
if (schedule.order) this.order = schedule.order
if (schedule.isStart) this.isStart = schedule.isStart
if (schedule.isEnd) this.isEnd = schedule.isEnd
if (schedule.isImportant) this.isImportant = schedule.isImportant
}
get startPercentage() {
return ((this.startHour * 60 + this.startMinute) / 1440) * 100
}
get endPercentage() {
return ((this.endHour * 60 + this.endMinute) / 1440) * 100
}
get isAllDay() {
return (
this.startHour == 0 && this.startMinute == 0 && this.endHour == 23 && this.endMinute == 59
)
}
}Repository
- BE API๋ฅผ ํตํด DB์ ๊ฐ์ ์ ๊ณต ๋ฐ์.
- ๊ธฐ๋ณธ์ ์ธ CRUD ๊ธฐ๋ฅ.
import { ApiResponse } from '@utils/api/models/ApiResponse'
import { Schedule } from '@typings/Schedule'
import api from '@utils/api/api'
import ApiError from '@utils/error/ApiError'
type ScheduleRepository = {
findAll: () => Promise<Schedule[]>
findById: (id: number) => Promise<Schedule>
findByDate: (date: { year: number; month?: number; day?: number }) => Promise<Schedule[]>
add: (schedule: Schedule) => Promise<null | number>
delete: (id: number) => Promise<void>
modify: (id: number, schedule: Schedule) => Promise<void>
}
const scheduleRepository: ScheduleRepository = {
findAll: async () => {
const response = await api().get('schedule')
const body = response.data.body.map(schedule => new Schedule(schedule))
const apiResponse = new ApiResponse<Schedule[]>().parseClass(response, body)
if (apiResponse.isFailure) throw new ApiError(apiResponse.code)
return apiResponse.body
},
findById: async (id: number) => {
const response = await api().get(`schedule/${id}`)
const apiResponse = new ApiResponse<Schedule>().parseData(response)
if (apiResponse.isFailure) throw new ApiError(apiResponse.code)
return apiResponse.body
},
findByDate: async (date: { year: number; month?: number; day?: number }) => {
const response = await api().get('schedule', { params: date })
const body = response.data.body.map(schedule => new Schedule(schedule))
const apiResponse = new ApiResponse<Schedule[]>().parseClass(response, body)
if (apiResponse.isFailure) throw new ApiError(apiResponse.code)
return apiResponse.body
},
add: async (schedule: Schedule) => {
const apiResponse: ApiResponse<number | null> = new ApiResponse<number | null>().parseData(
await api().post('schedule', schedule),
)
if (apiResponse.isFailure) return null
return apiResponse.body
},
delete: async id => {
const apiResponse: ApiResponse<null> = new ApiResponse<null>().parseData(
await api().delete(`schedule/${id}`),
)
if (apiResponse.isFailure) throw new ApiError(apiResponse.code)
},
modify: async (id, schedule) => {
const apiResponse: ApiResponse<null> = new ApiResponse<null>().parseData(
await api().put(`schedule/${id}`, schedule),
)
if (apiResponse.isFailure) throw new ApiError(apiResponse.code)
},
}
export default scheduleRepository