gdit.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // 文件: gdit.js
  2. // 广东科学技术职业学院 课程表导入适配脚本
  3. if (typeof Strings === 'undefined') {
  4. var Strings = {
  5. BASE_URL: "https://wbdt.gdit.edu.cn",
  6. GET_STUDENT_SCHEDULE_URL: "front/extraCard/queryStudentSchedule"
  7. };
  8. }
  9. async function stepDescriptionAlert() {
  10. try {
  11. const confirmed = await window.shiguangBridgePromise.showAlert(
  12. "提示",
  13. "即将执行导入课程操作。请确保你已处于登录状态,并已打开课程表页面。",
  14. "确认"
  15. );
  16. return confirmed;
  17. } catch (error) {
  18. console.error("显示弹窗时发生错误:", error);
  19. return false;
  20. }
  21. }
  22. async function selectSemesterSelection() {
  23. const now = new Date();
  24. const currentYear = now.getFullYear();
  25. const currentMonth = now.getMonth() + 1;
  26. const currentSemester = currentMonth >= 9 || currentMonth <= 2 ? 1 : 2;
  27. const presetSemesters = [];
  28. const presetSemestersName = [];
  29. for (let year = currentYear; year >= currentYear - 3; year--) {
  30. for (let semester = (year === currentYear ? currentSemester : 2); semester >= 1; semester--) {
  31. const semesterName = `${year}-${year + 1}学年 第${semester}学期`;
  32. presetSemesters.push({
  33. name: semesterName,
  34. schoolYear: `${year}-${year + 1}`,
  35. semester: String(semester)
  36. });
  37. presetSemestersName.push(semesterName);
  38. }
  39. }
  40. try {
  41. const selectedIndex = await window.shiguangBridgePromise.showSingleSelection(
  42. "选择要导入的学期",
  43. JSON.stringify(presetSemestersName),
  44. 0
  45. );
  46. if (selectedIndex !== null && selectedIndex >= 0 && selectedIndex < presetSemesters.length) {
  47. const selected = presetSemesters[selectedIndex];
  48. console.log("用户选择了: " + selected.name);
  49. return selected;
  50. } else {
  51. console.log("用户取消了选择。");
  52. return null;
  53. }
  54. } catch (error) {
  55. console.error("显示单选列表弹窗时发生错误:", error);
  56. window.shiguangBridge.showToast("显示列表出错!" + error.message);
  57. return null;
  58. }
  59. }
  60. async function fetchCourses(schoolYear, semester) {
  61. try {
  62. console.log(`正在获取 ${schoolYear} 第${semester}学期 的课程数据...`);
  63. const timestamp = Date.now();
  64. const url = `${Strings.BASE_URL}/${Strings.GET_STUDENT_SCHEDULE_URL}?_t=${timestamp}&semester=${semester}&schoolYear=${schoolYear}`;
  65. const response = await fetch(url, {
  66. method: 'GET',
  67. headers: {
  68. 'Content-Type': 'application/json'
  69. },
  70. credentials: 'include'
  71. });
  72. if (!response.ok) {
  73. throw new Error(`请求失败: ${response.status}`);
  74. }
  75. const result = await response.json();
  76. console.log("API 返回数据:", result);
  77. if (!result.meta || !result.meta.success) {
  78. throw new Error(result.meta ? result.meta.message : "请求失败");
  79. }
  80. if (!result.data || !Array.isArray(result.data) || result.data.length === 0) {
  81. throw new Error("该学期没有课程数据");
  82. }
  83. const courses = parseCourses(result.data);
  84. return courses;
  85. } catch (error) {
  86. console.error('获取课程数据失败:', error);
  87. window.shiguangBridge.showToast("获取课程失败: " + error.message);
  88. return null;
  89. }
  90. }
  91. function parseCourses(rawCourses) {
  92. console.log(`正在解析课程数据,共 ${rawCourses.length} 条原始记录...`);
  93. const courses = [];
  94. for (const raw of rawCourses) {
  95. try {
  96. const name = raw.courseName || "";
  97. const teacher = raw.userName || "";
  98. const position = raw.placeName || "";
  99. const day = Number(raw.weekDay);
  100. if (isNaN(day) || day < 1 || day > 7) continue;
  101. const sectionStr = raw.festivals || "";
  102. const sectionMatch = sectionStr.match(/(\d+)-(\d+)/);
  103. if (!sectionMatch) continue;
  104. const startSection = Number(sectionMatch[1]);
  105. const endSection = Number(sectionMatch[2]);
  106. const startWeek = Number(raw.startWeek);
  107. const endWeek = Number(raw.endWeek);
  108. if (isNaN(startWeek) || isNaN(endWeek)) continue;
  109. const singleDoubleWeek = raw.singleDoubleWeek || "0";
  110. const weeks = [];
  111. for (let w = startWeek; w <= endWeek; w++) {
  112. if (singleDoubleWeek === "1" && w % 2 === 0) continue;
  113. if (singleDoubleWeek === "2" && w % 2 !== 0) continue;
  114. weeks.push(w);
  115. }
  116. if (name && weeks.length > 0) {
  117. courses.push({
  118. name: name.trim(),
  119. teacher: teacher.trim(),
  120. position: position.trim(),
  121. day: day,
  122. startSection: startSection,
  123. endSection: endSection,
  124. weeks: weeks,
  125. isCustomTime: false
  126. });
  127. }
  128. } catch (e) {
  129. console.warn("解析单条课程数据失败:", e, raw);
  130. }
  131. }
  132. console.log(`成功解析 ${courses.length} 门课程`);
  133. return courses;
  134. }
  135. async function saveCourses(courses) {
  136. try {
  137. console.log("正在尝试导入课程...");
  138. const result = await window.shiguangBridgePromise.saveImportedCourses(JSON.stringify(courses));
  139. if (result === true) {
  140. console.log("课程导入成功!");
  141. } else {
  142. console.log("课程导入未成功,结果:" + result);
  143. window.shiguangBridge.showToast("课程导入失败,请查看日志。");
  144. }
  145. } catch (error) {
  146. console.error("导入课程时发生错误:", error);
  147. window.shiguangBridge.showToast("导入课程失败: " + error.message);
  148. }
  149. }
  150. async function setPresetTimeSlots() {
  151. const presetTimeSlots = [
  152. { "number": 1, "startTime": "08:10", "endTime": "08:55" },
  153. { "number": 2, "startTime": "09:05", "endTime": "09:50" },
  154. { "number": 3, "startTime": "10:10", "endTime": "10:55" },
  155. { "number": 4, "startTime": "11:05", "endTime": "11:50" },
  156. { "number": 5, "startTime": "14:30", "endTime": "15:15" },
  157. { "number": 6, "startTime": "15:25", "endTime": "16:10" },
  158. { "number": 7, "startTime": "16:30", "endTime": "17:15" },
  159. { "number": 8, "startTime": "17:25", "endTime": "18:10" },
  160. { "number": 9, "startTime": "19:10", "endTime": "19:55" },
  161. { "number": 10, "startTime": "20:05", "endTime": "20:50" },
  162. { "number": 11, "startTime": "21:00", "endTime": "21:45" }
  163. ];
  164. try {
  165. console.log("正在尝试导入预设时间段...");
  166. const result = await window.shiguangBridgePromise.savePresetTimeSlots(JSON.stringify(presetTimeSlots));
  167. if (result === true) {
  168. console.log("预设时间段导入成功!");
  169. } else {
  170. console.log("预设时间段导入未成功,结果:" + result);
  171. }
  172. } catch (error) {
  173. console.error("导入时间段时发生错误:", error);
  174. }
  175. }
  176. async function runImportFlow() {
  177. const confirmed = await stepDescriptionAlert();
  178. if (!confirmed) {
  179. console.log("用户取消了操作。");
  180. return;
  181. }
  182. const semester = await selectSemesterSelection();
  183. if (!semester) {
  184. console.log("用户取消了学期选择。");
  185. return;
  186. }
  187. const courses = await fetchCourses(semester.schoolYear, semester.semester);
  188. if (!courses || courses.length === 0) {
  189. window.shiguangBridge.showToast("未找到课程数据,请确认选择了正确的学期");
  190. return;
  191. }
  192. await saveCourses(courses);
  193. await setPresetTimeSlots();
  194. window.shiguangBridge.showToast(`成功导入 ${courses.length} 门课程!`);
  195. window.shiguangBridge.notifyTaskCompletion();
  196. }
  197. runImportFlow();