Skip to content

Commit 18864f5

Browse files
committed
feat(clients): 添加一般课表获取
1 parent 03eb9b9 commit 18864f5

File tree

7 files changed

+338
-1883
lines changed

7 files changed

+338
-1883
lines changed

auth/cas.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,24 @@ export default class CASAuth {
344344
}
345345
}
346346

347+
async loginHUBM() {
348+
const url = 'http://hub.m.hust.edu.cn/hub_weix';
349+
const isLogin = await this.checkLoginStatus();
350+
351+
if (!isLogin) {
352+
return false;
353+
}
354+
355+
try {
356+
let response = await this.axios.get(url);
357+
response = await followRedirect(response, this.axios);
358+
359+
return response.status === 200;
360+
} catch (e) {
361+
return false;
362+
}
363+
}
364+
347365
async loginONE() {
348366
const url = 'https://one.hust.edu.cn/dcp/';
349367
const isLogin = await this.checkLoginStatus();

bun.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

clients/course-client.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import axios from 'axios';
33
import { useCookie } from '@/utils/use-cookie';
44
import type HUST from '..';
55
import { getPhysicsCourseGrades, getPhysicsCourseSchedule as getPhysicsCourseSchedule } from './course/physics';
6+
import { getNormalCourseSchedule } from './course/course';
67

78
export default class CourseClient {
89
protected readonly axios: AxiosInstance;
@@ -33,4 +34,10 @@ export default class CourseClient {
3334
getPhysicsCourseGrades(this.axios),
3435
);
3536
}
36-
}
37+
38+
async getNormalCourseSchedule(semesterId: string) {
39+
return await this.hust.handleRequest(() =>
40+
getNormalCourseSchedule(this.axios, semesterId),
41+
);
42+
}
43+
}

