| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- // 文件: neu.js
- // 1. 显示校区选择弹窗
- async function showCampusSelection() {
- const campuses = ["南湖校区", "浑南校区"];
- try {
- console.log("即将显示单选列表弹窗...");
- const selectedIndex = await window.AndroidBridgePromise.showSingleSelection(
- "选择你所在的校区",
- JSON.stringify(campuses),
- 2
- );
- if (selectedIndex !== -1) {
- return campuses[selectedIndex]; // 返回用户选择的校区
- } else {
- return false; // 用户取消时返回 false
- }
- } catch (error) {
- console.error("显示单选列表弹窗时发生错误:", error);
- AndroidBridge.showToast("Single Selection:显示列表出错!" + error.message);
- return false; // 出现错误时也返回 false
- }
- }
- // 2. 从课表页面中提取课程数据
- async function extractCoursesFromPage() {
- const iframe = document.querySelector('iframe');
- const lessons = [];
- const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
- const time = iframeDoc.querySelector('.kbappTimeXQText')
- const time_text = time.textContent;
- const dayCols = iframeDoc.querySelectorAll('.kbappTimetableDayColumnRoot');
-
- dayCols.forEach((dayCol, dayIndex) => {
- const timeSlots = dayCol.children;
- const day = dayIndex >= 1 ? dayIndex : 7;
-
- let startSection = 0;
- let endSection = 0;
-
- for (let slot of timeSlots) {
- const flexValue = slot.style.flex;
- const nums = parseInt(flexValue.split(' ')[0]);
- startSection = endSection + 1;
- endSection = startSection + nums - 1;
-
- if (slot.classList.contains('kbappTimetableDayColumnConflictContainer')) {
- // 获取所有课程项
- const courseItems = slot.querySelectorAll('.kbappTimetableCourseRenderCourseItem');
-
- courseItems.forEach(courseItem => {
- const infoTexts = courseItem.querySelectorAll('.kbappTimetableCourseRenderCourseItemInfoText');
- let name, details;
-
- infoTexts.forEach((text, idx) => {
- if (idx === 0) name = text.textContent.trim();
- else if (idx === 1) details = parseCourseDetails(text.textContent.trim());
- else if (idx === 2) return;
- });
-
- lessons.push({
- name: name,
- teacher: details.teacher,
- position: details.position,
- day: day,
- startSection: startSection,
- endSection: endSection,
- weeks: details.weeks
- });
- });
- }
- }
- });
- return { lessons: lessons, time_text: time_text };
- }
- // 2.1 解析课程详情字符串,提取周次、教师和地点信息
- function parseCourseDetails(detailStr) {
- // 匹配所有周次模式
- const weekPattern = /(\d+-\d+周(?:\([单双]\))?|\d+周(?:\([单双]\))?)/g;
- const weekMatches = detailStr.match(weekPattern);
-
- let weeks = '';
- let remaining = detailStr;
-
- if (weekMatches) {
- // 提取所有周次部分
- weeks = weekMatches.join(',');
- // 从原字符串中移除周次部分
- weekMatches.forEach(match => {
- remaining = remaining.replace(match, '');
- });
- }
-
- // 按空格分割剩余部分
- const parts = remaining.trim().split(/\s+/).filter(p => p);
-
- let teacher = '';
- let position = '';
- if (parts.length > 0) {
- teacher = parts[0];
- if (parts.length > 1) {
- position = parts.slice(1).join(' '); // 修正这一行
- }
- }
-
- // 清理教师名中的多余逗号
- teacher = teacher.replace(/^[,,]/, '').replace(/[,,]$/, '');
-
- return {
- weeks: parseWeeksString(weeks),
- teacher: teacher.trim(),
- position: position.trim()
- };
- }
- // 2.2将周次文字提取成数组
- function parseWeeksString(weeksStr) {
- if (!weeksStr) return [];
-
- const result = [];
- const weekParts = weeksStr.split(/[,,]/).map(part => part.trim());
-
- weekParts.forEach(part => {
- // 匹配单个数字周
- const singleMatch = part.match(/^(\d+)周(?:\(([单双])\))?$/);
- if (singleMatch) {
- const num = parseInt(singleMatch[1]);
- const type = singleMatch[2];
- if (!type || (type === '单' && num % 2 === 1) || (type === '双' && num % 2 === 0)) {
- result.push(num);
- }
- return;
- }
-
- // 匹配范围周
- const rangeMatch = part.match(/^(\d+)-(\d+)周(?:\(([单双])\))?$/);
- if (rangeMatch) {
- const start = parseInt(rangeMatch[1]);
- const end = parseInt(rangeMatch[2]);
- const type = rangeMatch[3];
-
- if (!type) {
- for (let i = start; i <= end; i++) result.push(i);
- } else if (type === '单') {
- for (let i = start; i <= end; i++) {
- if (i % 2 === 1) result.push(i);
- }
- } else if (type === '双') {
- for (let i = start; i <= end; i++) {
- if (i % 2 === 0) result.push(i);
- }
- }
- }
- });
-
- return [...new Set(result)].sort((a, b) => a - b);
- }
- // 3. 导入课程数据
- async function SaveCourses(lessons) {
- console.log("正在准备导入课程数据...");
- const testCourses = lessons;
- try {
- const result = await window.AndroidBridgePromise.saveImportedCourses(JSON.stringify(testCourses));
- } catch (error) {
- console.error("导入课程时发生错误:", error);
- AndroidBridge.showToast("导入课程失败: " + error.message);
- }
- }
- // 4. 根据校区导入对应的时间段
- async function importTimeSlotsByCampus(campus) {
- console.log(`正在准备${campus}时间段数据...`);
- const hunNanTimeSlots = [
- { "number": 1, "startTime": "08:30", "endTime": "09:15" },
- { "number": 2, "startTime": "09:25", "endTime": "10:10" },
- { "number": 3, "startTime": "10:30", "endTime": "11:15" },
- { "number": 4, "startTime": "11:25", "endTime": "12:10" },
- { "number": 5, "startTime": "14:00", "endTime": "14:45" },
- { "number": 6, "startTime": "14:55", "endTime": "15:40" },
- { "number": 7, "startTime": "16:00", "endTime": "16:45" },
- { "number": 8, "startTime": "16:55", "endTime": "17:40" },
- { "number": 9, "startTime": "18:30", "endTime": "19:15" },
- { "number": 10, "startTime": "19:25", "endTime": "20:10" },
- { "number": 11, "startTime": "20:30", "endTime": "21:15" },
- { "number": 12, "startTime": "21:15", "endTime": "22:10" },
- ];
-
- const nanHuTimeSlots = [
- { "number": 1, "startTime": "08:00", "endTime": "08:45" },
- { "number": 2, "startTime": "08:55", "endTime": "09:40" },
- { "number": 3, "startTime": "10:00", "endTime": "10:45" },
- { "number": 4, "startTime": "10:55", "endTime": "11:40" },
- { "number": 5, "startTime": "14:00", "endTime": "14:45" },
- { "number": 6, "startTime": "14:55", "endTime": "15:40" },
- { "number": 7, "startTime": "16:00", "endTime": "16:45" },
- { "number": 8, "startTime": "16:55", "endTime": "17:40" },
- { "number": 9, "startTime": "18:30", "endTime": "19:15" },
- { "number": 10, "startTime": "19:25", "endTime": "20:10" },
- { "number": 11, "startTime": "20:20", "endTime": "21:05" },
- { "number": 12, "startTime": "21:15", "endTime": "22:00" },
- ];
-
- // 根据校区选择对应的时间表
- const timeSlotsToImport = (campus === "南湖校区") ? nanHuTimeSlots : hunNanTimeSlots;
- try {
- const result = await window.AndroidBridgePromise.savePresetTimeSlots(JSON.stringify(timeSlotsToImport));
- } catch (error) {
- console.error("导入时间段时发生错误:", error);
- window.AndroidBridge.showToast("导入时间段失败: " + error.message);
- }
- }
- // 5. 导入课表配置
- async function SaveConfig(time_text) {
- console.log("正在准备配置数据...");
- // 注意:只传入要修改的字段,其他字段(如 semesterTotalWeeks)会使用 Kotlin 模型中的默认值
- const courseConfigData = {
- "semesterTotalWeeks": 18,
- "defaultClassDuration": 45,
- "defaultBreakDuration": 10,
- "firstDayOfWeek": 7
- };
- try {
- const configJsonString = JSON.stringify(courseConfigData);
- const result = await window.AndroidBridgePromise.saveCourseConfig(configJsonString);
- } catch (error) {
- console.error("导入配置时发生错误:", error);
- AndroidBridge.showToast("导入配置失败: " + error.message);
- }
- }
- /**
- * 编排这些异步操作,并在用户取消时停止后续执行。
- */
- async function runAllDemosSequentially() {
- AndroidBridge.showToast("开始导入课表...");
-
- // 2. 校区选择
- const selectedCampus = await showCampusSelection();
- if (!selectedCampus) {
- console.log("用户取消了校区选择,停止后续执行。");
- AndroidBridge.showToast("已取消导入");
- return; // 用户取消,立即退出函数
- }
- // 3. 从课表页面中提取课程数据
- const PageInfo = await extractCoursesFromPage();
- const lessons = PageInfo.lessons;
- const time_text = PageInfo.time_text;
-
- // 4. 保存课程数据到数据库
- await SaveCourses(lessons);
-
- // 5. 根据选择的校区导入对应的时间段
- await importTimeSlotsByCampus(selectedCampus);
-
- // 6. 保存底层配置
- await SaveConfig(time_text);
- // 发送最终的生命周期完成信号
- AndroidBridge.notifyTaskCompletion();
- AndroidBridge.showToast("课表导入完成!");
- }
- // 启动所有演示
- runAllDemosSequentially();
|