USST教务系统余课监控

自动刷新USST教务选课系统,检查课程是否有余量

目前為 2025-09-25 提交的版本,檢視 最新版本

// ==UserScript==
// @name         USST教务系统余课监控
// @namespace    https://bobliu.tech/
// @version      1.0.0
// @license      MIT
// @description  自动刷新USST教务选课系统,检查课程是否有余量
// @author       BobLiu
// @match        https://jwgl.usst.edu.cn/jwglxt/xsxk/zzxkyzb_cxZzxkYzbIndex.html?*
// @icon         https://jwgl.usst.edu.cn/jwglxt/logo/favicon.ico
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    let monitorRunning = false;
    const postMethod = $.post;

    const notify = (msg) => {
        new Notification(msg);
        console.log(msg);
        $.alert(msg);
    };

    const checkNotificationPermission = async () => {
        if (Notification.permission != 'granted' && (await Notification.requestPermission()) != 'granted') {
            console.error('无通知权限');
        }
    };

    const stopMonitor = (manualStop) => {
        monitorRunning = false;
        $.post = postMethod;
        if (manualStop) {
            notify('结束监控课程');
            document.querySelector('[name="query"]').click();
        }
    };

    const runMonitor = async (courseId, classNum) => {
        monitorRunning = true;
        await checkNotificationPermission();

        $.post = (url, payload, callback) => {
            postMethod(url, payload, (data) => {
                callback(data);
                if (url.match('cxJxb') && parseInt(data[classNum].yxzrs) < parseInt(data[classNum].jxbrl)) {
                    notify('课程有余量啦');
                    stopMonitor(false);
                }
            });
        };

        notify('开始监控课程');
        document.querySelector('[name="searchInput"]').value = courseId;
        while (monitorRunning) {
            document.querySelector('[name="query"]').click();
            await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 1750 + 1250)));
        }
    };

    const injectButton = (coursePanel) => {
        try {
            coursePanel.querySelector('th:last-of-type').colSpan = 2;
            const courseId = coursePanel.querySelector('.kcmc').innerText.match(/^\((\d+)\)/)[1];
            coursePanel.querySelectorAll('.body_tr').forEach((courseActions, index) => {
                courseActions.innerHTML += `<td><button type="button" class="btn btn-default btn-sm" onclick="${
                    monitorRunning ? 'stopMonitor(true)' : `runMonitor('${courseId}', ${index})`
                }">${monitorRunning ? '取消监控' : '监控'}</button></td>`;
            });
        } catch (err) {}
    };

    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            mutation.addedNodes.forEach((node) => {
                if (node.nodeType === Node.ELEMENT_NODE) {
                    if (node.classList && node.classList.contains('panel-info')) {
                        injectButton(node);
                    }
                    const panelInfoNodes = node.querySelectorAll?.('.panel-info') ?? [];
                    panelInfoNodes.forEach(injectButton);
                }
            });
        });
    });

    window.runMonitor = runMonitor;
    window.stopMonitor = stopMonitor;
    observer.observe(document.body, {
        childList: true,
        subtree: true,
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址