Просмотр исходного кода

refactor: 优化 NWPU 适配脚本(dataId 提取 + 学期重选) (#414)

zengzoxiong 1 неделя назад
Родитель
Сommit
e3280fe3d4
1 измененных файлов с 78 добавлено и 48 удалено
  1. 78 48
      resources/NWPU/nwpu_01.js

+ 78 - 48
resources/NWPU/nwpu_01.js

@@ -1,7 +1,7 @@
 // 西北工业大学(NWPU) 拾光课程表适配脚本
 // 适配系统:EAMS 教务系统(jwxt.nwpu.edu.cn)
 // 适配范围:本科(BACHELOR_AND_ASSOCIATE)
-// 维护者:用户7227
+// 维护者:zengzoxiong
 
 /**
  * 将 HHmm 整数格式转换为 HH:mm 字符串
@@ -28,42 +28,57 @@ async function request(url) {
 }
 
 /**
- * 获取学生 ID
+ * 获取学生 ID(降级方案)
  * 调用 student-portrait API 获取当前登录学生的数据库 ID
  * @returns {Promise<number|null>} - 学生 ID
  */
-async function getStudentId() {
-    console.log("[NWPU] 正在获取学生 ID...");
+async function getStudentIdFallback() {
+    console.log("[NWPU] 降级方案:通过 API 获取学生 ID...");
     try {
         var data = await request("/student/for-std/student-portrait/getStdInfo?bizTypeAssoc=2&cultivateTypeAssoc=1");
         var json = JSON.parse(data);
         if (json && json.student && json.student.id) {
-            console.log("[NWPU] 学生 ID: " + json.student.id);
+            console.log("[NWPU] API 获取学生 ID: " + json.student.id);
             return json.student.id;
         }
         console.error("[NWPU] API 响应中未找到 student.id");
         return null;
     } catch (e) {
-        console.error("[NWPU] 获取学生 ID 失败: " + e.message);
+        console.error("[NWPU] API 获取学生 ID 失败: " + e.message);
         return null;
     }
 }
 
 /**
- * 获取学期列表
- * 请求课表页面 HTML,解析 #allSemesters 下拉框
- * @returns {Promise<Array<{id: number, name: string}>>} - 学期列表
+ * 获取学期列表和学生 ID
+ * 请求课表页面 HTML,解析 #allSemesters 下拉框和 dataId
+ * dataId 提取失败时降级调用 getStdInfo API
+ * @returns {Promise<{semesters: Array, studentId: number|null}>} - 学期列表和学生 ID
  */
-async function getSemesters() {
-    console.log("[NWPU] 正在获取学期列表...");
+async function getSemestersAndStudentId() {
+    console.log("[NWPU] 正在获取学期列表和学生 ID...");
     try {
         var html = await request("/student/for-std/course-table");
+
+        // 优先从 HTML 提取 dataId
+        var dataIdMatch = html.match(/var\s+dataId\s*=\s*(\d+)/);
+        var studentId = dataIdMatch ? parseInt(dataIdMatch[1]) : null;
+
+        if (studentId) {
+            console.log("[NWPU] 从页面提取 dataId: " + studentId);
+        } else {
+            // 降级:调用 API 获取
+            console.log("[NWPU] 页面未找到 dataId,降级调用 API...");
+            studentId = await getStudentIdFallback();
+        }
+
+        // 解析学期列表
         var parser = new DOMParser();
         var doc = parser.parseFromString(html, "text/html");
         var select = doc.querySelector("#allSemesters");
         if (!select) {
             console.error("[NWPU] 未找到 #allSemesters 元素");
-            return [];
+            return { semesters: [], studentId: studentId };
         }
         var options = select.querySelectorAll("option");
         var semesters = [];
@@ -76,10 +91,10 @@ async function getSemesters() {
             }
         }
         console.log("[NWPU] 获取到 " + semesters.length + " 个学期");
-        return semesters;
+        return { semesters: semesters, studentId: studentId };
     } catch (e) {
         console.error("[NWPU] 获取学期列表失败: " + e.message);
-        return [];
+        return { semesters: [], studentId: null };
     }
 }
 
@@ -334,10 +349,10 @@ async function runImportFlow() {
             return;
         }
 
-        // 2. 获取学生 ID
-        AndroidBridge.showToast("正在获取学生信息...");
-        var studentId = await getStudentId();
-        if (!studentId) {
+        // 2. 获取学期列表和学生 ID(从同一页面提取)
+        AndroidBridge.showToast("正在获取学期列表...");
+        var pageData = await getSemestersAndStudentId();
+        if (!pageData.studentId) {
             await window.AndroidBridgePromise.showAlert(
                 "导入失败",
                 "未能获取学生 ID,请确认您已登录教务系统。",
@@ -345,11 +360,7 @@ async function runImportFlow() {
             );
             return;
         }
-
-        // 3. 获取学期列表
-        AndroidBridge.showToast("正在获取学期列表...");
-        var semesters = await getSemesters();
-        if (semesters.length === 0) {
+        if (pageData.semesters.length === 0) {
             await window.AndroidBridgePromise.showAlert(
                 "导入失败",
                 "未能获取学期列表,请刷新页面后重试。",
@@ -357,51 +368,70 @@ async function runImportFlow() {
             );
             return;
         }
+        var semesters = pageData.semesters;
+        var studentId = pageData.studentId;
 
-        // 4. 用户选择学期
+        // 3. 用户选择学期(支持重选)
         var semesterNames = [];
         for (var i = 0; i < semesters.length; i++) {
             semesterNames.push(semesters[i].name);
         }
-        var selectedIndex = await window.AndroidBridgePromise.showSingleSelection(
-            "选择学期",
-            JSON.stringify(semesterNames),
-            0
-        );
-        if (selectedIndex === null || selectedIndex < 0 || selectedIndex >= semesters.length) {
-            AndroidBridge.showToast("导入已取消");
-            return;
-        }
-        var selectedSemester = semesters[selectedIndex];
-        console.log("[NWPU] 选择学期: " + selectedSemester.name + " (ID: " + selectedSemester.id + ")");
 
-        // 5. 获取课程数据
-        var apiData = await getCourseData(selectedSemester.id, studentId);
-        if (!apiData) return;
+        var activities = null;
+        var selectedSemester = null;
 
-        var tableVm = apiData.studentTableVm;
-        if (!tableVm || !tableVm.activities || tableVm.activities.length === 0) {
-            AndroidBridge.showToast("该学期没有课程数据");
-            return;
+        while (true) {
+            var selectedIndex = await window.AndroidBridgePromise.showSingleSelection(
+                "选择学期",
+                JSON.stringify(semesterNames),
+                0
+            );
+            if (selectedIndex === null || selectedIndex < 0 || selectedIndex >= semesters.length) {
+                AndroidBridge.showToast("导入已取消");
+                return;
+            }
+            selectedSemester = semesters[selectedIndex];
+            console.log("[NWPU] 选择学期: " + selectedSemester.name + " (ID: " + selectedSemester.id + ")");
+
+            // 4. 获取课程数据
+            var apiData = await getCourseData(selectedSemester.id, studentId);
+            if (!apiData) return;
+
+            var tableVm = apiData.studentTableVm;
+            if (tableVm && tableVm.activities && tableVm.activities.length > 0) {
+                activities = tableVm.activities;
+                break;
+            }
+
+            // 无数据,弹窗提示后重新选择
+            var retry = await window.AndroidBridgePromise.showAlert(
+                "无课程数据",
+                "「" + selectedSemester.name + "」没有课程数据,请选择其他学期。",
+                "重新选择"
+            );
+            if (!retry) {
+                AndroidBridge.showToast("导入已取消");
+                return;
+            }
         }
-        var activities = tableVm.activities;
+
         console.log("[NWPU] 获取到 " + activities.length + " 条课程活动");
 
-        // 6. 获取学期信息(开始日期、结束日期)
+        // 5. 获取学期信息(开始日期、结束日期)
         AndroidBridge.showToast("正在获取学期信息...");
         var semesterInfo = await getSemesterInfo(selectedSemester.id);
         console.log("[NWPU] 学期开始: " + (semesterInfo.startDate || "未知") + ", 结束: " + (semesterInfo.endDate || "未知"));
 
-        // 7. 提取时间段
+        // 6. 提取时间段
         var timeSlots = extractTimeSlots(apiData);
 
-        // 8. 提取课表配置
+        // 7. 提取课表配置
         var courseConfig = extractCourseConfig(semesterInfo, activities);
 
-        // 9. 转换课程数据
+        // 8. 转换课程数据
         var courses = convertCourses(activities);
 
-        // 10. 三步导入:时间段 → 配置 → 课程
+        // 9. 三步导入:时间段 → 配置 → 课程
         var timeSlotResult = await saveTimeSlots(timeSlots);
         if (!timeSlotResult) return;