|
|
@@ -1,5 +1,5 @@
|
|
|
async function runImportFlow() {
|
|
|
- // 兼容电脑端测试:如果在电脑浏览器里跑,模拟手机软件的弹窗和保存功能
|
|
|
+ // 兼容电脑端测试
|
|
|
if (typeof window.AndroidBridgePromise === 'undefined') {
|
|
|
window.AndroidBridgePromise = {
|
|
|
showAlert: async () => true,
|
|
|
@@ -20,14 +20,12 @@ async function runImportFlow() {
|
|
|
|
|
|
AndroidBridge.showToast("开始提取课表数据...");
|
|
|
|
|
|
- // 1. 定位课表所在的表格 (强智系统常见的表格ID是 kbtable)
|
|
|
const table = document.getElementById('kbtable') || document.querySelector('.table_border') || document.querySelector('table');
|
|
|
if (!table || !table.innerText.includes('星期')) {
|
|
|
AndroidBridge.showToast("没找到课表!请确保您当前在“学期理论课表”页面。");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 2. 弹窗与用户确认
|
|
|
const alertConfirmed = await window.AndroidBridgePromise.showAlert(
|
|
|
"强智教务解析",
|
|
|
"已检测到课表页面,是否提取数据并导入?",
|
|
|
@@ -37,74 +35,47 @@ async function runImportFlow() {
|
|
|
|
|
|
try {
|
|
|
let courses = [];
|
|
|
- let courseSet = new Set(); // 用来防止课程重复添加
|
|
|
+ let courseSet = new Set();
|
|
|
let rows = table.querySelectorAll('tr');
|
|
|
-
|
|
|
- // 匹配表头,确定每一列对应星期几
|
|
|
- let headerRow = rows[0];
|
|
|
- let dayMapping = {};
|
|
|
- let ths = headerRow.querySelectorAll('th, td');
|
|
|
- for (let i = 0; i < ths.length; i++) {
|
|
|
- let text = ths[i].innerText;
|
|
|
- if (text.includes('一')) dayMapping[i] = 1;
|
|
|
- else if (text.includes('二')) dayMapping[i] = 2;
|
|
|
- else if (text.includes('三')) dayMapping[i] = 3;
|
|
|
- else if (text.includes('四')) dayMapping[i] = 4;
|
|
|
- else if (text.includes('五')) dayMapping[i] = 5;
|
|
|
- else if (text.includes('六')) dayMapping[i] = 6;
|
|
|
- else if (text.includes('日')) dayMapping[i] = 7;
|
|
|
- }
|
|
|
|
|
|
// 遍历课表每一行(跳过第一行的表头)
|
|
|
for (let i = 1; i < rows.length; i++) {
|
|
|
- let cells = rows[i].querySelectorAll('td');
|
|
|
+ // 【关键修复1】同时获取 th 和 td,防止错位
|
|
|
+ let cells = rows[i].querySelectorAll('td, th');
|
|
|
+
|
|
|
for (let j = 0; j < cells.length; j++) {
|
|
|
let cell = cells[j];
|
|
|
- let day = dayMapping[j];
|
|
|
- if (!day) continue; // 如果这列不是星期几(比如是左侧的“第一节”栏),就跳过
|
|
|
-
|
|
|
- // 提取单元格内的文字块(处理同一时间有两门课的情况)
|
|
|
- let blocks = [];
|
|
|
- let kbNodes = cell.querySelectorAll('.kbcontent');
|
|
|
- if (kbNodes.length > 0) {
|
|
|
- kbNodes.forEach(n => {
|
|
|
- if(n.innerText.trim()) blocks.push(n.innerText.trim());
|
|
|
- });
|
|
|
- } else {
|
|
|
- // 如果没有 class 为 kbcontent 的块,就靠 "-------" 分割线来切分
|
|
|
- blocks = cell.innerText.split(/-{5,}/).map(t => t.trim()).filter(t => t);
|
|
|
- }
|
|
|
+
|
|
|
+ // 【关键修复2】逆向计算星期几:倒数第7列永远是周一,倒数第1列永远是周日
|
|
|
+ // 这能完美解决强智系统左侧节次列导致的数据错位问题
|
|
|
+ let day = 7 - (cells.length - 1 - j);
|
|
|
+ if (day < 1 || day > 7) continue; // 如果算出来不是1-7,说明是左侧的节次列,跳过
|
|
|
+
|
|
|
+ let blocks = cell.innerText.split(/-{5,}/).map(t => t.trim()).filter(t => t);
|
|
|
|
|
|
for (let block of blocks) {
|
|
|
- if (!block || block === ' ') continue;
|
|
|
+ if (!block || block === ' ' || block === '') continue;
|
|
|
|
|
|
- // 将一门课的文字按行打散(课程名、老师、周次、地点通常是换行或空格隔开的)
|
|
|
let lines = block.split(/\n/).map(l => l.trim()).filter(l => l);
|
|
|
if(lines.length < 4) {
|
|
|
lines = block.split(/\s+/).map(l => l.trim()).filter(l => l);
|
|
|
}
|
|
|
if (lines.length < 3) continue;
|
|
|
|
|
|
- // 1. 提取课程名 (去掉后面的 [32][必修] 等字眼)
|
|
|
let name = lines[0].replace(/\[.*?\]/g, '').trim();
|
|
|
-
|
|
|
- // 2. 提取老师
|
|
|
let teacher = lines[1] || "未知";
|
|
|
|
|
|
- // 3. 找时间规则行,例如 "14-15(全部)[01-02-03-04节]"
|
|
|
let timeRegex = /([\d\-,]+)(?:\((单|双|.*?)\))?.*?\[([\d\-]+)节\]/;
|
|
|
let timeLineIdx = lines.findIndex(l => timeRegex.test(l));
|
|
|
if (timeLineIdx === -1) continue;
|
|
|
|
|
|
let match = lines[timeLineIdx].match(timeRegex);
|
|
|
- let weeksStr = match[1]; // 提取周数部分:14-15
|
|
|
- let oddEven = match[2]; // 提取单双周:单 / 双
|
|
|
- let sectionsStr = match[3]; // 提取节次部分:01-02-03-04
|
|
|
+ let weeksStr = match[1];
|
|
|
+ let oddEven = match[2];
|
|
|
+ let sectionsStr = match[3];
|
|
|
|
|
|
- // 4. 提取上课地点 (通常在时间行的下一行)
|
|
|
let position = (timeLineIdx + 1 < lines.length) ? lines[timeLineIdx + 1] : "未知地点";
|
|
|
|
|
|
- // 将 "1-4,6" 转换成具体的 [1,2,3,4,6] 数组
|
|
|
let weeks = [];
|
|
|
let weekParts = weeksStr.split(',');
|
|
|
for (let wp of weekParts) {
|
|
|
@@ -122,12 +93,10 @@ async function runImportFlow() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 将 "01-02-03-04" 转换成开始和结束节次
|
|
|
let secParts = sectionsStr.split('-');
|
|
|
let startSection = parseInt(secParts[0]);
|
|
|
let endSection = parseInt(secParts[secParts.length - 1]);
|
|
|
|
|
|
- // 去重:强智系统一节大课会占据好几行,生成唯一ID防止重复添加同一门课
|
|
|
let uid = `${name}-${day}-${startSection}-${endSection}-${weeks.join(',')}`;
|
|
|
if (!courseSet.has(uid)) {
|
|
|
courseSet.add(uid);
|
|
|
@@ -152,12 +121,11 @@ async function runImportFlow() {
|
|
|
|
|
|
AndroidBridge.showToast(`提取成功,共发现 ${courses.length} 门课程,正在保存...`);
|
|
|
|
|
|
- // 3. 将数据提交给轻屿课表APP
|
|
|
const saveResult = await window.AndroidBridgePromise.saveImportedCourses(JSON.stringify(courses));
|
|
|
|
|
|
if (saveResult) {
|
|
|
AndroidBridge.showToast("导入大功告成!");
|
|
|
- AndroidBridge.notifyTaskCompletion(); // 通知APP关掉网页
|
|
|
+ AndroidBridge.notifyTaskCompletion();
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
@@ -166,5 +134,4 @@ async function runImportFlow() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 执行上面的全套流程
|
|
|
runImportFlow();
|