// ==UserScript==
// @name 4.0华医网刷课脚本
// @namespace https://jiaobenmiao.com/
// @version 7.0
// @description 该油猴脚本用于 华医网 的辅助看课,脚本功能如下:自动静音播放,自动切换视频,屏蔽课堂问答,自动考试
// @author 脚本喵
// @match *://*.91huayi.com/course_ware/course_ware_polyv.aspx?*
// @match *://*.91huayi.com/course_ware/course_ware_cc.aspx*
// @match *://*.91huayi.com/pages/exam.aspx?*
// @match *://*.91huayi.com/pages/exam_result.aspx?*
// @match *://*.91huayi.com/*
// @grant none
// @icon https://jiaobenmiao.com/img/logo2.jpg
// @license MIT
// ==/UserScript==
(function () {
'use strict';
// ===================== 调试窗口(集成模式切换按钮) =====================
window.debugLog = function (msg) {
let box = document.getElementById('debug-box');
if (!box) return;
let time = new Date().toLocaleTimeString();
box.value = `[${time}] ${msg}\n` + box.value;
};
function createDebugWindow() {
let debugUI = document.createElement("div");
debugUI.style.cssText = `
position: fixed; top: 10px; left: 10px; z-index: 999999;
width: 380px; background: #1a1a1a; color: #0f0;
padding: 8px; border-radius: 6px; font-size:12px;
font-family: Consolas, monospace;
`;
let currentMode = localStorage.getItem("华医mode") == "2" ? "视频+考试" : "单刷视频";
debugUI.innerHTML = `
📝 调试日志(V7.0)
关闭
当前模式:${currentMode}(点击切换)
`;
document.body.appendChild(debugUI);
document.getElementById("close-debug").onclick = () => debugUI.remove();
// 模式切换功能
document.getElementById("mode-btn").onclick = function () {
let now = localStorage.getItem("华医mode") == "2" ? "1" : "2";
localStorage.setItem("华医mode", now);
let txt = now == "2" ? "视频+考试" : "单刷视频";
this.innerText = `当前模式:${txt}(点击切换)`;
debugLog("✅ 已切换运行模式:" + txt);
};
}
createDebugWindow();
var submitTime = 9100;//交卷时间控制
var reTryTime = 4500;//重考,视频进入考试延时控制
var examTime = 10000;//听课完成进入考试延时
var randomX = 5000;//随机延时上限
var vSpeed = 1; //首次使用脚本的默认播放速度
var autoSkip = false; //一个可能会封号的功能。
var keyPlayRate = "JJ_Playrate";
var keyTest = "JJ_Test";
var keyResult = "JJ_Result";
var keyThisTitle = "JJ_ThisTitle";
var keyTestAnswer = "JJ_TestAnswer";
var keyRightAnswer = "JJ_RightAnswer";
var keyAllAnswer = "JJ_AllAnswer";
var btstyleA = "font-size: 16px;font-weight: 300;text-decoration: none;text-align: center;line-height: 40px;height: 40px;padding: 0 40px;display: inline-block;appearance: none;cursor: pointer;border: none;box-sizing: border-box;transition-property: all;transition-duration: .3s;background-color: #4cb0f9;border-color: #4cb0f9;border-radius: 4px;margin: 5px;color: #FFF;";
var btstyleB = "font-size: 12px;font-weight: 300;text-decoration: none;text-align: center;line-height: 20px;height: 20px;padding: 0 5px;display: inline-block;appearance: none;cursor: pointer;border: none;box-sizing: border-box;transition-property: all;transition-duration: .3s;background-color: #4cb0f9;border-color: #4cb0f9;border-radius: 4px;margin: 5px;color: #FFF;";
var btstyleC = "font-size: 12px;font-weight: 300;text-decoration: none;text-align: center;line-height: 20px;height: 20px;padding: 0 5px;display: inline-block;appearance: none;cursor: pointer;border: none;box-sizing: border-box;transition-property: all;transition-duration: .3s;background-color: #f15854;border-color: #f15854;border-radius: 4px;margin: 5px;color: #FFF;";
var urlInfos = window.location.href.split("/");
var urlTip = urlInfos[urlInfos.length - 1].split("?")[0];
var huayi = getHuayi();
var nspeed = 0;
var clock = null;
advis();
debugLog("🚀 脚本启动成功,版本:V7.0");
debugLog("✅ 当前页面已识别,准备执行任务");
document.querySelector("span[id='tixing']").innerHTML = "当前网址已适配 ✅";
if (urlTip == "course_ware_polyv.aspx") {
console.log("当前任务: 华医看视频");
debugLog("📺 进入保利威播放器视频页面");
debugLog("📌 下一步:自动静音、自动播放、自动下一集");
document.querySelector("div[id='Div1']").style.top = "40px";
huayi.seeVideo(1);
} else if (urlTip == "course_ware_cc.aspx") {
console.log("当前任务: 华医看视频");
debugLog("📺 进入CC视频播放器页面");
debugLog("📌 下一步:自动静音、自动播放、自动下一集");
document.querySelector("div[id='Div1']").style.top = "40px";
huayi.seeVideo(2);
} else if (urlTip == "exam.aspx") {
console.log("当前任务: 华医考试");
debugLog("📝 进入考试页面,开始自动答题");
debugLog("📌 下一步:匹配答案 → 自动选择 → 自动交卷");
huayi.doTest();
} else if (urlTip == "course.aspx" || urlTip == "cme.aspx") {
console.log("当前任务: 课程列表");
debugLog("📚 进入课程列表页面");
debugLog("📌 等待进入视频或考试环节");
huayi.courseList();
} else if (urlTip == "exam_result.aspx") {
console.log("当前任务: 华医考试结果审核");
debugLog("✅ 进入考试结果页面,判断是否通过");
debugLog("📌 下一步:通过则跳转视频,不通过自动重考");
huayi.doResult();
} else {
console.log("其它情况");
debugLog("⚠️ 未知页面类型,不执行任务");
try {
document.querySelector("span[id='tixing']").innerHTML = "此页面非视频、考试或未适配
";
} catch (error) { };
};
function getHuayi() {
return {
courseList: function () {
addAnwserCopybtn();
DelAllAnwser();
},
seeVideo: function (e) {
var tr = localStorage.getItem(keyPlayRate);
var playRateNow = 1;
cleanKeyStorage();
asynckillsendQuestion();
killsendQuestion2();
killsendQuestion3();
addinfo();
window.onload = function () {
localStorage.setItem(keyThisTitle, JSON.stringify(window.document.title));
ratechg(playRateNow);
if (autoSkip == true) {
setTimeout(function () {
skipVideo();
}, (submitTime + Math.ceil(Math.random() * randomX)));
};
clock = setInterval(examherftest, 3000);
switch (e) {
case 1:
window.s2j_onPlayerInitOver()
{
player?.j2s_setVolume(0);
document.querySelector("video").defaultMuted = true;
setTimeout(function () {
try {
player.j2s_resumeVideo();
examherftest();
debugLog("▶️ 保利威视频已自动播放,已静音");
} catch (error) { };
}, 8000);
};
break;
case 2:
window.on_CCH5player_ready()
{
cc_js_Player?.setVolume(0);
document.querySelector("video").defaultMuted = true;
setTimeout(function () {
try {
cc_js_Player.play();
examherftest();
debugLog("▶️ CC视频已自动播放,已静音");
} catch (error) { };
}, 8000);
};
break;
};
};
},
doTest: function () {
var questions = JSON.parse(localStorage.getItem(keyTest)) || {};
var qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
if (JSON.stringify(qRightAnswer) == "{}") {
qRightAnswer = LoadRightAnwser();
debugLog("📚 已加载历史答案库,开始匹配题目");
};
var qTestAnswer = {};
var index = 0;
while (true) {
var question = document.querySelectorAll("table[class='tablestyle']")[index];
if (question == null) break;
var q = question.querySelector(".q_name").innerText.substring(2).replace(/\s*/g, "");
if (qRightAnswer.hasOwnProperty(q)) {
var rightSelection = findAnwser("tbody", index, qRightAnswer[q])
rightSelection.click();
debugLog(`✅ 第${index+1}题:匹配历史答案,已自动选择`);
} else {
if (questions.hasOwnProperty(q)) {
questions[q] = getNextChoice(questions[q]);
} else {
questions[q] = "A";
};
var answer = getChoiceCode(questions[q]);
var element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];
if (!element) {
questions[q] = "A";
answer = getChoiceCode("A");
element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];
};
try {
var answerText = element.innerText.substring(3);
qTestAnswer[q] = answerText;
} catch (error) { };
element.click();
debugLog(`🔄 第${index+1}题:无历史答案,随机选择`);
};
index = index + 1;
};
localStorage.setItem(keyTest, JSON.stringify(questions));
localStorage.setItem(keyTestAnswer, JSON.stringify(qTestAnswer));
debugLog(`📝 全部题目作答完成,等待${submitTime/1000}秒后自动交卷`);
setTimeout(function () {
document.querySelector("#btn_submit").click();
debugLog("📤 已自动提交试卷");
}, (submitTime + Math.ceil(Math.random() * randomX)));
function findAnwser(qakey, index, rightAnwserText) {
var answerslist = document.querySelectorAll(qakey)[index];
var arr = answerslist.getElementsByTagName("label");
for (var i = 0; i < arr.length; i++) {
if (arr[i].innerText.substring(3) == rightAnwserText) {
return arr[i];
};
};
};
function getChoiceCode(an) {
var charin = an || "A";
return charin.charCodeAt(0) - "A".charCodeAt(0);
};
function getNextChoice(an) {
var code = an.charCodeAt(0) + 1;
return String.fromCharCode(code);
};
},
doResult: function () {
var res = $(".tips_text")[0].innerText;
var dds = $(".state_cour_lis");
localStorage.removeItem(keyResult);
if (res == "考试通过" || res == "考试通过!" || res.includes("完成项目学习")) {
console.log("考试通过");
debugLog("🎉 考试通过!答案已保存到本地库");
debugLog(`⏳ 10秒后自动跳回视频页面`);
saveRightAnwser();
SaveAllAnwser();
cleanKeyStorage();
setTimeout(function () {
let host = window.location.host;
let params = new URLSearchParams(window.location.search);
let cwid = params.get("cwid");
let target = `https://${host}/course_ware/course_ware_polyv.aspx?cwid=${cwid}&ff=0&ft=0`;
debugLog("🔗 正在跳转到:" + target);
window.location.href = target;
}, 10000);
} else {
console.log("考试未通过");
debugLog("❌ 考试未通过,记录错题,准备重新考试");
debugLog(`⏳ 等待${reTryTime/1000}秒后自动重考`);
var qWrong = {};
for (var i = 0; i < dds.length; ++i) {
if (!dds[i].querySelector("img").src.includes("bar_img")) {
qWrong[dds[i].querySelector("p").title.replace(/\s*/g, "")] = i
};
};
if (qWrong != {}) {
localStorage.setItem(keyResult, JSON.stringify(qWrong));
saveRightAnwser();
setTimeout(function () {
$("input[type=button][value='重新考试']").click();
debugLog("🔄 已点击重新考试");
}, (reTryTime + Math.ceil(Math.random() * randomX)) * 1);
};
};
},
};
};
function SaveAllAnwser() {
var qAllAnswer = JSON.parse(localStorage.getItem(keyAllAnswer)) || {};
var qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
var qTitle = JSON.parse(localStorage.getItem(keyThisTitle)) || "没有记录到章节名称";
var qOldAnswer = qAllAnswer[qTitle] || {};
for (var q in qRightAnswer) {
qOldAnswer[q] = qRightAnswer[q];
};
qAllAnswer[qTitle] = qOldAnswer;
if (qAllAnswer != null) {
localStorage.setItem(keyAllAnswer, JSON.stringify(qAllAnswer));
};
};
function LoadRightAnwser() {
var qAllAnswer = JSON.parse(localStorage.getItem(keyAllAnswer)) || {};
var qTitle = JSON.parse(localStorage.getItem(keyThisTitle)) || "没有记录到章节名称";
if (qTitle == "没有记录到章节名称") {
return {};
};
var qOldAnswer = qAllAnswer[qTitle] || {};
return qOldAnswer
};
function saveRightAnwser() {
var qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
var qTestAnswer = JSON.parse(localStorage.getItem(keyTestAnswer)) || {};
var qWrongs = JSON.parse(localStorage.getItem(keyResult)) || {};
for (var q in qTestAnswer) {
if (!qWrongs.hasOwnProperty(q)) {
qRightAnswer[q] = qTestAnswer[q];
};
};
localStorage.removeItem(keyTestAnswer);
if (qRightAnswer != null) {
localStorage.setItem(keyRightAnswer, JSON.stringify(qRightAnswer));
};
};
function addAnwserCopybtn() {
let alink = document.createElement("a");
alink.innerHTML = '显示已记录答案';
alink.style = btstyleB;
alink.onclick = function (event) {
var qAllAnswer = JSON.parse(localStorage.getItem(keyAllAnswer)) || {};
var Aout = JSON.stringify(qAllAnswer, null, "\t")
if (document.getElementById("AnwserOut")) {
document.getElementById("AnwserOut").innerHTML = Aout;
} else {
let textout = document.createElement("textarea");
textout.id = "AnwserOut";
textout.innerHTML = Aout;
textout.rows = 20;
textout.cols = 30;
document.getElementById("main_div").parentNode.append(textout);
};
};
document.getElementById("main_div").parentNode.append(alink);
};
function DelAllAnwser() {
let alink = document.createElement("a");
alink.innerHTML = '清除已记录答案';
alink.style = btstyleB;
alink.onclick = function (event) {
var r = confirm("确定清除历史答案?!");
if (r) {
localStorage.removeItem(keyAllAnswer);
};
};
document.getElementById("main_div").parentNode.append(alink);
};
function skipVideo() {
var oVideo = document.getElementsByTagName('video')[0];
if (oVideo) {
oVideo.currentTime = oVideo.duration - 1
};
};
function clickexam() {
setTimeout(function () {
document.querySelector("#jrks").click();
}, (Math.ceil(Math.random() * randomX)));
};
function ratechg(ra) {
var videoObj = document.querySelector("video")
try {
clearInterval(nspeed);
nspeed = setInterval(() => {
videoObj.playbackRate = ra;
}, 1000);
localStorage.setItem(keyPlayRate, ra);
} catch (error) { };
};
// ===================== 旧版模式切换函数(保留不删除) =====================
function addinfo() {
debugLog("ℹ️ 视频页面初始化完成,运行正常");
};
function cleanKeyStorage() {
localStorage.removeItem(keyTest);
localStorage.removeItem(keyResult);
localStorage.removeItem(keyTestAnswer);
localStorage.removeItem(keyRightAnswer);
};
function examherftest() {
var hreftest = document.getElementById("jrks").attributes["disabled"];
var state = document.querySelectorAll("i[id='top_play']")[0].parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText;
if (state == "已完成" || state == "待考试" || !hreftest) {
if (localStorage.getItem("华医mode") == "2" && state == "待考试") {
debugLog("📌 视频播放完成,模式:视频+考试,自动进入考试");
try {
clickexam();
} catch (error) { };
} else {
debugLog("📌 视频播放完成,寻找下一个视频");
const targetElements = document.querySelectorAll("i[id='top_play']");
const parentElement = targetElements[0].parentElement;
const grandparentElement = parentElement.parentElement;
const lis = document.querySelectorAll("li[class='lis-inside-content']");
var index = Array.from(lis).findIndex(li => li === grandparentElement);
if (index + 2 <= document.querySelectorAll("li[class='lis-inside-content']").length) {
index += 2;
document.querySelector("#top_body > div.video-container > div.page-container > div.page-content > ul > li:nth-child(" + index + ") > h2").click();
setTimeout(function () {
document.evaluate("//button[contains(., '知道了')]", document, null, XPathResult.ANY_TYPE).iterateNext().click();
}, 2000);
} else {
if ($('button:contains("未学习")').length > 0) {
$('button:contains("未学习")').siblings().eq(0).click();
} else if ($('button:contains("学习中")').length > 0) {
$('button:contains("学习中")').siblings().eq(0).click();
} else if ($('button:contains("待考试")').length > 0 && localStorage.getItem("华医mode") == "2") {
$('button:contains("待考试")').siblings().eq(0).click();
} else {
debugLog("✅ 全部课程学习完成!");
clearInterval(clock);
};
};
};
};
};
function sleep(timeout) {
return new Promise((resolve) => { setTimeout(resolve, timeout); });
};
function asynckillsendQuestion() {
(async function () {
while (!window.player || !window.player.sendQuestion) {
await sleep(20);
};
player.sendQuestion = function () { };
})();
};
function killsendQuestion2() {
if (typeof (isInteraction) != "undefined") {
isInteraction = "off";
};
};
function killsendQuestion3() {
var clockms = setInterval(async function () {
try {
if ($('.pv-ask-head').length > 0) {
$(".pv-ask-skip").click();
debugLog("🧹 已自动关闭弹窗问题");
};
} catch (err) { };
try {
if ($('.signBtn').length > 0) {
$(".signBtn").click();
debugLog("🧹 已自动关闭签到弹窗");
};
} catch (err) { };
try {
if ($("button[onclick='closeProcessbarTip()']").length > 0) {
$("button[onclick='closeBangZhu()']").click();
$("button[onclick='closeProcessbarTip()']").click();
debugLog("🧹 已自动关闭提示弹窗");
};
} catch (err) { };
try {
if ($("button[class='btn_sign']").length > 0) {
$("button[class='btn_sign']").click();
};
} catch (err) { };
try {
var state = document.querySelectorAll("i[id='top_play']")[0].parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText;
if ($('video').prop('paused') == true && state != "已完成" && state != "待考试") {
$('video').get(0).play();
$('video').prop('muted') = true;
debugLog("▶️ 视频意外暂停,已自动恢复播放");
} else if (state == "已完成") {
document.querySelector("video").pause();
};
} catch (err) { };
}, 10000);
};
function advis() {
let div1 = document.createElement("div");
div1.innerHTML = `
`;
document.body.append(div1);
let clo = document.querySelector("span[id='clo']");
clo.onclick = function () {
document.querySelector("div[id='Div1']").style.display = "none";
};
};
})();