urp_01.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // 通用 URP 教务拾光课程表适配脚本
  2. /**
  3. * 解析位图格式的周次 (011100...)
  4. */
  5. function parseWeekString(weekStr) {
  6. let weeks = [];
  7. if (!weekStr) return weeks;
  8. for (let i = 0; i < weekStr.length; i++) {
  9. if (weekStr[i] === '1') weeks.push(i + 1);
  10. }
  11. return weeks;
  12. }
  13. /**
  14. * 格式化时间 (0800 -> 08:00)
  15. */
  16. function formatTime(timeStr) {
  17. if (timeStr && timeStr.length === 4) {
  18. return timeStr.substring(0, 2) + ":" + timeStr.substring(2);
  19. }
  20. return timeStr;
  21. }
  22. /**
  23. * 动态获取 API 路径
  24. */
  25. function getApiUrl() {
  26. const baseUrl = window.location.origin;
  27. return `${baseUrl}/student/courseSelect/thisSemesterCurriculum/ajaxStudentSchedule/callback`;
  28. }
  29. async function promptUserToStart() {
  30. return await window.AndroidBridgePromise.showAlert(
  31. "教务系统课表导入",
  32. "请确保您已进入教务系统课表查询页面后再开始导入",
  33. "好的,开始导入"
  34. );
  35. }
  36. /**
  37. * 网络请求和数据解析
  38. */
  39. async function fetchAndParseJwData() {
  40. try {
  41. const apiUrl = getApiUrl();
  42. console.log("正在通过动态地址获取教务数据:", apiUrl);
  43. AndroidBridge.showToast("正在获取教务数据...");
  44. const response = await fetch(apiUrl, {
  45. "headers": { "content-type": "application/x-www-form-urlencoded; charset=UTF-8" },
  46. "method": "POST",
  47. "credentials": "include"
  48. });
  49. const data = await response.json();
  50. if (!data) throw new Error("服务器未返回任何数据");
  51. // 严格遵循 dateList 结构解析
  52. if (!data.dateList || !Array.isArray(data.dateList)) {
  53. console.error("教务返回数据异常:", data);
  54. throw new Error("未能获取到课程列表,请确认是否已登录或页面正确");
  55. }
  56. // 解析时间段 (jcsjbs)
  57. const timeSlots = (data.jcsjbs || []).map(item => ({
  58. number: parseInt(item.jc),
  59. startTime: formatTime(item.kssj),
  60. endTime: formatTime(item.jssj)
  61. }));
  62. // 解析课程
  63. let courses = [];
  64. data.dateList.forEach(plan => {
  65. if (plan && plan.selectCourseList && Array.isArray(plan.selectCourseList)) {
  66. plan.selectCourseList.forEach(c => {
  67. const teacher = (c.attendClassTeacher || "").replace(/\* /g, "").trim();
  68. if (c.timeAndPlaceList && Array.isArray(c.timeAndPlaceList)) {
  69. c.timeAndPlaceList.forEach(tp => {
  70. courses.push({
  71. name: c.courseName,
  72. teacher: teacher,
  73. position: (tp.teachingBuildingName || "") + (tp.classroomName || ""),
  74. day: parseInt(tp.classDay),
  75. startSection: parseInt(tp.classSessions),
  76. endSection: parseInt(tp.classSessions) + parseInt(tp.continuingSession) - 1,
  77. weeks: parseWeekString(tp.classWeek)
  78. });
  79. });
  80. }
  81. });
  82. }
  83. });
  84. if (courses.length === 0) {
  85. throw new Error("该学期暂无排课数据");
  86. }
  87. return { courses, timeSlots };
  88. } catch (e) {
  89. console.error("解析失败详情:", e);
  90. AndroidBridge.showToast("同步失败: " + e.message);
  91. return null;
  92. }
  93. }
  94. /**
  95. * 保存数据到应用
  96. */
  97. async function saveToApp(result) {
  98. const courseSuccess = await window.AndroidBridgePromise.saveImportedCourses(JSON.stringify(result.courses));
  99. if (!courseSuccess) return false;
  100. if (result.timeSlots && result.timeSlots.length > 0) {
  101. await window.AndroidBridgePromise.savePresetTimeSlots(JSON.stringify(result.timeSlots));
  102. }
  103. await window.AndroidBridgePromise.saveCourseConfig(JSON.stringify({
  104. semesterTotalWeeks: 20
  105. }));
  106. return true;
  107. }
  108. /**
  109. * 流程控制
  110. */
  111. async function runImportFlow() {
  112. const alertResult = await promptUserToStart();
  113. if (!alertResult) return;
  114. const result = await fetchAndParseJwData();
  115. if (!result || result.courses.length === 0) return;
  116. if (await saveToApp(result)) {
  117. AndroidBridge.showToast(`成功导入 ${result.courses.length} 个课程时段`);
  118. AndroidBridge.notifyTaskCompletion();
  119. }
  120. }
  121. // 启动
  122. runImportFlow();