cqu.js 4.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. const getStudentId = () => document.querySelector('.trigger-user-name').innerText.match(/\[(.*?)\]/)?.[1];
  2. const checkLogin = () => window.location.hostname === 'my.cqu.edu.cn' && getStudentId() !== undefined;
  3. const getAccessToken = () => localStorage.getItem('cqu_edu_ACCESS_TOKEN').replaceAll('"', '');
  4. const baseFetch = async (url, accessToken, method, body, description) => {
  5. const response = await fetch(
  6. url,
  7. {
  8. method,
  9. credentials: 'include',
  10. headers: {
  11. 'Content-Type': 'application/json',
  12. 'Authorization': `Bearer ${accessToken}`,
  13. },
  14. body,
  15. }
  16. );
  17. if (!response.ok) {
  18. AndroidBridge.showToast(`获取${description}失败,请退出重试`);
  19. throw new Error(`获取${description}失败: ${termResponse.status} ${termResponse.statusText}`);
  20. }
  21. return await response.json();
  22. }
  23. const getTermId = async (accessToken) => (await baseFetch('https://my.cqu.edu.cn/api/resourceapi/session/info-detail', accessToken, 'GET', null, '学期信息')).curSessionId;
  24. const getStartDate = async (termId, accessToken) => (new Date((await baseFetch(`https://my.cqu.edu.cn/api/resourceapi/session/info/${termId}`, accessToken, 'GET', null, '学期详情')).data.beginDate).toISOString().split('T')[0]);
  25. const getMaxWeek = async (termId, accessToken) => (await baseFetch(`https://my.cqu.edu.cn/api/timetable/course/maxWeek/${termId}`, accessToken, 'GET', null, '最大周数')).data;
  26. const getTimeSlots = async (accessToken) => (await baseFetch('https://my.cqu.edu.cn/api/workspace/time-pattern/session-time-pattern', accessToken, 'GET', null, '时间段配置')).data.classPeriodVOS;
  27. const getSchedule = async (termId, accessToken, studentId) => (await baseFetch(`https://my.cqu.edu.cn/api/timetable/class/timetable/student/my-table-detail?sessionId=${termId}`, accessToken, 'POST', JSON.stringify([studentId]), '课程表')).classTimetableVOList;
  28. const parseSchedule = (startDate, maxWeek, timeSlots, schedule) => ({
  29. courseConfig: {
  30. semesterStartDate: startDate,
  31. totalWeeks: maxWeek,
  32. },
  33. timeSlots: timeSlots.map((timeSlot, index) => ({
  34. number: timeSlot.periodOrder ?? index + 1,
  35. startTime: timeSlot.startTime ?? '',
  36. endTime: timeSlot.endTime ?? '',
  37. })),
  38. courses: schedule.map((course) => ({
  39. name: course.courseName ?? '',
  40. teacher: course.instructorName?.slice(0, course.instructorName?.indexOf('-')) ?? '',
  41. position: course.position ?? course.roomName ?? '',
  42. day: course.weekDay ?? 0,
  43. startSection: (course.periodFormat?.indexOf('-') ?? 0) > 0 ? (Number(course.periodFormat?.split('-')[0]) + 1) : (Number(course.periodFormat) + 1) ?? 0,
  44. endSection: (course.periodFormat?.indexOf('-') ?? 0) > 0 ? (Number(course.periodFormat?.split('-')[1]) + 1) : (Number(course.periodFormat) + 1) ?? 0,
  45. weeks: (course.teachingWeek ?? '').split('').map((char, index) => (char === '1' ? index + 1 : null)).filter(week => week !== null),
  46. })),
  47. });
  48. const saveSchedule = (parsedSchedule) => Promise.allSettled([
  49. window.AndroidBridgePromise.saveCourseConfig(JSON.stringify(parsedSchedule?.courseConfig)),
  50. window.AndroidBridgePromise.saveImportedCourses(JSON.stringify(parsedSchedule?.courses)),
  51. window.AndroidBridgePromise.savePresetTimeSlots(JSON.stringify(parsedSchedule?.timeSlots)),
  52. ]);
  53. (async () => {
  54. if (!checkLogin()) {
  55. AndroidBridge.showToast("尚未登录重庆大学教务系统,请先登录!");
  56. throw new Error("未检测到登录状态");
  57. }
  58. const studentId = getStudentId();
  59. const accessToken = getAccessToken();
  60. if (!accessToken) {
  61. AndroidBridge.showToast("尚未登录");
  62. throw new Error("未找到访问令牌,请确保已登录 my.cqu.edu.cn");
  63. }
  64. const termId = await getTermId(accessToken);
  65. await saveSchedule(parseSchedule(...(await Promise.allSettled([getStartDate(termId, accessToken), getMaxWeek(termId, accessToken), getTimeSlots(accessToken), getSchedule(termId, accessToken, studentId)])).map(result => result.value)));
  66. AndroidBridge.notifyTaskCompletion();
  67. })();