| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- /**
- * 拾光课程表适配脚本 - 山东石油化工学院 (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();
|