imnc_01.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /**
  2. * 呼和浩特民族学院 (IMNC) 课表解析脚本
  3. * 放置于测试目录用于真机测试
  4. */
  5. // 周次解析函数
  6. function parseWeeks(weekStr) {
  7. let weeks = [];
  8. if (!weekStr) return weeks;
  9. let isSingle = weekStr.includes('单');
  10. let isDouble = weekStr.includes('双');
  11. // 匹配 "1-16", "第1-9周"
  12. let match = weekStr.match(/(\d+)-(\d+)/);
  13. if (match) {
  14. let start = parseInt(match[1]);
  15. let end = parseInt(match[2]);
  16. for (let i = start; i <= end; i++) {
  17. if (isSingle && i % 2 === 0) continue;
  18. if (isDouble && i % 2 !== 0) continue;
  19. weeks.push(i);
  20. }
  21. } else {
  22. // 匹配 "第13周"
  23. let singleMatch = weekStr.match(/(\d+)/);
  24. if (singleMatch) {
  25. weeks.push(parseInt(singleMatch[1]));
  26. }
  27. }
  28. return weeks;
  29. }
  30. // 核心解析函数
  31. function fetchAndParseCourses() {
  32. let courses = [];
  33. let table = document.querySelector('#timetable');
  34. if (!table) return null;
  35. let rows = table.querySelectorAll('tr');
  36. // 第 0 行是表头,从第 1 行开始遍历节次
  37. for (let i = 1; i < rows.length; i++) {
  38. let row = rows[i];
  39. let cells = row.querySelectorAll('td');
  40. let section = i; // 1 到 13 节
  41. for (let j = 0; j < cells.length; j++) {
  42. let cell = cells[j];
  43. let day = j + 1; // 星期 1 到 7
  44. let html = cell.innerHTML.trim();
  45. if (!html || html === '&nbsp;') continue;
  46. // 按 <br> 分割
  47. let parts = html.split(/<br\s*\/?>/i).map(s => s.trim()).filter(s => s !== '');
  48. // 每 5 个元素代表一个完整的课程块
  49. for (let k = 0; k < parts.length; k += 5) {
  50. if (k + 3 >= parts.length) break;
  51. let namePart = parts[k];
  52. let position = parts[k+1];
  53. let teacher = parts[k+2];
  54. let weekStr = parts[k+3];
  55. // parts[k+4] 是 "讲授" 等类型,暂时不需要存入
  56. // 提取书名号内的课程名
  57. let nameMatch = namePart.match(/&lt;&lt;(.*?)&gt;&gt;/);
  58. let name = nameMatch ? nameMatch[1] : namePart;
  59. // 兼容某些浏览器可能将转义符还原的情况
  60. if (!nameMatch) {
  61. let nameMatch2 = namePart.match(/<<(.*?)>>/);
  62. if (nameMatch2) name = nameMatch2[1];
  63. }
  64. let weeks = parseWeeks(weekStr);
  65. // 查找同一天、同名、同老师、同地点、同周次,且正好是上一节的课程(合并连上的课)
  66. let existingCourse = courses.find(c =>
  67. c.name === name &&
  68. c.day === day &&
  69. c.teacher === teacher &&
  70. c.position === position &&
  71. JSON.stringify(c.weeks) === JSON.stringify(weeks) &&
  72. c.endSection === section - 1
  73. );
  74. if (existingCourse) {
  75. existingCourse.endSection = section;
  76. } else {
  77. courses.push({
  78. name: name,
  79. teacher: teacher,
  80. position: position,
  81. day: day,
  82. startSection: section,
  83. endSection: section,
  84. weeks: weeks
  85. });
  86. }
  87. }
  88. }
  89. }
  90. return courses;
  91. }
  92. // 调度流程
  93. async function runImportFlow() {
  94. try {
  95. AndroidBridge.showToast("开始解析课表...");
  96. const alertConfirmed = await window.AndroidBridgePromise.showAlert(
  97. "导入确认",
  98. "请确保您目前处于教务系统的“学生课表”显示页面。\n是否立即提取并导入课表?",
  99. "开始提取"
  100. );
  101. if (!alertConfirmed) {
  102. AndroidBridge.showToast("导入已取消");
  103. return;
  104. }
  105. let courses = fetchAndParseCourses();
  106. if (!courses || courses.length === 0) {
  107. await window.AndroidBridgePromise.showAlert("错误", "未在当前页面找到课表数据,请确认是否处于课表页面,或联系适配开发者。", "好的");
  108. return;
  109. }
  110. await window.AndroidBridgePromise.saveImportedCourses(JSON.stringify(courses));
  111. AndroidBridge.showToast(`成功导入 ${courses.length} 门课程块!`);
  112. AndroidBridge.notifyTaskCompletion();
  113. } catch (error) {
  114. AndroidBridge.showToast("导入发生错误: " + error.message);
  115. }
  116. }
  117. // 启动执行
  118. runImportFlow();