|
@@ -119,11 +119,16 @@ function parseTimetableToModel(htmlString) {
|
|
|
const tempDiv = document.createElement('div');
|
|
const tempDiv = document.createElement('div');
|
|
|
tempDiv.innerHTML = block;
|
|
tempDiv.innerHTML = block;
|
|
|
|
|
|
|
|
- // 1. 提取课程名(包含所有文本,包括实验标记)
|
|
|
|
|
|
|
+ // 1. 提取课程名(跳过开头的空行,处理 <br> 开头的分隔块)
|
|
|
let name = "";
|
|
let name = "";
|
|
|
- const firstLine = tempDiv.innerHTML.split('<br>')[0].trim();
|
|
|
|
|
- // 移除HTML标签,保留文本内容
|
|
|
|
|
- name = firstLine.replace(/<[^>]*>/g, '').trim();
|
|
|
|
|
|
|
+ const htmlLines = tempDiv.innerHTML.split('<br>');
|
|
|
|
|
+ for (const line of htmlLines) {
|
|
|
|
|
+ const text = line.replace(/<[^>]*>/g, '').trim();
|
|
|
|
|
+ if (text) {
|
|
|
|
|
+ name = text;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if (!name) return;
|
|
if (!name) return;
|
|
|
|
|
|
|
@@ -250,6 +255,61 @@ function extractTimeSlots(htmlString) {
|
|
|
return timeSlots.length > 0 ? timeSlots : null;
|
|
return timeSlots.length > 0 ? timeSlots : null;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 根据学期字符串获取学期第一周周一日期
|
|
|
|
|
+ * 学期格式如 "2025-2026-2"
|
|
|
|
|
+ * 春季学期:3月第二个周一,秋季学期:9月1日所在周的周一
|
|
|
|
|
+ */
|
|
|
|
|
+function getSemesterStartMonday(semesterId) {
|
|
|
|
|
+ if (!semesterId) return null;
|
|
|
|
|
+ const parts = semesterId.split('-');
|
|
|
|
|
+ if (parts.length < 3) return null;
|
|
|
|
|
+ const year1 = parseInt(parts[0], 10);
|
|
|
|
|
+ const year2 = parseInt(parts[1], 10);
|
|
|
|
|
+ const semester = parseInt(parts[2], 10);
|
|
|
|
|
+ if (isNaN(year1) || isNaN(year2) || isNaN(semester)) return null;
|
|
|
|
|
+
|
|
|
|
|
+ // 估算学期开始日期
|
|
|
|
|
+ let startDate;
|
|
|
|
|
+ if (semester === 1) {
|
|
|
|
|
+ startDate = new Date(year1, 8, 1); // 秋季学期:约9月1日
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 春季学期:3月第二个周一
|
|
|
|
|
+ const march1Day = new Date(year2, 2, 1).getDay();
|
|
|
|
|
+ const firstMondayDate = march1Day === 1 ? 1 : march1Day === 0 ? 2 : 9 - march1Day;
|
|
|
|
|
+ startDate = new Date(year2, 2, firstMondayDate + 7); // 第二个周一
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 找到学期开始日期所在周的周一
|
|
|
|
|
+ const startDay = startDate.getDay(); // 0=周日
|
|
|
|
|
+ const monday = new Date(startDate);
|
|
|
|
|
+ monday.setDate(startDate.getDate() + (startDay === 0 ? -6 : 1 - startDay));
|
|
|
|
|
+ return monday;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 格式化日期为 YYYY-MM-DD
|
|
|
|
|
+ */
|
|
|
|
|
+function formatDate(date) {
|
|
|
|
|
+ const y = date.getFullYear();
|
|
|
|
|
+ const m = String(date.getMonth() + 1).padStart(2, '0');
|
|
|
|
|
+ const d = String(date.getDate()).padStart(2, '0');
|
|
|
|
|
+ return `${y}-${m}-${d}`;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 根据学期字符串计算当前周数
|
|
|
|
|
+ */
|
|
|
|
|
+function calculateCurrentWeek(semesterId) {
|
|
|
|
|
+ const monday = getSemesterStartMonday(semesterId);
|
|
|
|
|
+ if (!monday) return 1;
|
|
|
|
|
+
|
|
|
|
|
+ const now = new Date();
|
|
|
|
|
+ const diffMs = now.getTime() - monday.getTime();
|
|
|
|
|
+ const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
|
|
|
+ return Math.max(1, Math.floor(diffDays / 7) + 1);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 显示欢迎提示
|
|
* 显示欢迎提示
|
|
|
*/
|
|
*/
|
|
@@ -312,9 +372,15 @@ async function fetchCourseHtml() {
|
|
|
/**
|
|
/**
|
|
|
* 保存课程数据到 App
|
|
* 保存课程数据到 App
|
|
|
*/
|
|
*/
|
|
|
-async function saveCourseDataToApp(courses, timeSlots) {
|
|
|
|
|
|
|
+async function saveCourseDataToApp(courses, timeSlots, semesterId) {
|
|
|
|
|
+ // 计算学期开始日期和当前周数
|
|
|
|
|
+ const startMonday = getSemesterStartMonday(semesterId);
|
|
|
|
|
+ const currentWeek = calculateCurrentWeek(semesterId);
|
|
|
|
|
+
|
|
|
// 保存学期配置
|
|
// 保存学期配置
|
|
|
await window.AndroidBridgePromise.saveCourseConfig(JSON.stringify({
|
|
await window.AndroidBridgePromise.saveCourseConfig(JSON.stringify({
|
|
|
|
|
+ "semesterStartDate": startMonday ? formatDate(startMonday) : null,
|
|
|
|
|
+ "currentWeek": currentWeek,
|
|
|
"semesterTotalWeeks": 20,
|
|
"semesterTotalWeeks": 20,
|
|
|
"firstDayOfWeek": 1
|
|
"firstDayOfWeek": 1
|
|
|
}));
|
|
}));
|
|
@@ -382,7 +448,7 @@ async function runImportFlow() {
|
|
|
// 尝试直接从初始 HTML 中解析课程
|
|
// 尝试直接从初始 HTML 中解析课程
|
|
|
const initialCourses = parseTimetableToModel(html);
|
|
const initialCourses = parseTimetableToModel(html);
|
|
|
if (initialCourses.length > 0) {
|
|
if (initialCourses.length > 0) {
|
|
|
- await saveCourseDataToApp(initialCourses, timeSlots);
|
|
|
|
|
|
|
+ await saveCourseDataToApp(initialCourses, timeSlots, semesterId);
|
|
|
AndroidBridge.showToast(`成功导入 ${initialCourses.length} 门课程`);
|
|
AndroidBridge.showToast(`成功导入 ${initialCourses.length} 门课程`);
|
|
|
AndroidBridge.notifyTaskCompletion();
|
|
AndroidBridge.notifyTaskCompletion();
|
|
|
}
|
|
}
|
|
@@ -390,10 +456,9 @@ async function runImportFlow() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 8. 保存课程数据
|
|
// 8. 保存课程数据
|
|
|
- await saveCourseDataToApp(finalCourses, timeSlots);
|
|
|
|
|
|
|
+ await saveCourseDataToApp(finalCourses, timeSlots, semesterId);
|
|
|
|
|
|
|
|
- AndroidBridge.showToast(`成功导入 ${finalCourses.length} 门课程`);
|
|
|
|
|
- AndroidBridge.showToast(`请在设置界面手动选择当前周数`);
|
|
|
|
|
|
|
+ AndroidBridge.showToast(`成功导入 ${finalCourses.length} 门课程(当前第 ${calculateCurrentWeek(semesterId)} 周)`);
|
|
|
AndroidBridge.notifyTaskCompletion();
|
|
AndroidBridge.notifyTaskCompletion();
|
|
|
|
|
|
|
|
} catch (error) {
|
|
} catch (error) {
|