UNPKG

school-adviser

Version:
526 lines (466 loc) 11.8 kB
import axios from 'axios'; import { getApiUrl } from '../utils/api'; import { getDate } from '../utils/date'; import { HighSchoolTimetableParams, HighSchoolTimetableType } from '../types/timetable/highschool'; /** * @description 시간표 정보를 빌드하는 클래스입니다. * @example * const timetable = await new HighSchoolTimetableBuilder('J10', '7530124') * .withYear('2021') * .build(); */ export class HighSchoolTimetableBuilder { /** * @description API URL * * @private */ private readonly API_URL: string; /** * @description 시도교육청코드 * * @example * 'J10' * * @private */ private readonly scCode: string | undefined; /** * @description 표준학교코드 * * @example * '7530124' * * @private */ private readonly schoolCode: string | undefined; /** * @description 학년도 * @type {string} * * @example * '2021' */ private year: string | undefined; /** * @description 학기 * @type {string} * * @example * '1' */ private semester: string | undefined; /** * @description 시간표일자 * @type {string} * * @example * '20210825' */ private date: string | undefined; /** * @description 주야과정명 * @type {string} * * @example * '주간' */ private dayNightCourse: string | undefined; /** * @description 계열명 * @type {string} * * @example * '일반계' */ private realm: string | undefined; /** * @description 학과명 * @type {string} * * @example * '7차일반' */ private department: string | undefined; /** * @description 학년 * @type {string} * * @example * '1' */ private grade: string | undefined; /** * @description 강의실명 * @type {string} * * @example * '1-1' */ private classroom: string | undefined; /** * @description 학급명 * @type {string} * * @example * '1' */ private class: string | undefined; /** * @description 교시 * @type {string} * * @example * '1' */ private period: string | undefined; /** * @description 시간표시작일자 * @type {string} * * @example * '20210825' */ private from: string | undefined; /** * @description 시간표종료일자 * @type {string} * * @example * '20210825' */ private to: string | undefined; /** * @description 페이지 위치 * * @example * 1 * * @private */ private page: number | undefined; /** * @description 페이지 당 신청 숫자 * * @example * 100 * * @private */ private pageSize: number | undefined; /** * @description 학원 정보를 빌드하는 클래스입니다. * * @example * const timetable = await new HighSchoolTimetableBuilder('J10', '7581078') * .withYear('2021') * .build(); */ constructor(scCode: string, schoolCode: string) { this.scCode = scCode; this.schoolCode = schoolCode; this.API_URL = getApiUrl('hisTimetable'); } /** * @description 시간표 정보를 객체 형태로 빌드합니다. * * @example * const timetable = await new ElementaryTimetableBuilder() * .withParams({ * scCode: 'J10' * }) * .build(); * * @param params 시간표 정보를 담은 객체입니다. */ withParams = (params: HighSchoolTimetableParams): HighSchoolTimetableBuilder => { this.year = params.year; this.semester = params.semester; this.date = params.date; this.dayNightCourse = params.dayNightCourse; this.realm = params.realm; this.department = params.department; this.grade = params.grade; this.classroom = params.classroom; this.class = params.class; this.period = params.period; this.to = params.to; this.from = params.from; this.from = params.between?.[0]; this.to = params.between?.[1]; return this; }; /** * @description 학년도를 설정합니다. * * @example * '2021' * * @param year 학년도 */ withYear = (year: string): HighSchoolTimetableBuilder => { this.year = year; return this; }; /** * @description 학기를 설정합니다. * * @example * '1' * * @param semester 학기 */ withSemester = (semester: string): HighSchoolTimetableBuilder => { this.semester = semester; return this; }; /** * @description 시간표일자를 설정합니다. * * @example * '20210825' * * @param date 시간표일자 */ withDate = (date: string): HighSchoolTimetableBuilder => { this.date = date; return this; }; /** * @description 주야과정명을 설정합니다. * * @example * '주간' * * @param dayNightCourse 주야과정명 */ withDayNightCourse = (dayNightCourse: string): HighSchoolTimetableBuilder => { this.dayNightCourse = dayNightCourse; return this; }; /** * @description 계열명을 설정합니다. * * @example * '일반계' * * @param realm 계열명 */ withRealm = (realm: string): HighSchoolTimetableBuilder => { this.realm = realm; return this; }; /** * @description 학과명을 설정합니다. * * @example * '7차일반' * * @param department 학과명 */ withDepartment = (department: string): HighSchoolTimetableBuilder => { this.department = department; return this; }; /** * @description 학년을 설정합니다. * * @example * '1' * * @param grade 학년 */ withGrade = (grade: string): HighSchoolTimetableBuilder => { this.grade = grade; return this; }; /** * @description 강의실명을 설정합니다. * * @example * '1-1' * * @param classroom 강의실명 */ withClassroom = (classroom: string): HighSchoolTimetableBuilder => { this.classroom = classroom; return this; }; /** * @description 학급명을 설정합니다. * * @example * '1' * * @param class_ 학급명 */ withClass = (class_: string): HighSchoolTimetableBuilder => { this.class = class_; return this; }; /** * @description 교시를 설정합니다. * * @example * '1' * * @param period 교시 */ withPeriod = (period: string): HighSchoolTimetableBuilder => { this.period = period; return this; }; /** * @description 시간표시작일자를 설정합니다. * * @example * '20210825' * * @param from 시간표시작일자 */ withFrom = (from: string): HighSchoolTimetableBuilder => { this.from = from; return this; }; /** * @description 시간표종료일자를 설정합니다. * * @example * '20210825' * * @param to 시간표종료일자 */ withTo = (to: string): HighSchoolTimetableBuilder => { this.to = to; return this; }; /** * @description 시간표시작일자와 시간표종료일자를 설정합니다. * * @example * ['20210825', '20210825'] * * @param between 시간표시작일자와 시간표종료일자 */ withBetween = (between: [ string, string ]): HighSchoolTimetableBuilder => { this.from = between[0]; this.to = between[1]; return this; }; /** * @description 페이지 위치를 설정합니다. * * @example * 1 * * @param page 페이지 위치 */ withPage = (page: number): HighSchoolTimetableBuilder => { this.page = page; return this; }; /** * @description 페이지 당 신청 숫자를 설정합니다. * * @example * 100 * * @param pageSize 페이지 당 신청 숫자 */ withPageSize = (pageSize: number): HighSchoolTimetableBuilder => { this.pageSize = pageSize; return this; }; /** * @description API URL을 반환합니다. * * @example * 'https://open.neis.go.kr/hub/hisTimetable?KEY=...&Type=json' * * @returns {string} API URL */ url = (): string => { let url = this.API_URL; if (this.scCode) { url += `&ATPT_OFCDC_SC_CODE=${ this.scCode }`; } if (this.schoolCode) { url += `&SD_SCHUL_CODE=${ this.schoolCode }`; } if (this.year) { url += `&AY=${ this.year }`; } if (this.semester) { url += `&SEM=${ this.semester }`; } if (this.date) { url += `&ALL_TI_YMD=${ this.date }`; } if (this.dayNightCourse) { url += `&DGHT_CRSE_SC_NM=${ this.dayNightCourse }`; } if (this.realm) { url += `&ORD_SC_NM=${ this.realm }`; } if (this.department) { url += `&DEPT_NM=${ this.department }`; } if (this.grade) { url += `&GRADE=${ this.grade }`; } if (this.classroom) { url += `&CLRM_NM=${ this.classroom }`; } if (this.class) { url += `&CLASS_NM=${ this.class }`; } if (this.period) { url += `&PERIO=${ this.period }`; } if (this.from) { url += `&TI_FROM_YMD=${ this.from }`; } if (this.to) { url += `&TI_TO_YMD=${ this.to }`; } if (this.page) { url += `&pIndex=${ this.page }`; } if (this.pageSize) { url += `&pSize=${ this.pageSize }`; } return url; }; /** * @description 설정한 정보를 바탕으로 시간표 정보를 빌드합니다. * * @example * const timetable = await new HighSchoolTimetableBuidler('J10', '7530124') * .withYear('2021') * .build(); * * @returns {Promise<<HighSchoolTimetableType>[]>} 시간표 정보를 담은 객체입니다. * @throws {Error} 시간표 정보를 불러오지 못했을 경우 에러를 던집니다. * @see {@link https://open.neis.go.kr/portal/data/service/selectServicePage.do?page=1&rows=10&sortColumn=&sortDirection=&infId=OPEN18620200826103326268120&infSeq=2} API 정보 */ build = async (): Promise<HighSchoolTimetableType[]> => { try { const res = await axios.get(this.url()); if (res.data?.RESULT?.CODE === 'INFO-200') { return []; } const data = res.data.hisTimetable[1].row; data.forEach((timetable: HighSchoolTimetableType) => { if (typeof timetable.ALL_TI_YMD === 'string') { timetable.ALL_TI_YMD = getDate(timetable.ALL_TI_YMD); } if (typeof timetable.LOAD_DTM === 'string') { timetable.LOAD_DTM = getDate(timetable.LOAD_DTM); } }); return data; } catch (error) { throw new Error('Cannot find timetable with given info'); } }; }