tsu_01.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. function parseWeeks(weekStr) {
  2. const weeks = [];
  3. weekStr.split(',').forEach(part => {
  4. if (part.includes('-')) {
  5. const [start, end] = part.split('-').map(Number);
  6. for (let i = start; i <= end; i++) weeks.push(i);
  7. } else {
  8. const w = parseInt(part);
  9. if (!isNaN(w)) weeks.push(w);
  10. }
  11. });
  12. return weeks;
  13. }
  14. function findTable(win) {
  15. const t = Array.from(win.document.querySelectorAll('table'))
  16. .find(x => x.innerText.includes("星期一") && x.innerText.includes("["));
  17. if (t) return t;
  18. for (let i = 0; i < win.frames.length; i++) {
  19. try {
  20. const st = findTable(win.frames[i]);
  21. if (st) return st;
  22. } catch (e) {}
  23. }
  24. return null;
  25. }
  26. async function fetchAndParseCourses() {
  27. const table = findTable(window);
  28. if (!table) {
  29. throw new Error("未检测到课表数据,请确保已切换到显示课表的页面!");
  30. }
  31. const rawItems = [];
  32. Array.from(table.rows).forEach(row => {
  33. const cells = Array.from(row.cells);
  34. if (cells.length < 7) return;
  35. cells.forEach((cell, colIndex) => {
  36. const distanceToLast = cells.length - 1 - colIndex;
  37. if (distanceToLast > 6) return;
  38. const day = 7 - distanceToLast;
  39. const rawText = cell.innerText.trim();
  40. if (!rawText.includes('[')) return;
  41. const lines = rawText.split('\n').map(l => l.trim()).filter(l => l);
  42. lines.forEach((line, i) => {
  43. const match = line.match(/([\d\-,]+)\[(\d+)-(\d+)\]/);
  44. if (match) {
  45. let name = "未知课程";
  46. if (i >= 2) name = lines[i-2];
  47. else if (i >= 1) name = lines[i-1];
  48. let teacher = (i >= 1 && !lines[i-1].includes('[')) ? lines[i-1] : "未知教师";
  49. let position = (i < lines.length - 1) ? lines[i+1] : "未知地点";
  50. rawItems.push({
  51. name: name.replace(/\s/g, ""),
  52. teacher: teacher.replace(/\s/g, ""),
  53. position: position.replace(/\s/g, ""),
  54. day: day,
  55. startSection: parseInt(match[2]),
  56. endSection: parseInt(match[3]),
  57. weeks: parseWeeks(match[1])
  58. });
  59. }
  60. });
  61. });
  62. });
  63. const groupMap = new Map();
  64. rawItems.forEach(item => {
  65. const key = `${item.name}|${item.teacher}|${item.position}|${item.day}`;
  66. if (!groupMap.has(key)) groupMap.set(key, {});
  67. const weekMap = groupMap.get(key);
  68. item.weeks.forEach(w => {
  69. if (!weekMap[w]) weekMap[w] = new Set();
  70. for (let s = item.startSection; s <= item.endSection; s++) {
  71. weekMap[w].add(s);
  72. }
  73. });
  74. });
  75. const finalCourses = [];
  76. groupMap.forEach((weekMap, key) => {
  77. const [name, teacher, position, day] = key.split('|');
  78. const patternMap = new Map();
  79. Object.keys(weekMap).forEach(w => {
  80. const week = parseInt(w);
  81. const sections = Array.from(weekMap[week]).sort((a, b) => a - b);
  82. if (sections.length === 0) return;
  83. let start = sections[0];
  84. for (let i = 0; i < sections.length; i++) {
  85. if (i === sections.length - 1 || sections[i+1] !== sections[i] + 1) {
  86. const pKey = `${start}-${sections[i]}`;
  87. if (!patternMap.has(pKey)) patternMap.set(pKey, []);
  88. patternMap.get(pKey).push(week);
  89. if (i < sections.length - 1) start = sections[i+1];
  90. }
  91. }
  92. });
  93. patternMap.forEach((weeks, pKey) => {
  94. const [sStart, sEnd] = pKey.split('-').map(Number);
  95. finalCourses.push({
  96. name, teacher, position,
  97. day: parseInt(day),
  98. startSection: sStart,
  99. endSection: sEnd,
  100. weeks: weeks.sort((a, b) => a - b)
  101. });
  102. });
  103. });
  104. return finalCourses;
  105. }
  106. async function runImportFlow() {
  107. try {
  108. AndroidBridge.showToast("泰山学院引擎启动,抓取数据中...");
  109. const courses = await fetchAndParseCourses();
  110. if (!courses || courses.length === 0) {
  111. AndroidBridge.showToast("解析完成,但当前课表为空");
  112. AndroidBridge.notifyTaskCompletion();
  113. return;
  114. }
  115. const saveResult = await window.AndroidBridgePromise.saveImportedCourses(JSON.stringify(courses));
  116. if (saveResult === true) {
  117. AndroidBridge.showToast(`导入大成功!合并生成 ${courses.length} 个课块`);
  118. AndroidBridge.notifyTaskCompletion();
  119. }
  120. } catch (error) {
  121. AndroidBridge.showToast("⚠️ " + error.message);
  122. AndroidBridge.notifyTaskCompletion();
  123. }
  124. }
  125. runImportFlow();