广东省继续教育(含公需课)自动刷课

广东省继续教育(含公需课)刷课,自动答题 + 自动关闭弹窗 + 完成自动进入下章

// ==UserScript==
// @name         广东省继续教育(含公需课)自动刷课
// @version      2.1
// @description  广东省继续教育(含公需课)刷课,自动答题 + 自动关闭弹窗 + 完成自动进入下章
// @author       lzhzssy
// @icon         https://ggfw.gdhrss.gov.cn/favicon.ico
// @match        http*://ggfw.hrss.gd.gov.cn/zxpx/auc/play/player*
// @license      GPLv3
// @namespace https://greasyfork.org/
// ==/UserScript==

setTimeout(function () {
    // 静音
    p.tag.muted = true;
    var errChecking = setInterval(function () {
        if ($('.learnpercent').text().indexOf('已完成') != -1) {
            var learnlist = $("a:contains('未完成')").length != 0 ? $("a:contains('未完成')") : $("a:contains('未开始')");
            if (learnlist.length == 0) {
                if (confirm('本课程全部学习完成!即将关闭页面!')) {
                    window.close();
                }
            } else {
                learnlist.each(function () {
                    this.click();
                })
            }
        }
        // 暂停时自动开始播放
        if (p.paused()) {
            p.play()
        }
    }, 500);
}, 1000);

// ====== 自动答题功能(含通用弹窗处理) ======
(function () {
    const TRY_INTERVAL = 1000;
    let answeredThisQuestion = false;

    function clickEl(el) {
        if (!el) return false;
        try {
            el.click();
            return true;
        } catch (e) {
            try {
                el.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
                return true;
            } catch (err) {
                console.warn('click failed', err);
                return false;
            }
        }
    }

    function setInputChecked(input) {
        if (!input) return;
        input.checked = true;
        input.dispatchEvent(new Event('change', { bubbles: true }));
        input.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
    }

    function submitAnswer() {
        const submitBtn = document.querySelector('.reply-sub');
        if (submitBtn) {
            clickEl(submitBtn);
            return true;
        }
        if (typeof window.subAnswer === 'function') {
            try { window.subAnswer(); return true; } catch (e) {}
        }
        return false;
    }

    function findVisibleMessager() {
        const nodes = document.querySelectorAll('.messager-window');
        for (let n of nodes) {
            const style = window.getComputedStyle(n);
            if (style.display !== 'none' && n.offsetParent !== null) return n;
            const inline = n.getAttribute('style') || '';
            if (inline.indexOf('display: block') !== -1) return n;
        }
        return null;
    }

    function tryAutoAnswerOnce() {
        const form = document.querySelector('#from_ejectque');
        if (!form) return false;
        if (answeredThisQuestion) return false;

        // 默认先选 value='0'
        let opt = form.querySelector("input[name='panduan'][value='0']");
        if (!opt) opt = form.querySelector("input[name='panduan']");
        if (!opt) return false;

        setInputChecked(opt);
        setTimeout(() => {
            if (submitAnswer()) {
                answeredThisQuestion = true;
            }
        }, 1000);
        return true;
    }

    function handleDialog(dialog) {
        let text = dialog.innerText.trim();
        console.log('[AutoAnswer] 检测到弹窗:', text);

        // 处理“答案错误”
        if (text.includes('答案错误')) {
            console.log('[AutoAnswer] 检测到 "答案错误",切换答案重试');
            clickDialogOk(dialog);
            setTimeout(() => {
                const form = document.querySelector('#from_ejectque');
                if (!form) return;

                const alt = form.querySelector("input[name='panduan'][value='1']");
                if (alt) {
                    answeredThisQuestion = false;
                    setInputChecked(alt);
                    setTimeout(() => submitAnswer(), 200);
                } else {
                    const anyOpt = form.querySelectorAll("input[name='panduan']");
                    for (let o of anyOpt) {
                        if (!o.checked) {
                            answeredThisQuestion = false;
                            setInputChecked(o);
                            setTimeout(() => submitAnswer(), 200);
                            break;
                        }
                    }
                }
            }, 1000);
        }
        // 处理“答案正确”
        else if (text.includes('答案正确')) {
            console.log('[AutoAnswer] 检测到 "答案正确",点击确定继续');
            setTimeout(() => {
                clickDialogOk(dialog);
            }, 1000);
        }
        // 处理其他通用弹窗(如“请选择对应的答案!”、“提示”等)
        else {
            console.log('[AutoAnswer] 检测到其他弹窗,自动关闭');
            setTimeout(() => {
                clickDialogOk(dialog);
            }, 1000);
        }
    }

    function clickDialogOk(dialog) {
        let okBtn = Array.from(dialog.querySelectorAll('a.l-btn'))
            .find(a => (a.textContent || '').trim().includes('确定'));
        if (!okBtn) {
            const span = dialog.querySelector('.l-btn-text');
            if (span && span.textContent.includes('确定')) {
                okBtn = span.closest('a') || span;
            }
        }
        //if (!okBtn) {
        //    okBtn = dialog.querySelector('.panel-tool-close'); // X关闭按钮兜底
        //}
        if (okBtn) clickEl(okBtn);
    }

    const mainInterval = setInterval(() => {
        tryAutoAnswerOnce();

        const dialog = findVisibleMessager();
        if (dialog) {
            handleDialog(dialog);
        }
    }, TRY_INTERVAL);

    const formObserver = new MutationObserver(() => {
        answeredThisQuestion = false;
    });
    const formElem = document.querySelector('#from_ejectque');
    if (formElem) formObserver.observe(formElem, { childList: true, subtree: true });
})();