广东省继续教育(含公需课)刷课,自动答题 + 自动关闭弹窗 + 完成自动进入下章
// ==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 });
})();