Przeglądaj źródła

Merge pull request #616 from XingHeYuZhuan/pending

星河欲转 2 tygodni temu
rodzic
commit
b45dd568fb

+ 5 - 0
index/root_index.yaml

@@ -578,6 +578,11 @@ schools:
     initial: "Z"
     resource_folder: "CAUC"
 
+  - id: "DLUTCI"
+    name: "大连工程学院"
+    initial: "D"
+    resource_folder: "DLUTCI"
+
   - id: "ECJTU"
     name: "华东交通大学"
     initial: "H"

+ 8 - 0
resources/DLUTCI/adapters.yaml

@@ -0,0 +1,8 @@
+adapters:
+  - adapter_id: "DLUTCI_01"
+    adapter_name: "大连工程学院教务系统"
+    category: "BACHELOR_AND_ASSOCIATE"
+    asset_js_path: "dlutci.js"
+    import_url: "https://jw.dlutci.edu.cn"
+    maintainer: "Haooz"
+    description: "大连工程学院教务系统课表导入,登录到应用管理平台后直接点击导入即可"

+ 189 - 0
resources/DLUTCI/dlutci.js

@@ -0,0 +1,189 @@
+// 大连工程学院教务系统(jw.dlutci.edu.cn)拾光课表导入适配脚本
+// 基于智慧教务(app)系统,接口为 xskcb.do 获取课表、xnxqcx.do 选择学期
+
+// 周次位图解析:SKZC 为"0"/"1"串,第 i 位为"1"表示第 i+1 周有课
+function parseWeeks(skzc) {
+    const value = String(skzc || "");
+    const weeks = [];
+    for (let i = 0; i < value.length; i++) {
+        if (value[i] === "1") weeks.push(i + 1);
+    }
+    return weeks;
+}
+
+function getErrorMessage(error) {
+    if (error && typeof error.message === "string" && error.message.trim()) return error.message;
+    if (typeof error === "string" && error.trim()) return error;
+    try {
+        const serialized = JSON.stringify(error);
+        if (serialized && serialized !== "{}") return serialized;
+    } catch (_) {
+        // Ignore serialization failures.
+    }
+    return "未知错误";
+}
+
+// 教室:JASMC 为主,XXXQDM_DISPLAY 校区做后缀;均无则"待定"
+function parsePosition(row) {
+    const campus = String(row.XXXQDM_DISPLAY || "").trim();
+    const room = String(row.JASMC || "").trim();
+    if (campus && room) return `${room}(${campus})`;
+    return room || campus || "待定";
+}
+
+function parseCourse(row) {
+    const day = Number(row.SKXQ);
+    const startSection = Number(row.KSJC);
+    const endSection = Number(row.JSJC);
+    const weeks = parseWeeks(row.SKZC);
+    if (!row.KCM || !day || day < 1 || day > 7 || !startSection || !endSection ||
+        startSection > endSection || weeks.length === 0) return null;
+
+    return {
+        name: String(row.KCM).trim(),
+        teacher: String(row.SKJS || "").split(/[\\/、,,]/)[0].trim() || "未知",
+        position: parsePosition(row),
+        day,
+        startSection,
+        endSection,
+        weeks
+    };
+}
+
+// 接口返回 JSON = { datas: { xskcb: { rows: [...] } } },按行为一门课;同一门课多处时段会分多条,按组合键去重
+function transformSchedule(payload) {
+    const rows = payload && payload.datas && payload.datas.xskcb && payload.datas.xskcb.rows;
+    if (!Array.isArray(rows)) return [];
+    const rawCourses = rows.map(parseCourse).filter(Boolean);
+
+    const seen = new Set();
+    const courses = [];
+    for (const c of rawCourses) {
+        const key = `${c.name}|${c.day}|${c.startSection}|${c.endSection}|${c.weeks.join(',')}|${c.teacher}|${c.position}`;
+        if (seen.has(key)) continue;
+        seen.add(key);
+        courses.push(c);
+    }
+    return courses;
+}
+
+// 判断是否登录页
+function isLoginPage() {
+    const url = window.location.href;
+    return /login/i.test(url);
+}
+
+async function fetchCurrentSemester() {
+    const response = await fetch("/jwapp/sys/wdkb/modules/jshkcb/dqxnxq.do", {
+        method: "POST",
+        headers: {
+            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
+            "X-Requested-With": "XMLHttpRequest"
+        },
+        body: "",
+        credentials: "include"
+    });
+    if (!response.ok) throw new Error(`当前学期接口请求失败(HTTP ${response.status})`);
+    const payload = await response.json();
+    const rows = payload && payload.datas && payload.datas.dqxnxq && payload.datas.dqxnxq.rows;
+    const term = Array.isArray(rows) && rows.length > 0 ? rows[0] : null;
+    if (!term || (!term.DM && !term.XNXQDM)) throw new Error("未获取到当前学期信息。");
+    return { code: String(term.XNXQDM || term.DM) };
+}
+
+async function fetchSemesterList() {
+    const response = await fetch("/jwapp/sys/wdkb/modules/jshkcb/xnxqcx.do", {
+        method: "POST",
+        headers: {
+            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
+            "X-Requested-With": "XMLHttpRequest"
+        },
+        body: "*order=-DM",
+        credentials: "include"
+    });
+    if (!response.ok) throw new Error(`学期列表接口请求失败(HTTP ${response.status})`);
+    const payload = await response.json();
+    const rows = payload && payload.datas && payload.datas.xnxqcx && payload.datas.xnxqcx.rows;
+    if (!Array.isArray(rows)) throw new Error("学期列表返回数据格式异常。");
+    return rows.filter(item => item && (item.DM || item.XNXQDM)).map(item => {
+        const code = String(item.XNXQDM || item.DM);
+        const MC = String(item.MC || item.DM || item.XNXQDM);
+        return { code, name: MC };
+    });
+}
+
+// 选择学期,默认定位到当前学期
+async function selectSemester() {
+    const current = await fetchCurrentSemester();
+    const list = await fetchSemesterList();
+    if (list.length === 0) throw new Error("未获取到学期列表。");
+
+    const defaultIndex = Math.max(0, list.findIndex(s => s.code === current.code));
+    const selectedIndex = await window.shiguangBridgePromise.showSingleSelection(
+        "请选择学期",
+        JSON.stringify(list.map(s => s.name)),
+        defaultIndex
+    );
+    if (selectedIndex === null || selectedIndex === undefined) return null;
+    return list[selectedIndex];
+}
+
+async function fetchCourses(xnxqdm) {
+    window.shiguangBridge.showToast("正在请求课表数据...");
+    // 请求参数仅传 XNXQDM,即可返回该学期全部课表
+    const response = await fetch("/jwapp/sys/wdkb/modules/xskcb/xskcb.do", {
+        method: "POST",
+        headers: {
+            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
+            "X-Requested-With": "XMLHttpRequest"
+        },
+        body: `XNXQDM=${encodeURIComponent(xnxqdm)}`,
+        credentials: "include"
+    });
+    if (!response.ok) throw new Error(`课表接口请求失败(HTTP ${response.status})`);
+    const payload = await response.json();
+    return transformSchedule(payload);
+}
+
+async function runImportFlow() {
+    if (isLoginPage()) {
+        window.shiguangBridge.showToast("导入失败:请先登录教务系统!");
+        return;
+    }
+
+    const alertConfirmed = await window.shiguangBridgePromise.showAlert(
+        "教务系统课表导入",
+        "导入前请确保您已登录教务系统,建议在课表页面进行导入",
+        "好的,开始导入"
+    );
+    if (!alertConfirmed) {
+        window.shiguangBridge.showToast("用户取消了导入。");
+        return;
+    }
+
+    try {
+        const semester = await selectSemester();
+        if (!semester) {
+            window.shiguangBridge.showToast("用户取消了导入。");
+            return;
+        }
+        console.log(`JS: 选择学期: ${semester.name} (${semester.code})`);
+
+        const courses = await fetchCourses(semester.code);
+        if (courses.length === 0) {
+            window.shiguangBridge.showToast("未找到任何课程数据,请检查所选学期是否正确。");
+            return;
+        }
+
+        window.shiguangBridge.showToast(`正在保存 ${courses.length} 门课程...`);
+        await window.shiguangBridgePromise.saveImportedCourses(JSON.stringify(courses, null, 2));
+
+        window.shiguangBridge.showToast(`课程导入成功,共导入 ${courses.length} 门课程!`);
+        window.shiguangBridge.notifyTaskCompletion();
+    } catch (error) {
+        window.shiguangBridge.showToast(`导入失败:${getErrorMessage(error)}`);
+        console.error("JS: Import Error:", error);
+    }
+}
+
+runImportFlow();

+ 1 - 1
resources/GXMU/gxmu.js

@@ -38,7 +38,7 @@ function mapCourseRecord(record) {
     const weeks = parseWeeks(record.zc || "");
     if (weeks.length === 0) return null;
 
-    const day = parseInt(record.qsxq, 10);
+    const day = parseInt(record.xq, 10);
     const startSection = parseInt(record.ps, 10);
     const endSection = parseInt(record.pe, 10);
     if (!day || day < 1 || day > 7) return null;

+ 1 - 1
resources/HPU/adapters.yaml

@@ -4,6 +4,6 @@ adapters:
     adapter_name: "河南理工大学教务系统"
     category: "BACHELOR_AND_ASSOCIATE"
     asset_js_path: "hpu.js"
-    import_url: "https://uia.hpu.edu.cn/cas/login?service=http%3A%2F%2Fzhjw.hpu.edu.cn%2Feams%2Flogin.action"
+    import_url: "https://zhjw.hpu.edu.cn/eams/login.action"
     maintainer: "ca1q1an"
     description: "河南理工大学树维教务系统(eams架构),统一身份认证CAS登录\n导入后请在App中设置本学期开学日期"