Browse Source

add: 新疆政法学院教务适配 (#397)

jesse 2 weeks ago
parent
commit
4bc56b6755
3 changed files with 221 additions and 0 deletions
  1. 5 0
      index/root_index.yaml
  2. 8 0
      resources/XJZFU/adapters.yaml
  3. 208 0
      resources/XJZFU/xjzfu.js

+ 5 - 0
index/root_index.yaml

@@ -548,6 +548,11 @@ schools:
     initial: "X"
     resource_folder: "XYAFU"
 
+  - id: "XJZFU"
+    name: "新疆政法学院"
+    initial: "X"
+    resource_folder: "XJZFU"
+
   - id: "ZJUT"
     name: "浙江工业大学"
     initial: "Z"

+ 8 - 0
resources/XJZFU/adapters.yaml

@@ -0,0 +1,8 @@
+adapters:
+  - adapter_id: "XJZFU_01"
+    adapter_name: "新疆政法学院新教务系统"
+    category: "BACHELOR_AND_ASSOCIATE"
+    asset_js_path: "xjzfu.js"
+    import_url: "https://jwxt.xjzfu.edu.cn/jwapp/sys/homeapp/home/index.html"
+    maintainer: "jesse-s4"
+    description: "适配新疆政法学院金智教务系统 2026.07.20"

+ 208 - 0
resources/XJZFU/xjzfu.js

@@ -0,0 +1,208 @@
+// 新疆政法学院教务系统课程表导入脚本
+// 适配: jwxt.xjzfu.edu.cn
+
+function isOnStudentPage() {
+    return /jwxt\.xjzfu\.edu\.cn/i.test(window.location.href);
+}
+
+function parseWeekMask(mask) {
+    if (!mask) return [];
+    const weeks = [];
+    for (let i = 0; i < mask.length; i++) {
+        if (mask[i] === '1') weeks.push(i + 1);
+    }
+    return weeks;
+}
+
+function parseTeacher(str) {
+    if (!str) return '';
+    const names = [];
+    const parts = str.split(';');
+    for (const part of parts) {
+        const sections = part.split('/');
+        for (const section of sections) {
+            const match = section.match(/([^[\]]+)\[主讲\]/);
+            if (match) {
+                names.push(match[1].trim());
+            }
+        }
+    }
+    return [...new Set(names)].join('、');
+}
+
+function generateTimeSlots(arrangedList) {
+    const standardSchedule = [
+        { number: 1, startTime: '10:00', endTime: '10:45' },
+        { number: 2, startTime: '10:50', endTime: '11:35' },
+        { number: 3, startTime: '11:50', endTime: '12:35' },
+        { number: 4, startTime: '12:40', endTime: '13:25' },
+        { number: 5, startTime: '13:30', endTime: '14:15' },
+        { number: 6, startTime: '16:00', endTime: '16:45' },
+        { number: 7, startTime: '16:50', endTime: '17:35' },
+        { number: 8, startTime: '17:50', endTime: '18:35' },
+        { number: 9, startTime: '18:40', endTime: '19:25' },
+        { number: 10, startTime: '20:30', endTime: '21:15' },
+        { number: 11, startTime: '21:20', endTime: '22:05' }
+    ];
+
+    const maxSection = Math.max(...arrangedList.map(c => c.endSection).filter(Boolean), 0);
+    return standardSchedule.filter(s => s.number <= maxSection);
+}
+
+async function fetchScheduleData(termCode) {
+    const body = new URLSearchParams();
+    body.append('termCode', termCode);
+    body.append('campusCode', '1');
+    body.append('type', 'term');
+
+    const res = await fetch(
+        'https://jwxt.xjzfu.edu.cn/jwapp/sys/homeapp/api/home/student/getMyScheduleDetail.do',
+        {
+            method: 'POST',
+            headers: {
+                'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
+                'fetch-api': 'true'
+            },
+            credentials: 'include',
+            body: body.toString()
+        }
+    );
+    const data = await res.json();
+    if (data.code !== '0') throw new Error(data.msg || '获取课表失败');
+    return data.datas;
+}
+
+async function fetchTermWeeks(termCode) {
+    const res = await fetch(
+        `https://jwxt.xjzfu.edu.cn/jwapp/sys/homeapp/api/home/getTermWeeks.do?termCode=${encodeURIComponent(termCode)}`,
+        {
+            headers: { 'fetch-api': 'true' },
+            credentials: 'include'
+        }
+    );
+    const data = await res.json();
+    if (data.code !== '0') throw new Error(data.msg || '获取学期信息失败');
+    return data.datas;
+}
+
+async function fetchTermList() {
+    const res = await fetch(
+        'https://jwxt.xjzfu.edu.cn/jwapp/sys/homeapp/api/home/kb/xnxq.do',
+        { headers: { 'fetch-api': 'true' }, credentials: 'include' }
+    );
+    const data = await res.json();
+    if (data.code !== '0') throw new Error(data.msg || '获取学期列表失败');
+    const datas = data.datas || [];
+    if (datas.length === 0) throw new Error('学期列表为空');
+    let defaultIndex = 0;
+    const termNames = [];
+    const termCodes = [];
+    datas.forEach((d, i) => {
+        termNames.push(d.itemName);
+        termCodes.push(d.itemCode);
+        if (d.selected === true) defaultIndex = i;
+    });
+    return { termNames, termCodes, defaultIndex };
+}
+
+async function importCourseSchedule() {
+    try {
+        AndroidBridge.showToast('正在获取学期列表...');
+
+        const termList = await fetchTermList();
+
+        let selectedIdx = termList.defaultIndex;
+        if (typeof window.AndroidBridgePromise !== 'undefined') {
+            const choice = await window.AndroidBridgePromise.showSingleSelection(
+                '请选择要导入的学期',
+                JSON.stringify(termList.termNames),
+                termList.defaultIndex
+            );
+            if (choice === null) {
+                AndroidBridge.showToast('已取消导入');
+                return false;
+            }
+            selectedIdx = choice;
+        }
+
+        const termCode = termList.termCodes[selectedIdx];
+        AndroidBridge.showToast('正在获取课表数据...');
+        const datas = await fetchScheduleData(termCode);
+        const arrangedList = datas.arrangedList || [];
+
+        if (arrangedList.length === 0) {
+            AndroidBridge.showToast('未找到课程数据');
+            return false;
+        }
+
+        const courses = [];
+        for (const item of arrangedList) {
+            courses.push({
+                name: item.courseName,
+                teacher: parseTeacher(item.weeksAndTeachers),
+                position: item.placeName || '',
+                day: item.dayOfWeek,
+                startSection: item.beginSection,
+                endSection: item.endSection,
+                weeks: parseWeekMask(item.week)
+            });
+        }
+
+        courses.sort((a, b) => {
+            if (a.day !== b.day) return a.day - b.day;
+            if (a.startSection !== b.startSection) return a.startSection - b.startSection;
+            return a.endSection - b.endSection;
+        });
+
+        console.log(`找到 ${courses.length} 门课程:`, courses);
+
+        const courseResult = await window.AndroidBridgePromise.saveImportedCourses(
+            JSON.stringify(courses)
+        );
+        if (courseResult !== true) {
+            AndroidBridge.showToast('课程导入失败');
+            return false;
+        }
+        AndroidBridge.showToast(`成功导入 ${courses.length} 门课程!`);
+
+        const timeSlots = generateTimeSlots(arrangedList);
+        console.log('时间段配置:', timeSlots);
+
+        const slotResult = await window.AndroidBridgePromise.savePresetTimeSlots(
+            JSON.stringify(timeSlots)
+        );
+        if (slotResult === true) {
+            AndroidBridge.showToast('时间段配置成功!');
+        }
+
+        const weeksData = await fetchTermWeeks(termCode);
+        if (weeksData && weeksData.length > 0) {
+            const semesterStartDate = weeksData[0].startDate.split(' ')[0];
+            const config = {
+                semesterStartDate: semesterStartDate,
+                semesterTotalWeeks: weeksData.length,
+                defaultClassDuration: 45,
+                defaultBreakDuration: 10,
+                firstDayOfWeek: 1
+            };
+            await window.AndroidBridgePromise.saveCourseConfig(JSON.stringify(config));
+            console.log('学期配置已保存:', config);
+        }
+
+        AndroidBridge.showToast('课表导入完成!');
+        AndroidBridge.notifyTaskCompletion();
+        return true;
+
+    } catch (error) {
+        console.error('导入过程出错:', error);
+        AndroidBridge.showToast('导入失败: ' + error.message);
+        return false;
+    }
+}
+
+if (isOnStudentPage()) {
+    console.log('检测到新疆政法学院教务系统');
+    setTimeout(() => { importCourseSchedule(); }, 1000);
+} else {
+    AndroidBridge.showToast('请先登录教务系统!');
+}