clients/course/course.ts

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import type {
2+
NormalCourseSchedule,
3+
NormalCourseScheduleResponse,
4+
} from '@/types/clients/course/course';
5+
import type { AxiosInstance } from 'axios';
6+
import type { Dayjs } from 'dayjs';
7+
import dayjs from 'dayjs';
8+
9+
function getStartTimeFromLesson(lesson: number, date: Dayjs): Dayjs {
10+
const mayDay = date
11+
.clone()
12+
.set('month', 5)
13+
.set('day', 1)
14+
.set('hour', 0)
15+
.set('minute', 0)
16+
.set('second', 0);
17+
const nationalDay = date
18+
.clone()
19+
.set('month', 10)
20+
.set('day', 1)
21+
.set('hour', 0)
22+
.set('minute', 0)
23+
.set('second', 0);
24+
25+
if (date >= mayDay && date < nationalDay) {
26+
switch (lesson) {
27+
case 1:
28+
return date.hour(8).minute(0);
29+
case 2:
30+
return date.hour(8).minute(55);
31+
case 3:
32+
return date.hour(10).minute(10);
33+
case 4:
34+
return date.hour(11).minute(5);
35+
case 5:
36+
return date.hour(14).minute(0);
37+
case 6:
38+
return date.hour(14).minute(50);
39+
case 7:
40+
return date.hour(15).minute(55);
41+
case 8:
42+
return date.hour(16).minute(45);
43+
case 9:
44+
return date.hour(18).minute(30);
45+
case 10:
46+
return date.hour(19).minute(20);
47+
case 11:
48+
return date.hour(20).minute(15);
49+
case 12:
50+
return date.hour(21).minute(5);
51+
default:
52+
throw new Error(`Invalid lesson number: ${lesson}`);
53+
}
54+
} else {
55+
switch (lesson) {
56+
case 1:
57+
return date.hour(8).minute(0);
58+
case 2:
59+
return date.hour(8).minute(55);
60+
case 3:
61+
return date.hour(10).minute(10);
62+
case 4:
63+
return date.hour(11).minute(5);
64+
case 5:
65+
return date.hour(14).minute(30);
66+
case 6:
67+
return date.hour(15).minute(20);
68+
case 7:
69+
return date.hour(16).minute(25);
70+
case 8:
71+
return date.hour(17).minute(15);
72+
case 9:
73+
return date.hour(19).minute(0);
74+
case 10:
75+
return date.hour(19).minute(50);
76+
case 11:
77+
return date.hour(20).minute(45);
78+
case 12:
79+
return date.hour(21).minute(35);
80+
default:
81+
throw new Error(`Invalid lesson number: ${lesson}`);
82+
}
83+
}
84+
}
85+
86+
function getEndTimeFromLesson(lesson: number, date: Dayjs): Dayjs {
87+
const startTime = getStartTimeFromLesson(lesson, date);
88+
return startTime.add(45, 'minute');
89+
}
90+
91+
export async function getNormalCourseSchedule(
92+
axios: AxiosInstance,
93+
semesterId: string,
94+
): Promise<NormalCourseSchedule[]> {
95+
const url = `https://hubs.hust.edu.cn/schedule/getStudentScheduleByXqh?XQH=${semesterId}`;
96+
97+
try {
98+
const response = await axios.get(url);
99+
if (response.status !== 200) {
100+
throw new Error(
101+
`Error fetching course schedule for semester ${semesterId}.`,
102+
);
103+
}
104+
const data: NormalCourseScheduleResponse = response.data;
105+
106+
const results: NormalCourseSchedule[] = [];
107+
for (const item of data) {
108+
const startTime = dayjs(item.KS);
109+
const weekdays = [
110+
'MONDAY',
111+
'TUESDAY',
112+
'WEDNESDAY',
113+
'THURSDAY',
114+
'FRIDAY',
115+
'SATURDAY',
116+
'SUNDAY',
117+
] as const;
118+
for (const index in weekdays) {
119+
const dayKey = weekdays[index]!;
120+
const classes = item[dayKey];
121+
if (classes && classes.length > 0) {
122+
results.push(
123+
...classes.map((cls) => ({
124+
courseId: cls.KCBH,
125+
courseName: cls.KCMC,
126+
teacherName: cls.JSMC,
127+
roomName: cls.JSMC,
128+
startLesson: Number(cls.QSJC),
129+
endLesson: Number(cls.JSJC),
130+
startTime: getStartTimeFromLesson(
131+
Number(cls.QSJC),
132+
startTime.add(Number(index), 'day'),
133+
),
134+
endTime: getEndTimeFromLesson(
135+
Number(cls.JSJC),
136+
startTime.add(Number(index), 'day'),
137+
),
138+
weekDay: Number(cls.XQ),
139+
weekNum: item.ZC,
140+
classId: cls.KTBH,
141+
className: cls.KTMC,
142+
remarks: cls.BZ || '',
143+
targetGrade: cls.MXNJ,
144+
startWeek: cls.QSZC,
145+
endWeek: cls.JSZC,
146+
teachingMethod: cls.SKXS,
147+
semesterId: cls.XQH,
148+
})),
149+
);
150+
}
151+
}
152+
}
153+
154+
return results;
155+
} catch (e) {
156+
console.error('CourseClient.getNormalCourseSchedule error on fetching', e);
157+
throw e;
158+
}
159+
}

index.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,13 @@ export default class HUST {
154154
case Client.news:
155155
return await this.auth.loginONE();
156156
case Client.course:
157-
return await this.auth.loginPhysics();
157+
return (
158+
await Promise.all([
159+
this.auth.loginPhysics(),
160+
this.auth.loginHUBM(),
161+
this.auth.loginHUBS(),
162+
])
163+
).every((item) => item);
158164
default:
159165
throw new Error(`Client ${client} not supported`);
160166
}
@@ -261,7 +267,7 @@ console.log('Initializing HUST SDK...');
261267
const res = await hust.news.getNewsList();
262268
console.log('News List:', res);
263269

264-
const res2 = await hust.course.getPhysicsCourseGrades();
270+
const res2 = await hust.course.getNormalCourseSchedule('20242');
265271
console.log('Course Schedule:', res2);
266272

267273
console.log(`initialized after ${new Date().getTime() - now.getTime()}ms`);

0 commit comments

Comments
 (0)