/** * 拾光课程表适配脚本 - 山东石油化工学院 (sdipct.edu.cn) * 非该大学开发者适配,开发者无法及时发现问题 * 出现问题请提联系开发者或者提交pr更改,这更加快速 */ /** * 解析周次字符串,例如 "1,2,3,4,5" -> [1, 2, 3, 4, 5] */ function parseWeeks(weekStr) { if (!weekStr) return []; const weeks = weekStr.split(',') .map(w => Number(w.trim())) .filter(w => !isNaN(w) && w > 0); return [...new Set(weeks)].sort((a, b) => a - b); } /** * 将教务系统返回的 JSON 转换为拾光标准的 CourseJsonModel 数组 */ function parseJsonData(jsonData) { console.log("JS: 开始解析课程 JSON..."); if (!jsonData || jsonData.code !== 0 || !Array.isArray(jsonData.data)) { return []; } return jsonData.data.filter(raw => { return raw.kcmc && raw.xq && raw.ps && raw.pe && raw.zc; }).map(raw => { return { name: raw.kcmc.trim(), teacher: (raw.teaxms || "未知教师").trim(), position: (raw.jxcdmc || "未知地点").trim(), day: Number(raw.xq), startSection: Number(raw.ps), endSection: Number(raw.pe), weeks: parseWeeks(raw.zc) }; }).filter(course => { return course.weeks.length > 0 && course.startSection <= course.endSection; }); } /** * 校验函数:验证用户输入的学年格式 */ function validateYearInput(input) { return /^[0-9]{4}$/.test(input) ? false : "请输入四位数字的起始学年(如 2025)"; } /** * 步骤 A: 显示引导公告 */ async function promptUserToStart() { return await window.AndroidBridgePromise.showAlert( "教务导入说明", "1. 请确保已在浏览器中成功登录教务系统\n2. 导入过程中请勿关闭页面", "好的,开始导入" ); } /** * 步骤 B: 获取用户输入的学年 */ async function getAcademicYear() { const currentYear = new Date().getFullYear().toString(); return await window.AndroidBridgePromise.showPrompt( "选择学年", "请输入要导入的起始学年(例如 2025-2026 应输入2025):", currentYear, "validateYearInput" ); } /** * 步骤 C: 选择学期 */ async function selectSemester() { const semesters = ["第一学期 (秋季)", "第二学期 (春季)"]; return await window.AndroidBridgePromise.showSingleSelection( "选择学期", JSON.stringify(semesters), 0 ); } /** * 发起网络请求并获取数据 */ async function fetchCourses(academicYear, semesterIndex) { AndroidBridge.showToast("正在请求教务数据..."); const semesterCode = semesterIndex === 0 ? "01" : "02"; const body = `xnxqdm=${academicYear}${semesterCode}`; const url = "https://webvpn.sdipct.edu.cn/https/77726476706e69737468656265737421fae0598869236c596e0b9de29d51367bd943/new/student/xsgrkb/getCalendarWeekDatas?vpn-12-o2-jwxt.sdipct.edu.cn"; try { const response = await fetch(url, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded; charset=UTF-8" }, body: body, credentials: "include" }); if (!response.ok) throw new Error(`HTTP Error: ${response.status}`); const jsonData = await response.json(); return parseJsonData(jsonData); } catch (e) { console.error("Fetch Error:", e); AndroidBridge.showToast("网络请求失败,请检查登录状态"); return null; } } /** * 预设时间段数据 */ const StandardTimeSlots = [ { number: 1, startTime: "08:00", endTime: "08:50" }, { number: 2, startTime: "09:00", endTime: "09:50" }, { number: 3, startTime: "10:10", endTime: "11:00" }, { number: 4, startTime: "11:10", endTime: "12:00" }, { number: 5, startTime: "14:00", endTime: "14:50" }, { number: 6, startTime: "15:00", endTime: "15:50" }, { number: 7, startTime: "16:10", endTime: "17:00" }, { number: 8, startTime: "17:10", endTime: "18:00" }, { number: 9, startTime: "19:00", endTime: "19:50" }, { number: 10, startTime: "20:00", endTime: "20:50" } ]; // 主流程编排 async function runImportFlow() { // 1. 前置检查 const isReady = await promptUserToStart(); if (!isReady) return; // 用户点击取消,静默退出 // 2. 获取参数(学年、学期) const year = await getAcademicYear(); if (!year) { AndroidBridge.showToast("导入已取消"); return; } const semesterIdx = await selectSemester(); if (semesterIdx === null) { AndroidBridge.showToast("导入已取消"); return; } // 3. 执行获取与解析 const courses = await fetchCourses(year, semesterIdx); if (!courses || courses.length === 0) { if (courses && courses.length === 0) AndroidBridge.showToast("该学期暂无课程数据"); return; } // 4. 数据保存 try { // 保存课程 await window.AndroidBridgePromise.saveImportedCourses(JSON.stringify(courses)); // 保存预设时间表 await window.AndroidBridgePromise.savePresetTimeSlots(JSON.stringify(StandardTimeSlots)); AndroidBridge.showToast(`成功导入 ${courses.length} 门课程!`); // 5. 流程收尾:通知原生端任务完成 AndroidBridge.notifyTaskCompletion(); console.log("JS: 流程成功完成"); } catch (e) { AndroidBridge.showToast("保存失败: " + e.message); } } // 启动入口 runImportFlow();