tust_01.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // 天津科技大学(tust.edu.cn)拾光课程表适配脚本
  2. // 解析 classWeek 字符串 (支持不定长度)
  3. function parseWeekString(weekStr) {
  4. let weeks = [];
  5. if (!weekStr) return weeks;
  6. for (let i = 0; i < weekStr.length; i++) {
  7. if (weekStr[i] === '1') weeks.push(i + 1);
  8. }
  9. return weeks;
  10. }
  11. // 格式化时间 (0800 -> 08:00)
  12. function formatTime(timeStr) {
  13. if (timeStr && timeStr.length === 4) {
  14. return timeStr.substring(0, 2) + ":" + timeStr.substring(2);
  15. }
  16. return timeStr;
  17. }
  18. async function promptUserToStart() {
  19. return await window.shiguangBridgePromise.showAlert(
  20. "教务系统课表导入",
  21. "导入前请确认您已经在课表界面",
  22. "好的,开始导入"
  23. );
  24. }
  25. /**
  26. * 拉取课程数据并解析
  27. */
  28. async function fetchCourses() {
  29. // 随机码,每次页面刷新都会变
  30. const randomCodeRegExpExec = /\/student\/courseSelect\/thisSemesterCurriculum\/([0-9a-zA-Z]+)\/ajaxStudentSchedule\/curr\/callback/.exec(document.head.innerHTML);
  31. const randomCode = randomCodeRegExpExec[1];
  32. // 拉取课程数据
  33. const response = await fetch(`http://jwxtxs.tust.edu.cn:46110/student/courseSelect/thisSemesterCurriculum/${randomCode}/ajaxStudentSchedule/curr/callback`, {
  34. "headers": { "content-type": "application/x-www-form-urlencoded; charset=UTF-8" },
  35. "method": "POST",
  36. "credentials": "include"
  37. });
  38. const data = await response.json();
  39. if (!data) throw new Error("服务器未返回任何数据");
  40. if (!data.dateList || !Array.isArray(data.dateList)) {
  41. console.error("教务返回数据异常:", data);
  42. throw new Error("未能获取到课程列表,请检查是否已登录或该学期是否有课");
  43. }
  44. // 从中解析出课程
  45. const courses = [];
  46. data.dateList.forEach(plan => {
  47. // 修正:确保 selectCourseList 存在且是数组
  48. if (plan && plan.selectCourseList && Array.isArray(plan.selectCourseList)) {
  49. plan.selectCourseList.forEach(c => {
  50. const teacher = (c.attendClassTeacher || "").replace(/\* /g, "").trim();
  51. if (c.timeAndPlaceList && Array.isArray(c.timeAndPlaceList)) {
  52. c.timeAndPlaceList.forEach(tp => {
  53. courses.push({
  54. name: c.courseName,
  55. teacher: teacher,
  56. position: (tp.teachingBuildingName || "") + (tp.classroomName || ""),
  57. day: tp.classDay,
  58. startSection: tp.classSessions,
  59. endSection: tp.classSessions + tp.continuingSession - 1,
  60. weeks: parseWeekString(tp.classWeek),
  61. isCustomTime: false
  62. });
  63. });
  64. }
  65. });
  66. }
  67. });
  68. if (courses.length === 0) {
  69. throw new Error("该学期暂无排课数据");
  70. }
  71. console.log('courses:', courses);
  72. return courses;
  73. }
  74. async function fetchTimeSections() {
  75. const response = await fetch("http://jwxtxs.tust.edu.cn:46110/ajax/getSectionAndTime", {
  76. "headers": { "content-type": "application/x-www-form-urlencoded; charset=UTF-8" },
  77. "method": "POST",
  78. "credentials": "include",
  79. "body": "planNumber=&ff=f"
  80. });
  81. const data = await response.json();
  82. if (!data) throw new Error("服务器未返回任何数据");
  83. if (!data.sectionTime || !Array.isArray(data.sectionTime)) {
  84. console.error("时间段数据异常:", data);
  85. throw new Error("未能获取到时间段数据,这不应该发生,请联系维护者");
  86. }
  87. // 解析时间段
  88. const timeSlots = (data.sectionTime || []).map((item, index) => ({
  89. number: index + 1,
  90. startTime: formatTime(item.startTime),
  91. endTime: formatTime(item.endTime),
  92. }));
  93. console.log('timeSlots:', timeSlots);
  94. return timeSlots;
  95. }
  96. /**
  97. * 网络请求和数据解析
  98. */
  99. async function fetchAndParseJwData() {
  100. try {
  101. window.shiguangBridge.showToast("正在获取教务数据...");
  102. const [courses, timeSlots] = await Promise.all([fetchCourses(), fetchTimeSections()]);
  103. return { courses, timeSlots };
  104. } catch (e) {
  105. window.shiguangBridge.showToast("同步失败: " + e.message);
  106. console.error(e);
  107. return null;
  108. }
  109. }
  110. /**
  111. * 保存数据到应用
  112. */
  113. async function saveToApp(result) {
  114. const courseSuccess = await window.shiguangBridgePromise.saveImportedCourses(JSON.stringify(result.courses));
  115. if (!courseSuccess) return false;
  116. await window.shiguangBridgePromise.savePresetTimeSlots(JSON.stringify(result.timeSlots));
  117. await window.shiguangBridgePromise.saveCourseConfig(JSON.stringify({
  118. semesterTotalWeeks: 20
  119. }));
  120. return true;
  121. }
  122. /**
  123. * 流程控制
  124. */
  125. async function runImportFlow() {
  126. // 公告
  127. const alertResult = await promptUserToStart();
  128. if (!alertResult) return;
  129. // 请求与解析
  130. const result = await fetchAndParseJwData();
  131. if (!result || result.courses.length === 0) return;
  132. // 保存并结束
  133. if (await saveToApp(result)) {
  134. window.shiguangBridge.showToast(`成功导入 ${result.courses.length} 个课程时段`);
  135. window.shiguangBridge.notifyTaskCompletion();
  136. }
  137. }
  138. // 启动
  139. runImportFlow();