// ==UserScript==
// @name 🥇【免费华医网小助手]
// @namespace http://tampermonkey.net/
// @version 3.0.8
// @description 自动播放,自动考试
// @author 原创作者:Dr.S 改编(宾利) V: zyswk8888
// @license AGPL License
// @match *://*.91huayi.com/*
// @grant none
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFUAAABVCAMAAAAPK1hoAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkU1NDU0RjFGQkVEQTExRjA5RDY0QzBFNkQ3ODU5NDNCIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkU1NDU0RjIwQkVEQTExRjA5RDY0QzBFNkQ3ODU5NDNCIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RTU0NTRGMURCRURBMTFGMDlENjRDMEU2RDc4NTk0M0IiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RTU0NTRGMUVCRURBMTFGMDlENjRDMEU2RDc4NTk0M0IiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz45FESoAAADAFBMVEUSislxlqkthLY4pv////9uprN67/8FL14XVor9/vgjhcmGiIf55tjbxbichXGrucVNhJqI9f/q29BMTlFRZ3DS4+5ZpMRXm7e0ytju7u7k5OMAUKJHr/GE6v4zm/4klv4qp/8vUmT/9eX8/PdofInQuq1ps8nn1clIntEYpP8Wd7zz8vEid7ewo5pbobaEmagWe8rT09PCw8InQ1E5sv8ris8YmP66vb6kpKKVt880fKg1jMeVo614enmXq7isrKqx0uxjqr/c29qos7z+/vuOzNNww9drxuuzs7Fcl64tXYZkaGmSk5ItMDOom5IZS3UlY5ebnJt1yOVYc4X07uu6w8ossf8lj/2vxdZEdH4DAQFPlLRLxP83YHVkhZp1hZiGe2wVg775+Pi4qJ/Ky8zCpJIGdsdAWGi7//9diqjJztNVtNg0mOVlt9dGeZOT//8AdObZ3eJ00f739fR94P/j3twnfr4GfNcwjNgnaIGGo7kGaLWekYIudaoWXZc6aYUBbcZ2gIc4fJb+/PsTLjvCsaRn3Pzg1Mpst79YqND13c0GYqYXabIMjPiMl51szPhLiakjaaUDhOQYX6qDjZY+mbr7/Px31/x33P0+hJ0ffs8OmPwYjvhpdX78+vpEZH9nkZnCys2YjH57alrm5uXa8PlpanZYfZATb8QfkMzjzL91z/cbeahyus/Y19Y3erYBZNZAjbYJf8Fai7h30fC3urp3j5ykqq12bGapqqmek5RHrcxEfrMLERfu6ueNj
//脚本捐赠不会开启新的功能,所以无需声明antifeature
// ==/UserScript==
var newupdate = "";
(function () {
'use strict';
var submitTime = 6100;
var reTryTime = 2100;
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 mmcode = `data:image/gif;base64,R0lGODlh8QHxAfcAALOdW85ucfrWzNSWNfPz84qEiMnJyc2ZNS4uLri4uPvn3/vz7NC1svGKdKamptCMiceZR+vSl/fl3s2wcJqamvvFxdO4he/v73d3d7ZHUfe5qPfGtWdnZ/fv5ol8iNKEdOXl5f7+81hXV97d3QQEBEdHR/u+w9XV1c5baPiXhfinmehmZ9zEjfvz5/vb0+qWm/iIhPvU0rZxbdSZLLY6RPZ5ePfX1tlWWv742clJVPfkuNV5gvfb1vvOy+p4dcijWeeYiNhJVc6aKvbOzRYWFva9ucc6R+jIyJ8yO/mljOvZ1uV4acZCS62XgmxRUuykl+taZPjVvIlxcvrqx//+7dNrXfvv6/338tnGsvvLxue5tvqzmPve29rFy/ickvfu6+NSXPbGw+rXp7NlW/vn48lRXOfO1OuzqdW6xerXzLmjiff+/evGueOppZFMOPbZpuratuildueJgt7H05RTTv/943RdYvrDrvff2vWvoeXMoU1YLPXNxLxYY/VscndkadfDfZSGifzr3lQ3NP30z7mnovJkbO3i3b+XPPbz7pBlYHI7PtJCTndrc/f999Kfn25nSupsbvjP05SLkYiLVP33/O/f3+G6gM+eNfCZoFhGSPvGy/Xn4/Tj0vJzb5NbYOFhYP7u0fvj2tnRzPCpg/ayi6mdn/b+7shQTVdNUuC+mOzszO7l5OLV0siRNe/z9LKysignIN7j5evr6+KvsdJUUffz5/Xr4MPDw9mQOL4yPNSVHqKRfdbb3OCWMu/z7h0ZGJCQkLG1s1FRUY6DjxMVDe/t9ePn7L6+vlpQT/bs0ufr68THl357fj5BOQkJCfv7+yQeIfvr4/vv5///+vv///vv4//7//v/+v/r4//7+vfX2/rr5/v7///v6PfHyP/r5//w4Nvb2/zX1/3fnfPv8hENEOvn6nFxcff39yIiIl9fXxwcHM/PzwoOChAQEEFBQd+RlG1tbdfb19vX2E1NTdeSLeLj39/f366qr66ursOuqjs6Ov7+/gAAAP///yH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgOS4wLWMwMDAgNzkuMTcxYzI3ZmFiLCAyMDIyLzA4LzE2LTIyOjM1OjQxICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjQuMCAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OUJFNEVGRjNDMDAxMTFGMDg0NTZBQjVBRTk3QTVDQkMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OUJFNEVGRjRDMDAxMTFGMDg0NTZBQjVBRTk3QTVDQkMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5QkU0RUZGMUMwMDExMUYwODQ1NkFCNUFFOTdBNUNCQyIgc3RSZWY6ZG9jdW1lbnRJ`;
var clock = null;
var testtest = true;
advis();
createStatusPanel();
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "当前网址已适配ヾ(๑╹◡╹)ノ"
失效请赞赏联系  ε(┬┬﹏┬┬)3";
}
if (urlTip == "course_ware_polyv.aspx") {
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(1);
} else if (urlTip == "course_ware_cc.aspx") {
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(2);
} else if (urlTip == "face.aspx") {
console.log("当前任务: 刷脸界面");
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })();
} else if (urlTip == "course.aspx" || urlTip == "cme.aspx") {
console.log("当前任务: 课程列表");
huayi.courseList();
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })();
} else if (urlTip == "exam.aspx") {
console.log("当前任务: 华医考试");
huayi.doTest();
} else if (urlTip == "exam_result.aspx") {
console.log("当前任务: 华医考试结果审核");
huayi.doResult();
} else {
console.log("其它情况");
try {
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "此页面非视频、考试或未适配";
}
document.querySelector("img[id='Pic']").style.display = "block";
} catch (error) { };
};
function getHuayi() {
return {
courseList: function () {
addAnwserCopybtn();
addImportAnswerBtn();
DelAllAnwser();
},
seeVideo: function (e) {
var tr = localStorage.getItem(keyPlayRate);
var playRateNow = 1;
cleanKeyStorage();
asynckillsendQuestion();
killsendQuestion2();
killsendQuestion3();
addinfo();
changelayout();
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)));
console.log("秒过了!");
};
clock = setInterval(examherftest, 3000);
}
console.log('🎬 视频页面加载完成,开始保存/更新课程列表');
saveCourseList();
if (testtest) { addContinuousExamButton(); }
checkFaceVerificationReturn();
switch (e) {
case 1:
if (typeof window.s2j_onPlayerInitOver === 'function') {
window.s2j_onPlayerInitOver();
}
{
if (typeof player !== 'undefined' && player && player.j2s_setVolume) {
try {
player.j2s_setVolume(0);
console.log("保利威播放器静音成功");
} catch (error) {
console.log("保利威播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
if (typeof player !== 'undefined' && player && player.j2s_resumeVideo) {
player.j2s_resumeVideo();
}
examherftest();
} catch (error) {
console.log("上一段代码有误");
};
}, 8000);
};
killsendQuestion3();
break;
case 2:
if (typeof window.on_CCH5player_ready === 'function') {
window.on_CCH5player_ready();
}
{
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.setVolume) {
try {
cc_js_Player.setVolume(0);
console.log("CC播放器静音成功");
} catch (error) {
console.log("CC播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.play) {
cc_js_Player.play();
}
examherftest();
} catch (error) {
console.log("上一段代码有误");
};
}, 8000);
};
break;
default:
console.log("其他播放器?");
};
},
doTest: function () {
var questions = JSON.parse(localStorage.getItem(keyTest)) || {};
var qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
if (JSON.stringify(qRightAnswer) == "{}") {
qRightAnswer = LoadRightAnwser();
};
var qTestAnswer = {};
var index = 0;
while (true) {
var question = document.querySelectorAll("table[class='tablestyle']")[index];
if (question == null) break;
else {
var rawQuestion = question.querySelector(".q_name").innerText.substring(2);
var q = cleanQuestionText(rawQuestion);
console.log(q);
if (qRightAnswer.hasOwnProperty(q)) {
var rightSelection = findAnwser("tbody", index, qRightAnswer[q])
if (rightSelection) {
rightSelection.click();
}
} 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) {
console.log("找不到选项,选项更改为A index: " + index + " answer: " + answer);
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) { console.log("答案文本获取失败A:" + error); };
if (element) {
element.click();
}
};
index = index + 1;
};
};
localStorage.setItem(keyTest, JSON.stringify(questions));
localStorage.setItem(keyTestAnswer, JSON.stringify(qTestAnswer));
setTimeout(function () {
var submitButton = document.querySelector("#btn_submit");
if (submitButton) {
submitButton.click();
}
}, (submitTime + Math.ceil(Math.random() * randomX)));
function findAnwser(qakey, index, rightAnwserText) {
var answerslist = document.querySelectorAll(qakey)[index];
if (!answerslist) return null;
var arr = answerslist.getElementsByTagName("label");
console.log(`查找答案: ${rightAnwserText}`);
for (var i = 0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText===rightAnwserText) {
console.log(`✅ 精确匹配: ${optionText}`);
return arr[i];
}
}
for (var i=0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText.includes(rightAnwserText) || rightAnwserText.includes(optionText)) {
console.log(`🔍 模糊匹配: ${optionText}`);
return arr[i];
}
}
console.log(`❌ 未找到匹配答案,使用第一个选项`);
return arr[0];
}
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] ? $(".tips_text")[0].innerText : null;
var dds=$(".state_cour_lis");
localStorage.removeItem(keyResult);
if (res=="考试通过" || res=="考试通过!" || res=="完成项目学习可以申请学分了" ) {
console.log("考试通过");
saveRightAnwser();
SaveAllAnwser();
cleanKeyStorage();
checkExamContinuation();
setTimeout(function () {
}, 1000);
} else {
console.log("考试未通过")
var tipsTextElement=document.querySelector("p[class='tips_text' ]");
if (tipsTextElement) {
tipsTextElement.innerText="本次未通过,正在尝试更换答案\r\n(此为正常现象,脚本几秒后刷新,请勿操作)"
}
var qWrong={};
for (var i=0; i < dds.length; ++i) {
if (dds[i].querySelector("img") && !dds[i].querySelector("img").src.includes("bar_img")) {
var rawQuestion=dds[i].querySelector("p").title;
var cleanedQuestion=cleanQuestionText(rawQuestion);
qWrong[cleanedQuestion]=i
};
};
if (qWrong !={}) {
localStorage.setItem(keyResult, JSON.stringify(qWrong));
saveRightAnwser();
setTimeout(function () {
$("input[type=button][value='重新考试' ]").click();
}, (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=="没有记录到章节名称" ) {
console.log("没找到章节名称");
return {};
};
var qOldAnswer=qAllAnswer[qTitle] || {};
return qOldAnswer
};
function cleanQuestionText(questionText) {
if (!questionText) return '' ;
let cleaned=questionText
.replace(/[??]/g, '' )
.replace(/||[\u200B-\u200D\uFEFF]/g, '' )
.replace(/\s+/g, ' ' )
.trim();
cleaned=cleaned.replace(/^\d+、/, '' ).trim();
cleaned=cleaned.replace(/[((]\s*[))]/g, '' )
.replace(/[((]\s*([^))\s]+)\s*[))]/g, '$1' )
.trim();
return cleaned;
}
function getQuestionText(questionElement) {
try {
let rawText=questionElement.querySelector(".q_name").innerText;
let textWithoutNumber=rawText.replace(/^\d+、/, '' );
return cleanQuestionText(textWithoutNumber);
} catch (error) {
console.log("获取题目文本错误:", error);
return "" ;
}
}
function saveRightAnwser() {
var qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
var qTestAnswer=JSON.parse(localStorage.getItem(keyTestAnswer)) || {};
var qWrongs=JSON.parse(localStorage.getItem(keyResult)) || {};
console.log("开始保存正确答案...");
console.log("错题记录:", qWrongs);
console.log("测试答案:", qTestAnswer);
var cleanedWrongs={};
for (var wrongQ in qWrongs) {
var cleanedWrongQ=cleanQuestionText(wrongQ);
cleanedWrongs[cleanedWrongQ]=true;
console.log(`错题清洗: "${wrongQ}" -> "${cleanedWrongQ}"`);
}
for (var q in qTestAnswer) {
var cleanedQ = cleanQuestionText(q);
console.log(`处理题目: "${q}" -> "${cleanedQ}", 答案: ${qTestAnswer[q]}`);
if (!cleanedWrongs[cleanedQ]) {
console.log(`✅ 正确答案: "${cleanedQ}" -> ${qTestAnswer[q]}`);
qRightAnswer[cleanedQ] = qTestAnswer[q];
} else {
console.log(`❌ 错误题目: "${cleanedQ}" -> ${qTestAnswer[q]}`);
}
}
localStorage.removeItem(keyTestAnswer);
if (Object.keys(qRightAnswer).length > 0) {
localStorage.setItem(keyRightAnswer, JSON.stringify(qRightAnswer));
console.log("✅ 正确答案已保存:", qRightAnswer);
} else {
console.log("❌ 没有正确答案需要保存");
}
}
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;
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(textout);
}
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.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);
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
function skipVideo() {
var oVideo = document.getElementsByTagName('video')[0];
if (oVideo) {
oVideo.currentTime = oVideo.duration - 1
};
};
function addImportAnswerBtn() {
let alink = document.createElement("a");
alink.innerHTML = '导入答案';
alink.style = btstyleB;
alink.onclick = function (event) {
var input = prompt("请粘贴要导入的答案数据(JSON格式)");
if (input) {
try {
var importedAnswers = JSON.parse(input);
var existingAnswers = JSON.parse(localStorage.getItem(keyAllAnswer)) || {};
var mergedAnswers = mergeAnswerData(existingAnswers, importedAnswers);
localStorage.setItem(keyAllAnswer, JSON.stringify(mergedAnswers));
alert("✅ 答案导入成功!\n已合并 " + Object.keys(importedAnswers).length + " 个章节的答案");
} catch (error) {
alert("❌ 导入失败:数据格式不正确\n" + error);
}
}
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
function mergeAnswerData(existing, imported) {
var merged = JSON.parse(JSON.stringify(existing));
for (var chapter in imported) {
if (imported.hasOwnProperty(chapter)) {
if (!merged[chapter]) {
merged[chapter] = imported[chapter];
} else {
for (var question in imported[chapter]) {
if (imported[chapter].hasOwnProperty(question)) {
merged[chapter][question] = imported[chapter][question];
}
}
}
}
}
return merged;
};
function clickexam() {
console.log("已点击考试按钮");
setTimeout(function () {
var examButton = document.querySelector("#jrks");
if (examButton) {
examButton.click();
}
}, (Math.ceil(Math.random() * randomX)));
};
function addSkipbtn() {
let alink = document.createElement("a");
alink.innerHTML = '快进视频';
alink.style = btstyleA;
alink.onclick = function (event) {
skipVideo();
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
};
function addratebtn(ra) {
let alink = document.createElement("a");
alink.innerHTML = '' + ra + 'x';
alink.style = btstyleB;
alink.className = "speed";
alink.id = ra + "x";
alink.onclick = function (event) {
ratechg(ra);
try {
var arr = document.querySelectorAll("a[class='speed']");
arr.forEach(function (item, index, arr) {
arr[index].style = btstyleB;
});
} catch (error) {
};
alink.style = btstyleC;
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
}
function ratechg(ra) {
var videoObj = document.querySelector("video")
if (videoObj) {
try {
clearInterval(nspeed);
nspeed = setInterval(() => {
videoObj.playbackRate = ra;
}, 1 * 1000);
localStorage.setItem(keyPlayRate, ra);
} catch (error) { console.log("倍率调整错误" + error); };
}
};
function addrateinfo() {
let adiv1 = document.createElement("div");
adiv1.innerHTML = '当前播放速率';
adiv1.id = 'playrate';
adiv1.style = "font-size: 15px;text-align: center;margin-top: 10px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv1);
}
};
function addinfo() {
var moderesult = localStorage.getItem("华医mode");
if (moderesult == 2) {
moderesult = "当前模式:视频+考试";
} else {
moderesult = "当前模式:单刷视频";
};
var checkbox = document.createElement('div');
checkbox.innerHTML = '' + moderesult + '
[点击此处切换] ';
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(checkbox);
}
let mode1 = document.querySelector("a[id='mode']");
if (mode1) {
mode1.onclick = function () {
if (mode1.innerText == "当前模式:单刷视频\n[点击此处切换]") {
mode1.innerText = "当前模式:视频+考试\n[点击此处切换]";
localStorage.setItem("华医mode", "2");
} else {
mode1.innerText = "当前模式:单刷视频\n[点击此处切换]";
localStorage.setItem("华医mode", "1");
};
};
}
let adiv2 = document.createElement("div");
adiv2.innerHTML = '       本人医学研一学生,经常要帮师兄师姐刷华医视频,属实太累。偶然在抖音发现Dr.S的脚本,结果刷完1个视频立刻考试,导致频繁人脸识别跟手动区别不大。原作者已不更新,于是我自学修改了播放逻辑,实现无人值守连续播放。现将原先自用的脚本分享给大家❤❤
     刷完视频再切换考试模式,即可连续考试。
';
adiv2.id = 'jsinfo';
adiv2.style = "position:relative;left:10px;top:5px;width:240px;font-size:13px;text-align: justify;border: 1px dashed #ff9595;padding:5px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv2);
}
if (typeof $ !== 'undefined') {
$('div:contains("观看视频完成后,才能进入考试")').eq(-1).text('建议360安全浏览器和脚本猫');
}
let examBtnContainer = document.createElement('div');
examBtnContainer.id = 'continuousExamBtnContainer';
examBtnContainer.style = "text-align: center; margin: 10px 0;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(examBtnContainer);
}
};
function changelayout() {
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv) {
jjDiv.remove();
}
var photoImg = document.querySelector("img[id='photo']");
if (photoImg) {
photoImg.outerHTML = `
`;
photoImg.style.width = "120px";
photoImg.style.height = "120px";
}
var titleDivs = document.querySelectorAll("div[class='title']");
if (titleDivs[0] && titleDivs[0].children[0]) {
titleDivs[0].children[0].style = "color: #ff0000;font-weight: bold";
titleDivs[0].children[0].innerText = "支持作者";
}
var imgTextDivs = document.querySelector("div[class='imgtext']");
if (imgTextDivs && imgTextDivs.children[1]) {
imgTextDivs.children[1].style.width = "125px";
imgTextDivs.children[1].style = "color: #ff0000;padding-top:10px";
imgTextDivs.children[1].innerText = "作 者\n创作优化不易\n投点小费吧\n❤谢啦❤\n❤"
}
var topDiv = document.querySelector("div[class='top']");
if (topDiv) {
topDiv.outerHTML = '如服务器调整,脚本可能失效。反馈意见、免费增加课程请在Greasyfork私信或脚本反馈区联络。也欢迎投喂↓
';
}
};
function cleanKeyStorage() {
localStorage.removeItem(keyTest);
localStorage.removeItem(keyResult);
localStorage.removeItem(keyTestAnswer);
localStorage.removeItem(keyRightAnswer);
};
function examherftest() {
var examButton = document.getElementById("jrks");
var hreftest = examButton ? examButton.attributes["disabled"] : null;
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if ((state == "已完成" || state == "待考试" || !hreftest) && examButton) {
console.log("已经播放完了");
var modeElement = document.querySelector("a[id='mode']");
if (modeElement && modeElement.innerText.indexOf("视频+考试") != -1 && state == "待考试") {
console.log("mode=2,准备进入考试");
var retryCount = 0;
var maxRetries = 5;
function tryEnterExam() {
retryCount++;
console.log(`尝试进入考试 (第${retryCount}次)`);
try {
if (document.getElementById("jrks") && !document.getElementById("jrks").disabled) {
document.getElementById("jrks").click();
console.log("成功点击考试按钮");
return true;
}
if (typeof cwrid !== 'undefined') {
window.open("/pages/exam_tip.aspx?cwrid=" + cwrid, "_self");
console.log("尝试备用方式进入考试");
return true;
}
var currentUrl = window.location.href;
if (currentUrl.includes("course_ware")) {
var examUrl = currentUrl.replace("course_ware/course_ware_", "pages/exam.aspx?cwid=")
.split("?")[0] + "?cwid=" + getUrlParam("cwid");
window.location.href = examUrl;
console.log("尝试通过URL跳转进入考试");
return true;
}
} catch (error) {
console.log(`第${retryCount}次尝试失败:`, error);
}
return false;
}
if (tryEnterExam()) {
return;
}
var retryInterval = setInterval(function () {
if (retryCount >= maxRetries) {
clearInterval(retryInterval);
console.log(`尝试${maxRetries}次进入考试均失败,继续听课`);
proceedToNextVideo();
} else if (tryEnterExam()) {
clearInterval(retryInterval);
}
}, 2000);
} else {
proceedToNextVideo();
};
} else {
}
}
function proceedToNextVideo() {
console.log('🚀 准备跳转到下一个视频...');
const nextCwid = getNextCourseCwid();
if (nextCwid) {
console.log(`✅ 确定跳转到课程: ${nextCwid.substring(0, 8)}...`);
console.log(`🌐 跳转URL: course_ware.aspx?cwid=${nextCwid}`);
setTimeout(() => {
console.log('⏩ 正在跳转...');
window.location.href = `course_ware.aspx?cwid=${nextCwid}`;
}, 2000);
} else {
console.log('❌ 没有找到可用的课程,尝试刷新页面');
setTimeout(() => {
console.log('🔄 正在刷新页面...');
window.location.reload();
}, 2000);
}
}
function getUrlParam(name) {
var urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
};
function sleep(timeout) {
return new Promise((resolve) => { setTimeout(resolve, timeout); });
console.log("课堂问答循环调用");
};
function asynckillsendQuestion() {
(async function () {
while (!window.player || !window.player.sendQuestion) {
await sleep(20);
};
player.sendQuestion = function () {
};
})();
};
function killsendQuestion2() {
if (typeof (isInteraction) == "undefined") {
} else {
console.log('isInteraction设置off');
isInteraction = "off";
};
};
function killsendQuestion3() {
var clockms = setInterval(async function () {
try {
if (typeof $ !== 'undefined' && $('.pv-ask-head').length && $('.pv-ask-head').length > 0) {
console.log("检测到问题对话框,尝试跳过");
$(".pv-ask-skip").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.signBtn').length && $('.signBtn').length > 0) {
console.log("检测到签到对话框,尝试跳过");
$(".signBtn").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' &&
$("button[onclick='closeProcessbarTip()']").length &&
$("button[onclick='closeProcessbarTip()']").length > 0 &&
$("div[id='div_processbar_tip']").css("display") == "block") {
console.log("检测到温馨提示对话框(不能拖拽),尝试跳过");
$("button[onclick='closeBangZhu()']").click();
$("button[onclick='closeProcessbarTip()']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $("button[class='btn_sign']").length && $("button[class='btn_sign']").length > 0) {
console.log("检测到温馨提示对话框(疲劳提醒),尝试跳过");
$("button[class='btn_sign']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.rig_btn').length && $('.rig_btn').length > 0) {
if ($('#div_processbar_tip').is(':visible')) {
console.log("检测到按钮(知道了),执行隐藏操作");
$('#div_processbar_tip').hide();
}
};
} catch (err) {
console.log(err);
};
try {
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if (typeof $ !== 'undefined' &&
$('video').prop('paused') == true &&
state != "已完成" &&
state != "待考试") {
console.log("视频意外暂停,恢复播放");
$('video').get(0).play();
$('video').prop('muted') = true;
} else if (state == "已完成") {
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.pause();
}
};
} catch (err) {
};
}, 10000);
};
function autoClickKnowButton() {
const observer = new MutationObserver(() => {
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
observer.disconnect();
button.click();
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
button.click();
}
}
function saveCourseList() {
console.log('📋 开始保存/更新课程列表...');
const courseContainer = document.querySelector('.page-container');
if (!courseContainer) {
console.log('❌ 未找到课程列表容器');
return;
}
const courseItems = document.querySelectorAll('.lis-inside-content');
if (courseItems.length === 0) {
console.log('❌ 未找到课程项');
return;
}
console.log(`📚 找到 ${courseItems.length} 个课程项,开始解析...`);
const currentCourseList = [];
let hasChanges = false;
courseItems.forEach((item, index) => {
const titleElement = item.querySelector('h2');
const statusButton = item.querySelector('button');
if (titleElement && statusButton) {
const title = titleElement.textContent.trim();
const status = statusButton.textContent.trim();
const statusColor = statusButton.style.background;
const onclickAttr = titleElement.getAttribute('onclick');
let cwid = '';
if (onclickAttr) {
const match = onclickAttr.match(/cwid=([^']+)/);
if (match && match[1]) {
cwid = match[1];
}
}
if (cwid) {
currentCourseList.push({
title,
status,
statusColor,
cwid,
index
});
}
}
});
if (currentCourseList.length === 0) {
console.log('❌ 未解析到任何课程信息');
return;
}
const previousCourseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
if (previousCourseList.length === 0) {
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`✅ 首次保存课程列表完成,共 ${currentCourseList.length} 个课程`);
return;
}
console.log('🔍 检查课程状态变化...');
for (let i = 0; i < currentCourseList.length; i++) {
const currentCourse=currentCourseList[i];
const previousCourse=previousCourseList[i];
if (!previousCourse) {
console.log(` 新增课程: "${currentCourse.title}" `);
hasChanges=true;
continue;
}
if (currentCourse.status !==previousCourse.status) {
console.log(` 状态变化: "${currentCourse.title}" - ${previousCourse.status} → ${currentCourse.status}`);
hasChanges=true;
}
if (currentCourse.title !==previousCourse.title) {
console.log(` 标题变化: "${previousCourse.title}" → "${currentCourse.title}" `);
hasChanges=true;
}
if (currentCourse.cwid !==previousCourse.cwid) {
console.log(` cwid变化: "${currentCourse.title}" `);
hasChanges=true;
}
}
if (currentCourseList.length !==previousCourseList.length) {
console.log(` 课程数量变化: ${previousCourseList.length} → ${currentCourseList.length}`);
hasChanges=true;
}
if (hasChanges) {
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`🔄 课程列表已更新,共 ${currentCourseList.length} 个课程`);
console.log('📊 当前所有课程状态:');
currentCourseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
} else {
console.log('✅ 课程列表无变化,无需更新');
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
}
}
function getCurrentCourseCwid() {
const urlParams = new URLSearchParams(window.location.search);
const cwid = urlParams.get('cwid');
console.log(`🔍 当前课程 cwid: ${cwid ? cwid.substring(0, 8) + '...' : '未找到'}`);
return cwid;
}
function getNextCourseCwid() {
console.log('🔄 开始查找下一个课程...');
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
const currentCwid = getCurrentCourseCwid();
if (courseList.length === 0) {
console.log('❌ 未找到存储的课程列表');
return null;
}
console.log(`📊 课程列表中有 ${courseList.length} 个课程`);
const currentIndex = courseList.findIndex(course => course.cwid === currentCwid);
if (currentIndex === -1) {
console.log('❌ 未找到当前课程在列表中的位置');
console.log('当前课程可能不在列表中,将尝试第一个未完成的课程');
for (let i = 0; i < courseList.length; i++) {
const course=courseList[i];
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到第一个未完成课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
return null;
}
console.log(`📍 当前课程位置: 第 ${currentIndex + 1} 个 - "${courseList[currentIndex].title}" `);
console.log('🔍 向后查找未完成的课程...');
for (let i=currentIndex + 1; i < courseList.length; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到下一个课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('🔍 向后未找到,从开头查找未完成的课程...');
for (let i=0; i < currentIndex; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到前面的课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
console.log('所有课程状态:');
courseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
return null;
}
function advis() {
if (window.self !== window.top) {
console.log('小助手:当前处于 iframe 中,不创建面板');
return;
}
const existingPanel = document.getElementById('Div1');
if (existingPanel) {
console.log('已检测到小助手面板,防止重复创建');
return;
}
let div1 = document.createElement("div");
div1.innerHTML = `
`;
document.body.append(div1);
let share1 = document.getElementById('Share1');
let share2 = document.getElementById('Share2');
let clo = document.getElementById('clo');
if (share1) {
share1.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/500010", "_blank");
};
}
if (share2) {
share2.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/555651", "_blank");
};
}
if (clo) {
clo.onclick = function () {
var panel = document.getElementById('Div1');
if (panel) {
panel.style.display = 'none';
}
};
}
const panel = document.getElementById('Div1');
if (!panel) return;
const container = document.querySelector('.page-container') ||
document.querySelector('.lis-content') ||
document.querySelector('.container-inside-header');
let initialLeft = 140;
if (container) {
const rect = container.getBoundingClientRect();
initialLeft = rect.left + window.pageXOffset;
}
panel.style.left = initialLeft + 'px';
let isDragging = false;
let offsetX, offsetY;
panel.addEventListener('mousedown', function (e) {
if (e.target === clo ||
e.target.tagName === 'A' ||
e.target.tagName === 'IMG' ||
e.target.tagName === 'HR') return;
isDragging = true;
offsetX = e.clientX - panel.getBoundingClientRect().left;
offsetY = e.clientY - panel.getBoundingClientRect().top;
e.preventDefault();
});
document.addEventListener('mousemove', function (e) {
if (!isDragging) return;
panel.style.left = (e.clientX - offsetX) + 'px';
panel.style.top = (e.clientY - offsetY) + 'px';
});
document.addEventListener('mouseup', () => {
isDragging = false;
});
}
function addContinuousExamButton() {
if (document.getElementById('continuousExamBtn')) {
return;
}
let btn = document.createElement("a");
btn.innerHTML = '连续考试';
btn.style = btstyleA
btn.id = 'continuousExamBtn';
btn.onclick = function () {
console.log('🚀 开始连续考试流程...');
startContinuousExam();
};
const tipDiv = document.querySelector('div.r div[style*="border: 1px dashed #ff9595"]');
if (tipDiv) {
let btnContainer = document.createElement('div');
btnContainer.style = "text-align: center; margin: 10px 0;";
btnContainer.appendChild(btn);
tipDiv.parentNode.insertBefore(btnContainer, tipDiv.nextSibling);
} else {
const btnContainer = document.getElementById('continuousExamBtnContainer');
if (btnContainer) {
btnContainer.appendChild(btn);
} else {
document.body.appendChild(btn);
}
}
}
function createStatusPanel() {
const examPhase = localStorage.getItem('exam_phase');
if (!examPhase) {
const existingPanel = document.getElementById('examStatusPanel');
if (existingPanel) {
existingPanel.remove();
}
return;
}
if (document.getElementById('examStatusPanel')) {
updatePanelContent();
return;
}
const panel = document.createElement('div');
panel.id = 'examStatusPanel';
panel.style = `
position: fixed;
top: 20px;
right: 20px;
width: 300px;
background-color: rgba(255, 255, 255, 0.95);
border: 2px solid #4cb0f9;
border-radius: 8px;
padding: 15px;
z-index: 10000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
font-family: 'Microsoft YaHei', sans-serif;
`;
panel.innerHTML = `
连续考试状态
加载中...
`;
document.body.appendChild(panel);
var cancelBtn = document.getElementById('cancelExamBtn');
if (cancelBtn) {
cancelBtn.onclick = function () {
if (confirm('确定要取消连续考试吗?')) {
cancelContinuousExam();
}
};
}
updatePanelContent();
function updatePanelContent() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examPhase = localStorage.getItem('exam_phase');
let statusMessage = '';
if (examPhase === 'face_verification') {
statusMessage = `👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else if (examPhase === 'examination') {
statusMessage = `📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else {
statusMessage = '连续考试进行中...';
}
const contentElement = document.getElementById('examStatusContent');
if (contentElement) {
contentElement.innerHTML = statusMessage;
}
}
}
function updateExamStatus(message, isError = false) {
createStatusPanel();
const panel = document.getElementById('examStatusPanel');
if (!panel) {
console.log('状态面板不存在,跳过更新');
return;
}
panel.style.display = 'block';
const statusContent = document.getElementById('examStatusContent');
if (statusContent) {
statusContent.innerHTML = message;
statusContent.style.color = isError ? '#f15854' : '#333';
}
}
function cancelContinuousExam() {
console.log('❌ 结束连续考试');
localStorage.removeItem('exam_courses');
localStorage.removeItem('current_exam_index');
localStorage.removeItem('exam_phase');
const panel = document.getElementById('examStatusPanel');
if (panel) {
updateExamStatus('连续考试已取消');
setTimeout(() => {
}, 3000);
} else {
console.log('状态面板不存在,直接清除状态');
}
}
function startContinuousExam() {
localStorage.setItem("华医mode", "1");
console.log('🚀 开始连续考试流程,模式强制设置为单刷视频');
localStorage.setItem('exam_phase', 'setup');
createStatusPanel();
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
const examCourses = courseList.filter(course => course.status === '待考试');
if (examCourses.length === 0) {
console.log('❌ 没有找到待考试的课程');
updateExamStatus('❌ 没有找到待考试的课程', true);
localStorage.removeItem('exam_phase');
return;
}
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
localStorage.setItem('exam_phase', 'face_verification');
console.log(`📋 找到 ${examCourses.length} 个待考试课程`);
updateExamStatus(`找到 ${examCourses.length} 个待考试课程
准备开始刷脸流程...`);
startFaceVerificationProcess();
}
function startFaceVerificationProcess() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有课程刷脸完成,开始连续考试');
updateExamStatus('✅ 所有课程刷脸完成
开始连续考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startFaceVerificationProcess, 1000);
return;
}
console.log(`👤 开始第 ${currentIndex + 1} 个课程刷脸: ${currentCourse.title}`);
updateExamStatus(`👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
window.location.href = `course_ware.aspx?cwid=${currentCourse.cwid}`;
}
function checkFaceVerificationReturn() {
const examPhase = localStorage.getItem('exam_phase');
const isInFaceVerification = examPhase === 'face_verification';
if (isInFaceVerification) {
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
if (currentIndex < examCourses.length) {
console.log('🔍 检测到刷脸后返回,继续下一个课程');
localStorage.setItem('current_exam_index', currentIndex + 1);
updateExamStatus(`✅ 刷脸完成 ${currentIndex + 1}/${examCourses.length}
准备下一个课程...`);
setTimeout(startFaceVerificationProcess, 3000);
} else {
console.log('✅ 刷脸流程已完成');
updateExamStatus('✅ 刷脸流程已完成
准备开始考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
}
}
}
function startAllExams() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
if (examCourses.length === 0) {
console.log('❌ 没有待考试的课程');
updateExamStatus('❌ 没有待考试的课程', true);
return;
}
console.log('🎯 开始连续考试流程');
updateExamStatus(`🎯 开始连续考试流程
共 ${examCourses.length} 个考试待完成`);
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
startNextExam();
}
function startNextExam() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有考试完成!');
updateExamStatus('✅ 所有考试完成!
连续考试流程结束');
cancelContinuousExam();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startNextExam, 1000);
return;
}
console.log(`📝 开始第 ${currentIndex + 1} 个考试: ${currentCourse.title}`);
updateExamStatus(`📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
window.location.href = `/pages/exam.aspx?cwid=${currentCourse.cwid}`;
}
function checkExamContinuation() {
const examPhase = localStorage.getItem('exam_phase');
const isInExamMode = examPhase === 'examination';
if (isInExamMode) {
console.log('🔍 检测到考试完成,准备下一个考试');
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
localStorage.setItem('current_exam_index', currentIndex + 1);
updateExamStatus(`✅ 考试完成 ${currentIndex + 1}/${examCourses.length}
准备下一个考试...`);
setTimeout(() => {
startNextExam();
}, 3000);
}
}
})();
gwQOWPuloSKykYzlA6CZxbTEFRiWVVbcQ9nxyvmpirmdmlD/UAA/8MQzsAMGXECpceKpvAcHnEPEINwkLqIrLlf5pEMBIMA7PEM0YMAHJZwU/gM9gM97RAMuaNhMuM1JXVc+jJNT+IUnFgMJsMM6BCPVJeIrTiOBHdkFtIM+3Nc5xN4j7c35jQUR5MP0pcSfPU5JoYPctWLHpIOqOQCwfZ0ZHlECUiM9al3FXIc4NZx2zeMwiYNwrU8znIdTJIA63JA/HI4gwsReXGBNlMPmHV49RuSBqVimzAneIJkuZh5tOUszGKQ/oIPKNIXLhEmnxALdIGIy+shaHNfrSaRLnhmbvdsXYhBGbMqQfSR+NIXe1AhwzEX8vSRQBiXfGUk5kM84/xJMP1xAM6QTWXDAJjYFPoTHDT0DBjSTUF4lVrogdBhAMDQDBjhAkRzl2kCHsSDLHJ2DOoYEAZCUzpDAMEgOP2alXO4d6tkFMtSDO5SUKH4fBikJLBDWhIkD7PUDLBRkJPEDmaTlXC4mNyIHtIDJO1BA+LlYSCBDNPBkWSAAFL6I5XgjcLADLBgYY46mK6Ie59UDlfQEdK0RRhjAI8KMOpxAQsLEOdCVPEkLBYgmae4mGtZFc90Qk8ldX2KSJt2QO+hD4zVFOizlezyDO+SmYvKmdIranp2TdZUFBkwm9RwHfXghbSDHPzanH4VdXhRmmywYO1SYdk4ne3LdUqhFMP8ECZu0j26GFJuNQAJQQD4YQHShpJtdgHBVSZsU14s4Zh36xDpgiX+2J4PmHdXhQzDUAwLwgwjoA8JwZpoMg/kpWsWl5VBcgFTCDAnUUzKGRFRIKD+gw0nGZYO2qBo+HgHggwGcwDbuGVH8BQFwQDoNXTiJ3nV0JP34Q+SkJEiUQzsgwwno3g66KJOKGs2Ux5GMUxfOBNtYDgLAzYAqJlNQgEeWAJYUaIDE1Ho2KZmW4B+xzXk85Ez0VTsY5nuQx5imRFvY2OCtg8Ul44/dB8JEZ5n26VlVm19QjI3KxJ7dQ3GKhwPEaf50ILI8g2Sm3VJIR+p9IYv6qaX6HOu9FZ///kU5oMONsc/+cWJQKCXH4ZRsKipgaIkkFhGfXqqrThtvnAAhEYE6lIA+5CRnsgchsUMsDANyAuGrBquLVttHgAAuIAMu0ENWGN6ptcUsGIA+JIA4RJOwVmt7GmF3imV6wF+Ytqq1fusi6kXlRGkCvqc+Viq4pqv/AQuM8NxsrGQcqqu8YiX6tB6XoKr5DBg0kNyazau/XuWeAWo8hlSMxeu/HizCJqzCLizDNqzDPizERqzETizFVqzFXizGZqzGbizHdqzHfizIhqzIjizJlqzJnizKpqzKrizLtqzLvizMxqzMzizN1qzN3izO5qzO7izP9qzP/izQBq3QDi3RIhat0R4t0iat0i4t0zat0z4t1Eat1E4t1Vat1V4t1qJsQAAAOw==`;
var clock = null;
var testtest = true; //另一个可能会封号的功能,仅调试使用。
advis();
createStatusPanel(); //状态监视面板根据需要进行显示
// 修复错误:检查元素是否存在后再设置内容
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "当前网址已适配ヾ(๑╹◡╹)ノ"
失效请赞赏联系  ε(┬┬﹏┬┬)3";
}
if (urlTip == "course_ware_polyv.aspx") { //保利威播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(1);
} else if (urlTip == "course_ware_cc.aspx") { //CC播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(2);
} else if (urlTip == "face.aspx") { //刷脸
console.log("当前任务: 刷脸界面");
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "course.aspx" || urlTip == "cme.aspx") { //课程列表页面
console.log("当前任务: 课程列表");
huayi.courseList();
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "exam.aspx") { //考试页面
console.log("当前任务: 华医考试");
huayi.doTest();
} else if (urlTip == "exam_result.aspx") { //考试结果页面
console.log("当前任务: 华医考试结果审核");
huayi.doResult();
} else {
console.log("其它情况");
try {
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "此页面非视频、考试或未适配";
}
document.querySelector("img[id='Pic']").style.display = "block";
} catch (error) { };
};
function getHuayi() {
return {
courseList: function () {
addAnwserCopybtn();
addImportAnswerBtn();
DelAllAnwser();
},
seeVideo: function (e) {
var tr = localStorage.getItem(keyPlayRate);
//console.log("存储读取" + tr);//读取倍速
//var playRateNow = tr ? tr : vSpeed;
var playRateNow = 1;
cleanKeyStorage();
asynckillsendQuestion();//屏蔽课堂问答的函数;
killsendQuestion2();//屏蔽课堂问答的函数2;
killsendQuestion3(); //循环检测问答对话框是否弹出。
//addrateinfo();//插入一些按钮
//addratebtn(1);
//addratebtn(1.5);
//addratebtn(2);
//addSkipbtn();//跳过按钮
addinfo();//脚本信息
changelayout();
//速度调节部分
window.onload = function () {
localStorage.setItem(keyThisTitle, JSON.stringify(window.document.title));//储存章节标题
// console.log("准备激活加速");
ratechg(playRateNow);
if (autoSkip == true) {//秒过功能,已经不抵了,别尝试,没用的
setTimeout(function () {
skipVideo();
}, (submitTime + Math.ceil(Math.random() * randomX)));
console.log("秒过了!");
};
clock = setInterval(examherftest, 3000);//阿み杰此处要改11才能考试,循环法用examherftest检测考试按钮是否能点击
;
}
// 保存课程列表(每次都会检查并更新)
console.log('🎬 视频页面加载完成,开始保存/更新课程列表');
saveCourseList();
if (testtest) { addContinuousExamButton(); }// 添加连续考试按钮
// 检查是否是刷脸后返回
checkFaceVerificationReturn();
switch (e) {
case 1:
if (typeof window.s2j_onPlayerInitOver === 'function') {
window.s2j_onPlayerInitOver();
}
{
// 修复静音错误:先检查player对象是否存在
if (typeof player !== 'undefined' && player && player.j2s_setVolume) {
try {
player.j2s_setVolume(0);
console.log("保利威播放器静音成功");
} catch (error) {
console.log("保利威播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof player !== 'undefined' && player && player.j2s_resumeVideo) {
player.j2s_resumeVideo();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
killsendQuestion3();
break;
case 2:
if (typeof window.on_CCH5player_ready === 'function') {
window.on_CCH5player_ready();
}
{
// 修复静音错误:先检查cc_js_Player对象是否存在
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.setVolume) {
try {
cc_js_Player.setVolume(0);
console.log("CC播放器静音成功");
} catch (error) {
console.log("CC播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.play) {
cc_js_Player.play();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
break;
default:
console.log("其他播放器?");
};
},
doTest: function () {
var questions = JSON.parse(localStorage.getItem(keyTest)) || {};
var qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
if (JSON.stringify(qRightAnswer) == "{}") {
qRightAnswer = LoadRightAnwser();
};
var qTestAnswer = {};
var index = 0;
while (true) {
var question = document.querySelectorAll("table[class='tablestyle']")[index];
if (question == null) break;
else {
//var q = question.querySelector(".q_name").innerText.substring(2).replace(/\s*/g, "");//问题的具体文本
// 使用新的题目获取方式
var rawQuestion = question.querySelector(".q_name").innerText.substring(2);
var q = cleanQuestionText(rawQuestion);
console.log(q);
//thisQuestions=thisQuestions+q+"@"
if (qRightAnswer.hasOwnProperty(q)) { //当查询到记录了正确答案时的操作
//console.log("问题:"+ q + ",有答案:"+ qRightAnswer[q]);
var rightSelection = findAnwser("tbody", index, qRightAnswer[q]) //返回答案选项label
if (rightSelection) {
rightSelection.click();
}
} else {
if (questions.hasOwnProperty(q)) {
questions[q] = getNextChoice(questions[q]);//通过Unicode数字+1切换到下一个选项,返回的是字母选项
//console.log("不知道答案:"+ q+",测试:"+questions[q]);
} else { //如果系统没有记录
questions[q] = "A";
};
var answer = getChoiceCode(questions[q]);//将字母选项转换为Unicode数字并减去A代表的65,等于选项顺序,0是第一个选项
var element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
if (!element) { //选项除错机制
console.log("找不到选项,选项更改为A index: " + index + " answer: " + answer);
questions[q] = "A";
answer = getChoiceCode("A");
element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
//localStorage.removeItem(keyTest)
};
try {
var answerText = element.innerText.substring(3);//"A、"占用3个字符
//console.log("测试语法:" + (answerText == element.innerText.trim().substring(2)));
//element.nextSibling.innerText.trim().substring(2); //获得当前答案文本
qTestAnswer[q] = answerText;
//console.log("qTestAnswer:"+error);
} catch (error) { console.log("答案文本获取失败A:" + error); };
if (element) {
element.click();
}
};
index = index + 1;
};
};
//存储相关记录
localStorage.setItem(keyTest, JSON.stringify(questions));
localStorage.setItem(keyTestAnswer, JSON.stringify(qTestAnswer));
setTimeout(function () {
var submitButton = document.querySelector("#btn_submit");
if (submitButton) {
submitButton.click();
}
}, (submitTime + Math.ceil(Math.random() * randomX))); //交卷延时
///专用函数区
function findAnwser(qakey, index, rightAnwserText) {
var answerslist = document.querySelectorAll(qakey)[index];
if (!answerslist) return null;
var arr = answerslist.getElementsByTagName("label");
console.log(`查找答案: ${rightAnwserText}`);
// 精确匹配
for (var i = 0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText===rightAnwserText) {
console.log(`✅ 精确匹配: ${optionText}`);
return arr[i];
}
}
// 模糊匹配
for (var i=0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText.includes(rightAnwserText) || rightAnwserText.includes(optionText)) {
console.log(`🔍 模糊匹配: ${optionText}`);
return arr[i];
}
}
console.log(`❌ 未找到匹配答案,使用第一个选项`);
return arr[0];
}
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] ? $(".tips_text")[0].innerText : null;
var dds=$(".state_cour_lis");
localStorage.removeItem(keyResult);
if (res=="考试通过" || res=="考试通过!" || res=="完成项目学习可以申请学分了" ) {
console.log("考试通过");
saveRightAnwser();
SaveAllAnwser();
cleanKeyStorage();
checkExamContinuation();
setTimeout(function () {
// ...(原有代码)
}, 1000);
} else {
console.log("考试未通过")
var tipsTextElement=document.querySelector("p[class='tips_text' ]");
if (tipsTextElement) {
tipsTextElement.innerText="本次未通过,正在尝试更换答案\r\n(此为正常现象,脚本几秒后刷新,请勿操作)"
}
var qWrong={};
for (var i=0; i < dds.length; ++i) {
if (dds[i].querySelector("img") && !dds[i].querySelector("img").src.includes("bar_img")) {//这里表示否定
var rawQuestion=dds[i].querySelector("p").title;
var cleanedQuestion=cleanQuestionText(rawQuestion);
qWrong[cleanedQuestion]=i
};
};
if (qWrong !={}) {
localStorage.setItem(keyResult, JSON.stringify(qWrong));
saveRightAnwser();
setTimeout(function () {
$("input[type=button][value='重新考试' ]").click();
}, (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 qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) ||{};
var qTitle=JSON.parse(localStorage.getItem(keyThisTitle)) || "没有记录到章节名称" ;
if (qTitle=="没有记录到章节名称" ) {
console.log("没找到章节名称");
return {};
};
var qOldAnswer=qAllAnswer[qTitle] || {};
return qOldAnswer
};
// 修改题目处理逻辑,去除干扰的问号
// 统一的题目清洗函数
function cleanQuestionText(questionText) {
if (!questionText) return '' ;
// 去除各种特殊字符和空白
let cleaned=questionText
.replace(/[??]/g, '' )
.replace(/||[\u200B-\u200D\uFEFF]/g, '' ) // 去除零宽空格
.replace(/\s+/g, ' ' ) // 将多个空格合并为一个
.trim();
// 去除题目编号
cleaned=cleaned.replace(/^\d+、/, '' ).trim();
// 智能处理括号:
// 1. 只删除完全为空或只有空格的括号
// 2. 保留包含实际内容的括号
cleaned=cleaned.replace(/[((]\s*[))]/g, '' ) // 处理空括号
.replace(/[((]\s*([^))\s]+)\s*[))]/g, '$1' ) // 保留括号内的内容
.trim();
return cleaned;
}
// 修改题目获取方式,确保一致性
function getQuestionText(questionElement) {
try {
let rawText=questionElement.querySelector(".q_name").innerText;
// 去除编号部分(如"1、")
let textWithoutNumber=rawText.replace(/^\d+、/, '' );
return cleanQuestionText(textWithoutNumber);
} catch (error) {
console.log("获取题目文本错误:", error);
return "" ;
}
}
// 修改答案记录部分
function saveRightAnwser() {
var qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
var qTestAnswer=JSON.parse(localStorage.getItem(keyTestAnswer)) || {};
var qWrongs=JSON.parse(localStorage.getItem(keyResult)) || {};
console.log("开始保存正确答案...");
console.log("错题记录:", qWrongs);
console.log("测试答案:", qTestAnswer);
// 构建清理后的题目映射
var cleanedWrongs={};
for (var wrongQ in qWrongs) {
var cleanedWrongQ=cleanQuestionText(wrongQ);
cleanedWrongs[cleanedWrongQ]=true;
console.log(`错题清洗: "${wrongQ}" -> "${cleanedWrongQ}"`);
}
for (var q in qTestAnswer) {
var cleanedQ = cleanQuestionText(q);
console.log(`处理题目: "${q}" -> "${cleanedQ}", 答案: ${qTestAnswer[q]}`);
if (!cleanedWrongs[cleanedQ]) {
console.log(`✅ 正确答案: "${cleanedQ}" -> ${qTestAnswer[q]}`);
qRightAnswer[cleanedQ] = qTestAnswer[q];
} else {
console.log(`❌ 错误题目: "${cleanedQ}" -> ${qTestAnswer[q]}`);
}
}
localStorage.removeItem(keyTestAnswer);
if (Object.keys(qRightAnswer).length > 0) {
localStorage.setItem(keyRightAnswer, JSON.stringify(qRightAnswer));
console.log("✅ 正确答案已保存:", qRightAnswer);
} else {
console.log("❌ 没有正确答案需要保存");
}
}
//答案记录函数区结束//
//------------------答案复制相关按钮--------------------------------------------
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")
//Aout=encodeURIComponent(Aout);
//window.prompt("请复制",Aout);
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;
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(textout);
}
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.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);
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
//答案复制相关按钮 end
function skipVideo() {//这是跳过视频的代码
var oVideo = document.getElementsByTagName('video')[0];
if (oVideo) {
oVideo.currentTime = oVideo.duration - 1
};
};
// 在 courseList 函数中添加导入答案按钮
function addImportAnswerBtn() {
let alink = document.createElement("a");
alink.innerHTML = '导入答案';
alink.style = btstyleB;
alink.onclick = function (event) {
var input = prompt("请粘贴要导入的答案数据(JSON格式)");
if (input) {
try {
// 解析输入的JSON数据
var importedAnswers = JSON.parse(input);
// 获取现有的答案记录
var existingAnswers = JSON.parse(localStorage.getItem(keyAllAnswer)) || {};
// 合并答案
var mergedAnswers = mergeAnswerData(existingAnswers, importedAnswers);
// 保存合并后的答案
localStorage.setItem(keyAllAnswer, JSON.stringify(mergedAnswers));
alert("✅ 答案导入成功!\n已合并 " + Object.keys(importedAnswers).length + " 个章节的答案");
} catch (error) {
alert("❌ 导入失败:数据格式不正确\n" + error);
}
}
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
// 合并答案数据的函数
function mergeAnswerData(existing, imported) {
// 深拷贝现有答案
var merged = JSON.parse(JSON.stringify(existing));
// 遍历导入的答案
for (var chapter in imported) {
if (imported.hasOwnProperty(chapter)) {
// 如果章节不存在,直接添加
if (!merged[chapter]) {
merged[chapter] = imported[chapter];
} else {
// 合并章节内的题目答案
for (var question in imported[chapter]) {
if (imported[chapter].hasOwnProperty(question)) {
merged[chapter][question] = imported[chapter][question];
}
}
}
}
}
return merged;
};
//------------------看视频页面主要函数-------------------------------------------
function clickexam() { //延时点击考试按钮。
console.log("已点击考试按钮");
setTimeout(function () {
var examButton = document.querySelector("#jrks");
if (examButton) {
examButton.click();
}
}, (Math.ceil(Math.random() * randomX)));
//}, (examTime + Math.ceil(Math.random() * randomX)));
};
//按钮插入函数相关
function addSkipbtn() {//插入按钮快进视频按钮
let alink = document.createElement("a");
alink.innerHTML = '快进视频';
alink.style = btstyleA;
alink.onclick = function (event) {
skipVideo();
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
};
function addratebtn(ra) {//倍率调整按钮
let alink = document.createElement("a");
alink.innerHTML = '' + ra + 'x';
alink.style = btstyleB;
alink.className = "speed";
alink.id = ra + "x";
alink.onclick = function (event) {
ratechg(ra);
try {
var arr = document.querySelectorAll("a[class='speed']");
arr.forEach(function (item, index, arr) {
arr[index].style = btstyleB;
});
} catch (error) {
};
alink.style = btstyleC;
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
}
function ratechg(ra) {//倍率调整
var videoObj = document.querySelector("video")
if (videoObj) {
try {
clearInterval(nspeed);
nspeed = setInterval(() => {
videoObj.playbackRate = ra;
}, 1 * 1000);
localStorage.setItem(keyPlayRate, ra);
//document.querySelector("a[id=" + "'" + ra + "x']").style = btstyleC;
//document.getElementById("playrate").innerHTML = "当前播放速率" + ra + "x";
//console.log("倍率调整为" + ra);
} catch (error) { console.log("倍率调整错误" + error); };
}
};
function addrateinfo() {//插入说明
let adiv1 = document.createElement("div");
adiv1.innerHTML = '当前播放速率';
adiv1.id = 'playrate';
adiv1.style = "font-size: 15px;text-align: center;margin-top: 10px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv1);
}
};
function addinfo() {//插入说明
//模式切换按钮
var moderesult = localStorage.getItem("华医mode");
if (moderesult == 2) {
moderesult = "当前模式:视频+考试";
} else {//包括了结果为1或者无存储的情况
moderesult = "当前模式:单刷视频";
};
var checkbox = document.createElement('div');
checkbox.innerHTML = '' + moderesult + '
[点击此处切换] ';
// 添加到页面的 body 元素中
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(checkbox);
}
//插入说明部分
let mode1 = document.querySelector("a[id='mode']");
if (mode1) {
mode1.onclick = function () {
if (mode1.innerText == "当前模式:单刷视频\n[点击此处切换]") {
mode1.innerText = "当前模式:视频+考试\n[点击此处切换]";
localStorage.setItem("华医mode", "2");
} else {
mode1.innerText = "当前模式:单刷视频\n[点击此处切换]";
localStorage.setItem("华医mode", "1");
};
};
}
let adiv2 = document.createElement("div");
adiv2.innerHTML = '       本人医学研一学生,经常要帮师兄师姐刷华医视频,属实太累。偶然在抖音发现Dr.S的脚本,结果刷完1个视频立刻考试,导致频繁人脸识别跟手动区别不大。原作者已不更新,于是我自学修改了播放逻辑,实现无人值守连续播放。现将原先自用的脚本分享给大家❤❤
     刷完视频再切换考试模式,即可连续考试。
';
adiv2.id = 'jsinfo';
adiv2.style = "position:relative;left:10px;top:5px;width:240px;font-size:13px;text-align: justify;border: 1px dashed #ff9595;padding:5px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv2);
}
if (typeof $ !== 'undefined') {
$('div:contains("观看视频完成后,才能进入考试")').eq(-1).text('建议360安全浏览器和脚本猫');
}
// 创建连续考试按钮的容器
let examBtnContainer = document.createElement('div');
examBtnContainer.id = 'continuousExamBtnContainer';
examBtnContainer.style = "text-align: center; margin: 10px 0;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(examBtnContainer);
}
};
function changelayout() {
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv) {
jjDiv.remove();
}
var photoImg = document.querySelector("img[id='photo']");
if (photoImg) {
photoImg.outerHTML = `
`;
photoImg.style.width = "120px";
photoImg.style.height = "120px";
}
var titleDivs = document.querySelectorAll("div[class='title']");
if (titleDivs[0] && titleDivs[0].children[0]) {
titleDivs[0].children[0].style = "color: #ff0000;font-weight: bold";
titleDivs[0].children[0].innerText = "支持作者";
}
var imgTextDivs = document.querySelector("div[class='imgtext']");
if (imgTextDivs && imgTextDivs.children[1]) {
imgTextDivs.children[1].style.width = "125px";
imgTextDivs.children[1].style = "color: #ff0000;padding-top:10px";
imgTextDivs.children[1].innerText = "作 者\n创作优化不易\n投点小费吧\n❤谢啦❤\n❤"
}
var topDiv = document.querySelector("div[class='top']");
if (topDiv) {
topDiv.outerHTML = '如服务器调整,脚本可能失效。反馈意见、免费增加课程请在Greasyfork私信或脚本反馈区联络。也欢迎投喂↓
';
}
};
function cleanKeyStorage() {//缓存清理
localStorage.removeItem(keyTest);
localStorage.removeItem(keyResult);
localStorage.removeItem(keyTestAnswer);
localStorage.removeItem(keyRightAnswer);
};
function examherftest() {//考试按钮激活状态检测
var examButton = document.getElementById("jrks");
var hreftest = examButton ? examButton.attributes["disabled"] : null;
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if ((state == "已完成" || state == "待考试" || !hreftest) && examButton) {//value不为#说明考试按钮已经激活
console.log("已经播放完了");
// 优先处理"视频+考试"模式下的"待考试"状态
var modeElement = document.querySelector("a[id='mode']");
if (modeElement && modeElement.innerText.indexOf("视频+考试") != -1 && state == "待考试") {
console.log("mode=2,准备进入考试");
// 重试机制:尝试5次进入考试
var retryCount = 0;
var maxRetries = 5;
function tryEnterExam() {
retryCount++;
console.log(`尝试进入考试 (第${retryCount}次)`);
try {
// 方法1:尝试点击考试按钮
if (document.getElementById("jrks") && !document.getElementById("jrks").disabled) {
document.getElementById("jrks").click();
console.log("成功点击考试按钮");
return true; // 成功进入考试
}
// 方法2:尝试备用方式
if (typeof cwrid !== 'undefined') {
window.open("/pages/exam_tip.aspx?cwrid=" + cwrid, "_self");
console.log("尝试备用方式进入考试");
return true;
}
// 方法3:尝试通过URL跳转
var currentUrl = window.location.href;
if (currentUrl.includes("course_ware")) {
var examUrl = currentUrl.replace("course_ware/course_ware_", "pages/exam.aspx?cwid=")
.split("?")[0] + "?cwid=" + getUrlParam("cwid");
window.location.href = examUrl;
console.log("尝试通过URL跳转进入考试");
return true;
}
} catch (error) {
console.log(`第${retryCount}次尝试失败:`, error);
}
return false; // 进入考试失败
}
// 立即尝试第一次
if (tryEnterExam()) {
return; // 成功进入考试,直接返回
}
// 设置重试间隔
var retryInterval = setInterval(function () {
if (retryCount >= maxRetries) {
clearInterval(retryInterval);
console.log(`尝试${maxRetries}次进入考试均失败,继续听课`);
// 继续执行后续的跳转到下一个视频的逻辑
proceedToNextVideo();
} else if (tryEnterExam()) {
clearInterval(retryInterval); // 成功进入考试,停止重试
}
}, 2000); // 每2秒重试一次
} else {
// 单刷视频模式或非待考试状态,直接继续听课
proceedToNextVideo();
};
} else {//#代表考试按钮还没激活
//继续播放,无需任何操作
}
}
// 跳转到下一个视频的函数
function proceedToNextVideo() {
console.log('🚀 准备跳转到下一个视频...');
const nextCwid = getNextCourseCwid();
if (nextCwid) {
console.log(`✅ 确定跳转到课程: ${nextCwid.substring(0, 8)}...`);
console.log(`🌐 跳转URL: course_ware.aspx?cwid=${nextCwid}`);
// 延迟跳转,让用户有时间查看日志
setTimeout(() => {
console.log('⏩ 正在跳转...');
window.location.href = `course_ware.aspx?cwid=${nextCwid}`;
}, 2000);
} else {
console.log('❌ 没有找到可用的课程,尝试刷新页面');
setTimeout(() => {
console.log('🔄 正在刷新页面...');
window.location.reload();
}, 2000);
}
}
// 辅助函数:获取URL参数
function getUrlParam(name) {
var urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
};
//课堂问答跳过,临时版
function sleep(timeout) {
return new Promise((resolve) => { setTimeout(resolve, timeout); });
console.log("课堂问答循环调用");
};
function asynckillsendQuestion() {
(async function () {
while (!window.player || !window.player.sendQuestion) {
await sleep(20);
};
//console.log("课堂问答跳过插入");
player.sendQuestion = function () {
//console.log("播放器尝试弹出课堂问答,已屏蔽。");
};
})();
};
function killsendQuestion2() {
if (typeof (isInteraction) == "undefined") {
//console.log('变量未定义');
} else {
console.log('isInteraction设置off');
isInteraction = "off";
};
};
function killsendQuestion3() { //点击跳过按钮版的跳过课堂答题
var clockms = setInterval(async function () {
try {
if (typeof $ !== 'undefined' && $('.pv-ask-head').length && $('.pv-ask-head').length > 0) {
console.log("检测到问题对话框,尝试跳过");
$(".pv-ask-skip").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.signBtn').length && $('.signBtn').length > 0) {
console.log("检测到签到对话框,尝试跳过");
$(".signBtn").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' &&
$("button[onclick='closeProcessbarTip()']").length &&
$("button[onclick='closeProcessbarTip()']").length > 0 &&
$("div[id='div_processbar_tip']").css("display") == "block") {
console.log("检测到温馨提示对话框(不能拖拽),尝试跳过");//
//*[@id="div_processbar_tip"]/div/div[2]/input
//document.querySelector("#div_processbar_tip > div > div.foot_sub > input")
//#div_processbar_tip > div > div.foot_sub > input
//
$("button[onclick='closeBangZhu()']").click();
$("button[onclick='closeProcessbarTip()']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $("button[class='btn_sign']").length && $("button[class='btn_sign']").length > 0) {
console.log("检测到温馨提示对话框(疲劳提醒),尝试跳过");
$("button[class='btn_sign']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.rig_btn').length && $('.rig_btn').length > 0) {
if ($('#div_processbar_tip').is(':visible')) {
console.log("检测到按钮(知道了),执行隐藏操作");
$('#div_processbar_tip').hide();
}
//$(".rig_btn").click();
};
} catch (err) {
console.log(err);
};
try {
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if (typeof $ !== 'undefined' &&
$('video').prop('paused') == true &&
state != "已完成" &&
state != "待考试") {
console.log("视频意外暂停,恢复播放");
$('video').get(0).play();
//$('video').prop('volumed') = 0;
$('video').prop('muted') = true;
} else if (state == "已完成") {
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.pause();
}
//clearInterval(clockms);
};
} catch (err) {
//console.log(err);
};
}, 10000);
};
function autoClickKnowButton() {
// 检测按钮是否加载完成
const observer = new MutationObserver(() => {
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
observer.disconnect(); // 停止观察
button.click(); // 点击按钮
}
});
// 开始观察文档的变化
observer.observe(document.body, {
childList: true,
subtree: true
});
// 如果按钮已经加载完成,直接点击
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
button.click();
}
}
// 在全局函数区添加以下函数
function saveCourseList() {
console.log('📋 开始保存/更新课程列表...');
// 尝试获取课程列表容器
const courseContainer = document.querySelector('.page-container');
if (!courseContainer) {
console.log('❌ 未找到课程列表容器');
return;
}
// 尝试获取课程项
const courseItems = document.querySelectorAll('.lis-inside-content');
if (courseItems.length === 0) {
console.log('❌ 未找到课程项');
return;
}
console.log(`📚 找到 ${courseItems.length} 个课程项,开始解析...`);
const currentCourseList = [];
let hasChanges = false;
courseItems.forEach((item, index) => {
const titleElement = item.querySelector('h2');
const statusButton = item.querySelector('button');
if (titleElement && statusButton) {
const title = titleElement.textContent.trim();
const status = statusButton.textContent.trim();
const statusColor = statusButton.style.background;
// 从onclick属性中提取cwid
const onclickAttr = titleElement.getAttribute('onclick');
let cwid = '';
if (onclickAttr) {
const match = onclickAttr.match(/cwid=([^']+)/);
if (match && match[1]) {
cwid = match[1];
}
}
if (cwid) {
currentCourseList.push({
title,
status,
statusColor,
cwid,
index
});
//console.log(` 课程 ${index + 1}: "${title}" - 状态: ${status}`);
}
}
});
if (currentCourseList.length === 0) {
console.log('❌ 未解析到任何课程信息');
return;
}
// 获取之前保存的课程列表
const previousCourseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
if (previousCourseList.length === 0) {
// 第一次保存
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`✅ 首次保存课程列表完成,共 ${currentCourseList.length} 个课程`);
return;
}
// 检查是否有变化
console.log('🔍 检查课程状态变化...');
for (let i = 0; i < currentCourseList.length; i++) {
const currentCourse=currentCourseList[i];
const previousCourse=previousCourseList[i];
if (!previousCourse) {
console.log(` 新增课程: "${currentCourse.title}" `);
hasChanges=true;
continue;
}
// 检查状态变化
if (currentCourse.status !==previousCourse.status) {
console.log(` 状态变化: "${currentCourse.title}" - ${previousCourse.status} → ${currentCourse.status}`);
hasChanges=true;
}
// 检查标题变化(可能课程有更新)
if (currentCourse.title !==previousCourse.title) {
console.log(` 标题变化: "${previousCourse.title}" → "${currentCourse.title}" `);
hasChanges=true;
}
// 检查cwid变化(理论上不应该变)
if (currentCourse.cwid !==previousCourse.cwid) {
console.log(` cwid变化: "${currentCourse.title}" `);
hasChanges=true;
}
}
// 检查课程数量变化
if (currentCourseList.length !==previousCourseList.length) {
console.log(` 课程数量变化: ${previousCourseList.length} → ${currentCourseList.length}`);
hasChanges=true;
}
if (hasChanges) {
// 更新课程列表
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`🔄 课程列表已更新,共 ${currentCourseList.length} 个课程`);
// 输出详细的课程状态
console.log('📊 当前所有课程状态:');
currentCourseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
} else {
console.log('✅ 课程列表无变化,无需更新');
// 即使无变化,也确保本地存储的是最新数据(防止数据损坏)
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
}
}
function getCurrentCourseCwid() {
// 从当前URL获取cwid
const urlParams = new URLSearchParams(window.location.search);
const cwid = urlParams.get('cwid');
console.log(`🔍 当前课程 cwid: ${cwid ? cwid.substring(0, 8) + '...' : '未找到'}`);
return cwid;
}
function getNextCourseCwid() {
console.log('🔄 开始查找下一个课程...');
// 尝试从localStorage获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
const currentCwid = getCurrentCourseCwid();
if (courseList.length === 0) {
console.log('❌ 未找到存储的课程列表');
return null;
}
console.log(`📊 课程列表中有 ${courseList.length} 个课程`);
// 找到当前课程的索引
const currentIndex = courseList.findIndex(course => course.cwid === currentCwid);
if (currentIndex === -1) {
console.log('❌ 未找到当前课程在列表中的位置');
console.log('当前课程可能不在列表中,将尝试第一个未完成的课程');
// 尝试查找第一个未完成的课程
for (let i = 0; i < courseList.length; i++) {
const course=courseList[i];
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到第一个未完成课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
return null;
}
console.log(`📍 当前课程位置: 第 ${currentIndex + 1} 个 - "${courseList[currentIndex].title}" `);
// 查找下一个未完成的课程(从当前位置向后找)
console.log('🔍 向后查找未完成的课程...');
for (let i=currentIndex + 1; i < courseList.length; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到下一个课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
// 如果后面没有未完成的课程,尝试从开头查找
console.log('🔍 向后未找到,从开头查找未完成的课程...');
for (let i=0; i < currentIndex; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到前面的课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
console.log('所有课程状态:');
courseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
return null;
}
//--------------------------插入悬浮框------------------------------------//
function advis() {
// 🔴 第一步:只在顶层窗口运行,iframe 中直接退出
if (window.self !== window.top) {
console.log('小助手:当前处于 iframe 中,不创建面板');
return;
}
// 🔴 第二步:检查是否已有面板,防止重复创建(即使脚本多次调用)
const existingPanel = document.getElementById('Div1');
if (existingPanel) {
console.log('已检测到小助手面板,防止重复创建');
return; // 或者 existingPanel.remove(); 再创建(推荐 return 即可)
}
// 🟡 第三步:创建新面板
let div1 = document.createElement("div");
div1.innerHTML = `
`;
document.body.append(div1);
// 绑定事件
let share1 = document.getElementById('Share1');
let share2 = document.getElementById('Share2');
let clo = document.getElementById('clo');
if (share1) {
share1.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/500010", "_blank");
};
}
if (share2) {
share2.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/555651", "_blank");
};
}
if (clo) {
clo.onclick = function () {
var panel = document.getElementById('Div1');
if (panel) {
panel.style.display = 'none';
}
};
}
// === 初始化:左对齐课程列表 ===
const panel = document.getElementById('Div1');
if (!panel) return;
const container = document.querySelector('.page-container') ||
document.querySelector('.lis-content') ||
document.querySelector('.container-inside-header');
let initialLeft = 140; // 默认值
if (container) {
const rect = container.getBoundingClientRect();
initialLeft = rect.left + window.pageXOffset;
}
panel.style.left = initialLeft + 'px';
// === 拖拽功能 ===
let isDragging = false;
let offsetX, offsetY;
panel.addEventListener('mousedown', function (e) {
if (e.target === clo ||
e.target.tagName === 'A' ||
e.target.tagName === 'IMG' ||
e.target.tagName === 'HR') return;
isDragging = true;
offsetX = e.clientX - panel.getBoundingClientRect().left;
offsetY = e.clientY - panel.getBoundingClientRect().top;
e.preventDefault();
});
document.addEventListener('mousemove', function (e) {
if (!isDragging) return;
panel.style.left = (e.clientX - offsetX) + 'px';
panel.style.top = (e.clientY - offsetY) + 'px';
});
document.addEventListener('mouseup', () => {
isDragging = false;
});
// 创建状态面板(默认隐藏)
//createStatusPanel();
//document.getElementById('examStatusPanel').style.display = 'none';
}
//--------------------------连续考试的函数------------------------------------//
// 修改 addContinuousExamButton 函数
function addContinuousExamButton() {
// 检查是否已存在连续考试按钮
if (document.getElementById('continuousExamBtn')) {
return;
}
// 创建连续考试按钮
let btn = document.createElement("a");
btn.innerHTML = '连续考试';
btn.style = btstyleA
btn.id = 'continuousExamBtn';
btn.onclick = function () {
console.log('🚀 开始连续考试流程...');
startContinuousExam();
};
// 找到建议提示框
const tipDiv = document.querySelector('div.r div[style*="border: 1px dashed #ff9595"]');
if (tipDiv) {
// 创建按钮容器
let btnContainer = document.createElement('div');
btnContainer.style = "text-align: center; margin: 10px 0;";
btnContainer.appendChild(btn);
// 将按钮容器插入到建议提示框后面
tipDiv.parentNode.insertBefore(btnContainer, tipDiv.nextSibling);
} else {
// 如果找不到建议提示框,使用预留的容器
const btnContainer = document.getElementById('continuousExamBtnContainer');
if (btnContainer) {
btnContainer.appendChild(btn);
} else {
// 如果容器也不存在,添加到页面底部
document.body.appendChild(btn);
}
}
}
// 新增:创建状态面板的函数
function createStatusPanel() {
// 检查是否存在 exam_phase
const examPhase = localStorage.getItem('exam_phase');
if (!examPhase) {
// 如果不存在 exam_phase,移除可能存在的面板
const existingPanel = document.getElementById('examStatusPanel');
if (existingPanel) {
existingPanel.remove();
}
return;
}
// 检查是否已存在状态面板
if (document.getElementById('examStatusPanel')) {
// 如果面板已存在,只需更新状态信息
updatePanelContent();
return;
}
// 创建状态面板
const panel = document.createElement('div');
panel.id = 'examStatusPanel';
panel.style = `
position: fixed;
top: 20px;
right: 20px;
width: 300px;
background-color: rgba(255, 255, 255, 0.95);
border: 2px solid #4cb0f9;
border-radius: 8px;
padding: 15px;
z-index: 10000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
font-family: 'Microsoft YaHei', sans-serif;
`;
panel.innerHTML = `
连续考试状态
加载中...
`;
// 确保面板正确插入到页面中
document.body.appendChild(panel);
// 添加取消按钮事件
var cancelBtn = document.getElementById('cancelExamBtn');
if (cancelBtn) {
cancelBtn.onclick = function () {
if (confirm('确定要取消连续考试吗?')) {
cancelContinuousExam();
}
};
}
// 更新面板内容
updatePanelContent();
// 辅助函数:更新面板内容
function updatePanelContent() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examPhase = localStorage.getItem('exam_phase');
let statusMessage = '';
if (examPhase === 'face_verification') {
statusMessage = `👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else if (examPhase === 'examination') {
statusMessage = `📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else {
statusMessage = '连续考试进行中...';
}
const contentElement = document.getElementById('examStatusContent');
if (contentElement) {
contentElement.innerHTML = statusMessage;
}
}
}
// 修改:更新状态提示的函数
function updateExamStatus(message, isError = false) {
createStatusPanel(); // 确保面板存在
const panel = document.getElementById('examStatusPanel');
// 添加存在性检查
if (!panel) {
console.log('状态面板不存在,跳过更新');
return;
}
panel.style.display = 'block';
const statusContent = document.getElementById('examStatusContent');
if (statusContent) {
statusContent.innerHTML = message;
statusContent.style.color = isError ? '#f15854' : '#333';
}
}
// 取消连续考试
function cancelContinuousExam() {
console.log('❌ 结束连续考试');
// 清除相关状态
localStorage.removeItem('exam_courses');
localStorage.removeItem('current_exam_index');
localStorage.removeItem('exam_phase');
// 只有在面板存在时才更新状态
const panel = document.getElementById('examStatusPanel');
if (panel) {
updateExamStatus('连续考试已取消');
// 3秒后隐藏状态面板
setTimeout(() => {
//panel.style.display = 'none';
}, 3000);
} else {
console.log('状态面板不存在,直接清除状态');
}
}
// 连续考试主函数
function startContinuousExam() {
// 强制设置为单刷视频模式,避免冲突
localStorage.setItem("华医mode", "1");
console.log('🚀 开始连续考试流程,模式强制设置为单刷视频');
localStorage.setItem('exam_phase', 'setup'); // 设置阶段为初始化
// 创建状态面板
createStatusPanel();
// 获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
// 筛选待考试的课程
const examCourses = courseList.filter(course => course.status === '待考试');
if (examCourses.length === 0) {
console.log('❌ 没有找到待考试的课程');
updateExamStatus('❌ 没有找到待考试的课程', true);
localStorage.removeItem('exam_phase');
return;
}
// 保存待考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
localStorage.setItem('exam_phase', 'face_verification'); // 设置阶段为刷脸
console.log(`📋 找到 ${examCourses.length} 个待考试课程`);
updateExamStatus(`找到 ${examCourses.length} 个待考试课程
准备开始刷脸流程...`);
// 开始刷脸流程
startFaceVerificationProcess();
}
// 刷脸流程
function startFaceVerificationProcess() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有课程刷脸完成,开始连续考试');
updateExamStatus('✅ 所有课程刷脸完成
开始连续考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startFaceVerificationProcess, 1000);
return;
}
console.log(`👤 开始第 ${currentIndex + 1} 个课程刷脸: ${currentCourse.title}`);
updateExamStatus(`👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开课程链接进行刷脸
window.location.href = `course_ware.aspx?cwid=${currentCourse.cwid}`;
}
// 监听页面加载,判断是否在刷脸后返回
function checkFaceVerificationReturn() {
const examPhase = localStorage.getItem('exam_phase');
const isInFaceVerification = examPhase === 'face_verification';
if (isInFaceVerification) {
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
// 只有当索引有效时才继续
if (currentIndex < examCourses.length) {
console.log('🔍 检测到刷脸后返回,继续下一个课程');
localStorage.setItem('current_exam_index', currentIndex + 1);
updateExamStatus(`✅ 刷脸完成 ${currentIndex + 1}/${examCourses.length}
准备下一个课程...`);
// 添加延迟防止过快跳转
setTimeout(startFaceVerificationProcess, 3000);
} else {
console.log('✅ 刷脸流程已完成');
updateExamStatus('✅ 刷脸流程已完成
准备开始考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
}
}
}
// 开始所有考试
function startAllExams() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
if (examCourses.length === 0) {
console.log('❌ 没有待考试的课程');
updateExamStatus('❌ 没有待考试的课程', true);
return;
}
console.log('🎯 开始连续考试流程');
updateExamStatus(`🎯 开始连续考试流程
共 ${examCourses.length} 个考试待完成`);
// 保存考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
// 开始第一个考试
startNextExam();
}
// 开始下一个考试
function startNextExam() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有考试完成!');
updateExamStatus('✅ 所有考试完成!
连续考试流程结束');
cancelContinuousExam();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startNextExam, 1000);
return;
}
console.log(`📝 开始第 ${currentIndex + 1} 个考试: ${currentCourse.title}`);
updateExamStatus(`📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开考试页面
window.location.href = `/pages/exam.aspx?cwid=${currentCourse.cwid}`;
}
// 在考试结果页面检查是否需要继续下一个考试
function checkExamContinuation() {
const examPhase = localStorage.getItem('exam_phase');
const isInExamMode = examPhase === 'examination';
if (isInExamMode) {
console.log('🔍 检测到考试完成,准备下一个考试');
// 增加索引
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
localStorage.setItem('current_exam_index', currentIndex + 1);
// 更新状态提示
updateExamStatus(`✅ 考试完成 ${currentIndex + 1}/${examCourses.length}
准备下一个考试...`);
// 短暂延迟后继续下一个考试
setTimeout(() => {
startNextExam();
}, 3000);
}
}
//---------------------------------全局函数区end------------------------------//
})();gwQOWPuloSKykYzlA6CZxbTEFRiWVVbcQ9nxyvmpirmdmlD/UAA/8MQzsAMGXECpceKpvAcHnEPEINwkLqIrLlf5pEMBIMA7PEM0YMAHJZwU/gM9gM97RAMuaNhMuM1JXVc+jJNT+IUnFgMJsMM6BCPVJeIrTiOBHdkFtIM+3Nc5xN4j7c35jQUR5MP0pcSfPU5JoYPctWLHpIOqOQCwfZ0ZHlECUiM9al3FXIc4NZx2zeMwiYNwrU8znIdTJIA63JA/HI4gwsReXGBNlMPmHV49RuSBqVimzAneIJkuZh5tOUszGKQ/oIPKNIXLhEmnxALdIGIy+shaHNfrSaRLnhmbvdsXYhBGbMqQfSR+NIXe1AhwzEX8vSRQBiXfGUk5kM84/xJMP1xAM6QTWXDAJjYFPoTHDT0DBjSTUF4lVrogdBhAMDQDBjhAkRzl2kCHsSDLHJ2DOoYEAZCUzpDAMEgOP2alXO4d6tkFMtSDO5SUKH4fBikJLBDWhIkD7PUDLBRkJPEDmaTlXC4mNyIHtIDJO1BA+LlYSCBDNPBkWSAAFL6I5XgjcLADLBgYY46mK6Ie59UDlfQEdK0RRhjAI8KMOpxAQsLEOdCVPEkLBYgmae4mGtZFc90Qk8ldX2KSJt2QO+hD4zVFOizlezyDO+SmYvKmdIranp2TdZUFBkwm9RwHfXghbSDHPzanH4VdXhRmmywYO1SYdk4ne3LdUqhFMP8ECZu0j26GFJuNQAJQQD4YQHShpJtdgHBVSZsU14s4Zh36xDpgiX+2J4PmHdXhQzDUAwLwgwjoA8JwZpoMg/kpWsWl5VBcgFTCDAnUUzKGRFRIKD+gw0nGZYO2qBo+HgHggwGcwDbuGVH8BQFwQDoNXTiJ3nV0JP34Q+SkJEiUQzsgwwno3g66KJOKGs2Ux5GMUxfOBNtYDgLAzYAqJlNQgEeWAJYUaIDE1Ho2KZmW4B+xzXk85Ez0VTsY5nuQx5imRFvY2OCtg8Ul44/dB8JEZ5n26VlVm19QjI3KxJ7dQ3GKhwPEaf50ILI8g2Sm3VJIR+p9IYv6qaX6HOu9FZ///kU5oMONsc/+cWJQKCXH4ZRsKipgaIkkFhGfXqqrThtvnAAhEYE6lIA+5CRnsgchsUMsDANyAuGrBquLVttHgAAuIAMu0ENWGN6ptcUsGIA+JIA4RJOwVmt7GmF3imV6wF+Ytqq1fusi6kXlRGkCvqc+Viq4pqv/AQuM8NxsrGQcqqu8YiX6tB6XoKr5DBg0kNyazau/XuWeAWo8hlSMxeu/HizCJqzCLizDNqzDPizERqzETizFVqzFXizGZqzGbizHdqzHfizIhqzIjizJlqzJnizKpqzKrizLtqzLvizMxqzMzizN1qzN3izO5qzO7izP9qzP/izQBq3QDi3RIhat0R4t0iat0i4t0zat0z4t1Eat1E4t1Vat1V4t1qJsQAAAOw==`;
var clock = null;
var testtest = true; //另一个可能会封号的功能,仅调试使用。
advis();
createStatusPanel(); //状态监视面板根据需要进行显示
// 修复错误:检查元素是否存在后再设置内容
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "当前网址已适配ヾ(๑╹◡╹)ノ"
失效请赞赏联系  ε(┬┬﹏┬┬)3";
}
if (urlTip == "course_ware_polyv.aspx") { //保利威播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(1);
} else if (urlTip == "course_ware_cc.aspx") { //CC播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(2);
} else if (urlTip == "face.aspx") { //刷脸
console.log("当前任务: 刷脸界面");
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "course.aspx" || urlTip == "cme.aspx") { //课程列表页面
console.log("当前任务: 课程列表");
huayi.courseList();
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "exam.aspx") { //考试页面
console.log("当前任务: 华医考试");
huayi.doTest();
} else if (urlTip == "exam_result.aspx") { //考试结果页面
console.log("当前任务: 华医考试结果审核");
huayi.doResult();
} else {
console.log("其它情况");
try {
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "此页面非视频、考试或未适配";
}
document.querySelector("img[id='Pic']").style.display = "block";
} catch (error) { };
};
function getHuayi() {
return {
courseList: function () {
addAnwserCopybtn();
addImportAnswerBtn();
DelAllAnwser();
},
seeVideo: function (e) {
var tr = localStorage.getItem(keyPlayRate);
//console.log("存储读取" + tr);//读取倍速
//var playRateNow = tr ? tr : vSpeed;
var playRateNow = 1;
cleanKeyStorage();
asynckillsendQuestion();//屏蔽课堂问答的函数;
killsendQuestion2();//屏蔽课堂问答的函数2;
killsendQuestion3(); //循环检测问答对话框是否弹出。
//addrateinfo();//插入一些按钮
//addratebtn(1);
//addratebtn(1.5);
//addratebtn(2);
//addSkipbtn();//跳过按钮
addinfo();//脚本信息
changelayout();
//速度调节部分
window.onload = function () {
localStorage.setItem(keyThisTitle, JSON.stringify(window.document.title));//储存章节标题
// console.log("准备激活加速");
ratechg(playRateNow);
if (autoSkip == true) {//秒过功能,已经不抵了,别尝试,没用的
setTimeout(function () {
skipVideo();
}, (submitTime + Math.ceil(Math.random() * randomX)));
console.log("秒过了!");
};
clock = setInterval(examherftest, 3000);//阿み杰此处要改11才能考试,循环法用examherftest检测考试按钮是否能点击
;
}
// 保存课程列表(每次都会检查并更新)
console.log('🎬 视频页面加载完成,开始保存/更新课程列表');
saveCourseList();
if (testtest) { addContinuousExamButton(); }// 添加连续考试按钮
// 检查是否是刷脸后返回
checkFaceVerificationReturn();
switch (e) {
case 1:
if (typeof window.s2j_onPlayerInitOver === 'function') {
window.s2j_onPlayerInitOver();
}
{
// 修复静音错误:先检查player对象是否存在
if (typeof player !== 'undefined' && player && player.j2s_setVolume) {
try {
player.j2s_setVolume(0);
console.log("保利威播放器静音成功");
} catch (error) {
console.log("保利威播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof player !== 'undefined' && player && player.j2s_resumeVideo) {
player.j2s_resumeVideo();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
killsendQuestion3();
break;
case 2:
if (typeof window.on_CCH5player_ready === 'function') {
window.on_CCH5player_ready();
}
{
// 修复静音错误:先检查cc_js_Player对象是否存在
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.setVolume) {
try {
cc_js_Player.setVolume(0);
console.log("CC播放器静音成功");
} catch (error) {
console.log("CC播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.play) {
cc_js_Player.play();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
break;
default:
console.log("其他播放器?");
};
},
doTest: function () {
var questions = JSON.parse(localStorage.getItem(keyTest)) || {};
var qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
if (JSON.stringify(qRightAnswer) == "{}") {
qRightAnswer = LoadRightAnwser();
};
var qTestAnswer = {};
var index = 0;
while (true) {
var question = document.querySelectorAll("table[class='tablestyle']")[index];
if (question == null) break;
else {
//var q = question.querySelector(".q_name").innerText.substring(2).replace(/\s*/g, "");//问题的具体文本
// 使用新的题目获取方式
var rawQuestion = question.querySelector(".q_name").innerText.substring(2);
var q = cleanQuestionText(rawQuestion);
console.log(q);
//thisQuestions=thisQuestions+q+"@"
if (qRightAnswer.hasOwnProperty(q)) { //当查询到记录了正确答案时的操作
//console.log("问题:"+ q + ",有答案:"+ qRightAnswer[q]);
var rightSelection = findAnwser("tbody", index, qRightAnswer[q]) //返回答案选项label
if (rightSelection) {
rightSelection.click();
}
} else {
if (questions.hasOwnProperty(q)) {
questions[q] = getNextChoice(questions[q]);//通过Unicode数字+1切换到下一个选项,返回的是字母选项
//console.log("不知道答案:"+ q+",测试:"+questions[q]);
} else { //如果系统没有记录
questions[q] = "A";
};
var answer = getChoiceCode(questions[q]);//将字母选项转换为Unicode数字并减去A代表的65,等于选项顺序,0是第一个选项
var element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
if (!element) { //选项除错机制
console.log("找不到选项,选项更改为A index: " + index + " answer: " + answer);
questions[q] = "A";
answer = getChoiceCode("A");
element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
//localStorage.removeItem(keyTest)
};
try {
var answerText = element.innerText.substring(3);//"A、"占用3个字符
//console.log("测试语法:" + (answerText == element.innerText.trim().substring(2)));
//element.nextSibling.innerText.trim().substring(2); //获得当前答案文本
qTestAnswer[q] = answerText;
//console.log("qTestAnswer:"+error);
} catch (error) { console.log("答案文本获取失败A:" + error); };
if (element) {
element.click();
}
};
index = index + 1;
};
};
//存储相关记录
localStorage.setItem(keyTest, JSON.stringify(questions));
localStorage.setItem(keyTestAnswer, JSON.stringify(qTestAnswer));
setTimeout(function () {
var submitButton = document.querySelector("#btn_submit");
if (submitButton) {
submitButton.click();
}
}, (submitTime + Math.ceil(Math.random() * randomX))); //交卷延时
///专用函数区
function findAnwser(qakey, index, rightAnwserText) {
var answerslist = document.querySelectorAll(qakey)[index];
if (!answerslist) return null;
var arr = answerslist.getElementsByTagName("label");
console.log(`查找答案: ${rightAnwserText}`);
// 精确匹配
for (var i = 0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText===rightAnwserText) {
console.log(`✅ 精确匹配: ${optionText}`);
return arr[i];
}
}
// 模糊匹配
for (var i=0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText.includes(rightAnwserText) || rightAnwserText.includes(optionText)) {
console.log(`🔍 模糊匹配: ${optionText}`);
return arr[i];
}
}
console.log(`❌ 未找到匹配答案,使用第一个选项`);
return arr[0];
}
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] ? $(".tips_text")[0].innerText : null;
var dds=$(".state_cour_lis");
localStorage.removeItem(keyResult);
if (res=="考试通过" || res=="考试通过!" || res=="完成项目学习可以申请学分了" ) {
console.log("考试通过");
saveRightAnwser();
SaveAllAnwser();
cleanKeyStorage();
checkExamContinuation();
setTimeout(function () {
// ...(原有代码)
}, 1000);
} else {
console.log("考试未通过")
var tipsTextElement=document.querySelector("p[class='tips_text' ]");
if (tipsTextElement) {
tipsTextElement.innerText="本次未通过,正在尝试更换答案\r\n(此为正常现象,脚本几秒后刷新,请勿操作)"
}
var qWrong={};
for (var i=0; i < dds.length; ++i) {
if (dds[i].querySelector("img") && !dds[i].querySelector("img").src.includes("bar_img")) {//这里表示否定
var rawQuestion=dds[i].querySelector("p").title;
var cleanedQuestion=cleanQuestionText(rawQuestion);
qWrong[cleanedQuestion]=i
};
};
if (qWrong !={}) {
localStorage.setItem(keyResult, JSON.stringify(qWrong));
saveRightAnwser();
setTimeout(function () {
$("input[type=button][value='重新考试' ]").click();
}, (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 qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) ||{};
var qTitle=JSON.parse(localStorage.getItem(keyThisTitle)) || "没有记录到章节名称" ;
if (qTitle=="没有记录到章节名称" ) {
console.log("没找到章节名称");
return {};
};
var qOldAnswer=qAllAnswer[qTitle] || {};
return qOldAnswer
};
// 修改题目处理逻辑,去除干扰的问号
// 统一的题目清洗函数
function cleanQuestionText(questionText) {
if (!questionText) return '' ;
// 去除各种特殊字符和空白
let cleaned=questionText
.replace(/[??]/g, '' )
.replace(/||[\u200B-\u200D\uFEFF]/g, '' ) // 去除零宽空格
.replace(/\s+/g, ' ' ) // 将多个空格合并为一个
.trim();
// 去除题目编号
cleaned=cleaned.replace(/^\d+、/, '' ).trim();
// 智能处理括号:
// 1. 只删除完全为空或只有空格的括号
// 2. 保留包含实际内容的括号
cleaned=cleaned.replace(/[((]\s*[))]/g, '' ) // 处理空括号
.replace(/[((]\s*([^))\s]+)\s*[))]/g, '$1' ) // 保留括号内的内容
.trim();
return cleaned;
}
// 修改题目获取方式,确保一致性
function getQuestionText(questionElement) {
try {
let rawText=questionElement.querySelector(".q_name").innerText;
// 去除编号部分(如"1、")
let textWithoutNumber=rawText.replace(/^\d+、/, '' );
return cleanQuestionText(textWithoutNumber);
} catch (error) {
console.log("获取题目文本错误:", error);
return "" ;
}
}
// 修改答案记录部分
function saveRightAnwser() {
var qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
var qTestAnswer=JSON.parse(localStorage.getItem(keyTestAnswer)) || {};
var qWrongs=JSON.parse(localStorage.getItem(keyResult)) || {};
console.log("开始保存正确答案...");
console.log("错题记录:", qWrongs);
console.log("测试答案:", qTestAnswer);
// 构建清理后的题目映射
var cleanedWrongs={};
for (var wrongQ in qWrongs) {
var cleanedWrongQ=cleanQuestionText(wrongQ);
cleanedWrongs[cleanedWrongQ]=true;
console.log(`错题清洗: "${wrongQ}" -> "${cleanedWrongQ}"`);
}
for (var q in qTestAnswer) {
var cleanedQ = cleanQuestionText(q);
console.log(`处理题目: "${q}" -> "${cleanedQ}", 答案: ${qTestAnswer[q]}`);
if (!cleanedWrongs[cleanedQ]) {
console.log(`✅ 正确答案: "${cleanedQ}" -> ${qTestAnswer[q]}`);
qRightAnswer[cleanedQ] = qTestAnswer[q];
} else {
console.log(`❌ 错误题目: "${cleanedQ}" -> ${qTestAnswer[q]}`);
}
}
localStorage.removeItem(keyTestAnswer);
if (Object.keys(qRightAnswer).length > 0) {
localStorage.setItem(keyRightAnswer, JSON.stringify(qRightAnswer));
console.log("✅ 正确答案已保存:", qRightAnswer);
} else {
console.log("❌ 没有正确答案需要保存");
}
}
//答案记录函数区结束//
//------------------答案复制相关按钮--------------------------------------------
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")
//Aout=encodeURIComponent(Aout);
//window.prompt("请复制",Aout);
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;
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(textout);
}
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.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);
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
//答案复制相关按钮 end
function skipVideo() {//这是跳过视频的代码
var oVideo = document.getElementsByTagName('video')[0];
if (oVideo) {
oVideo.currentTime = oVideo.duration - 1
};
};
// 在 courseList 函数中添加导入答案按钮
function addImportAnswerBtn() {
let alink = document.createElement("a");
alink.innerHTML = '导入答案';
alink.style = btstyleB;
alink.onclick = function (event) {
var input = prompt("请粘贴要导入的答案数据(JSON格式)");
if (input) {
try {
// 解析输入的JSON数据
var importedAnswers = JSON.parse(input);
// 获取现有的答案记录
var existingAnswers = JSON.parse(localStorage.getItem(keyAllAnswer)) || {};
// 合并答案
var mergedAnswers = mergeAnswerData(existingAnswers, importedAnswers);
// 保存合并后的答案
localStorage.setItem(keyAllAnswer, JSON.stringify(mergedAnswers));
alert("✅ 答案导入成功!\n已合并 " + Object.keys(importedAnswers).length + " 个章节的答案");
} catch (error) {
alert("❌ 导入失败:数据格式不正确\n" + error);
}
}
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
// 合并答案数据的函数
function mergeAnswerData(existing, imported) {
// 深拷贝现有答案
var merged = JSON.parse(JSON.stringify(existing));
// 遍历导入的答案
for (var chapter in imported) {
if (imported.hasOwnProperty(chapter)) {
// 如果章节不存在,直接添加
if (!merged[chapter]) {
merged[chapter] = imported[chapter];
} else {
// 合并章节内的题目答案
for (var question in imported[chapter]) {
if (imported[chapter].hasOwnProperty(question)) {
merged[chapter][question] = imported[chapter][question];
}
}
}
}
}
return merged;
};
//------------------看视频页面主要函数-------------------------------------------
function clickexam() { //延时点击考试按钮。
console.log("已点击考试按钮");
setTimeout(function () {
var examButton = document.querySelector("#jrks");
if (examButton) {
examButton.click();
}
}, (Math.ceil(Math.random() * randomX)));
//}, (examTime + Math.ceil(Math.random() * randomX)));
};
//按钮插入函数相关
function addSkipbtn() {//插入按钮快进视频按钮
let alink = document.createElement("a");
alink.innerHTML = '快进视频';
alink.style = btstyleA;
alink.onclick = function (event) {
skipVideo();
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
};
function addratebtn(ra) {//倍率调整按钮
let alink = document.createElement("a");
alink.innerHTML = '' + ra + 'x';
alink.style = btstyleB;
alink.className = "speed";
alink.id = ra + "x";
alink.onclick = function (event) {
ratechg(ra);
try {
var arr = document.querySelectorAll("a[class='speed']");
arr.forEach(function (item, index, arr) {
arr[index].style = btstyleB;
});
} catch (error) {
};
alink.style = btstyleC;
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
}
function ratechg(ra) {//倍率调整
var videoObj = document.querySelector("video")
if (videoObj) {
try {
clearInterval(nspeed);
nspeed = setInterval(() => {
videoObj.playbackRate = ra;
}, 1 * 1000);
localStorage.setItem(keyPlayRate, ra);
//document.querySelector("a[id=" + "'" + ra + "x']").style = btstyleC;
//document.getElementById("playrate").innerHTML = "当前播放速率" + ra + "x";
//console.log("倍率调整为" + ra);
} catch (error) { console.log("倍率调整错误" + error); };
}
};
function addrateinfo() {//插入说明
let adiv1 = document.createElement("div");
adiv1.innerHTML = '当前播放速率';
adiv1.id = 'playrate';
adiv1.style = "font-size: 15px;text-align: center;margin-top: 10px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv1);
}
};
function addinfo() {//插入说明
//模式切换按钮
var moderesult = localStorage.getItem("华医mode");
if (moderesult == 2) {
moderesult = "当前模式:视频+考试";
} else {//包括了结果为1或者无存储的情况
moderesult = "当前模式:单刷视频";
};
var checkbox = document.createElement('div');
checkbox.innerHTML = '' + moderesult + '
[点击此处切换] ';
// 添加到页面的 body 元素中
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(checkbox);
}
//插入说明部分
let mode1 = document.querySelector("a[id='mode']");
if (mode1) {
mode1.onclick = function () {
if (mode1.innerText == "当前模式:单刷视频\n[点击此处切换]") {
mode1.innerText = "当前模式:视频+考试\n[点击此处切换]";
localStorage.setItem("华医mode", "2");
} else {
mode1.innerText = "当前模式:单刷视频\n[点击此处切换]";
localStorage.setItem("华医mode", "1");
};
};
}
let adiv2 = document.createElement("div");
adiv2.innerHTML = '       本人医学研一学生,经常要帮师兄师姐刷华医视频,属实太累。偶然在抖音发现Dr.S的脚本,结果刷完1个视频立刻考试,导致频繁人脸识别跟手动区别不大。原作者已不更新,于是我自学修改了播放逻辑,实现无人值守连续播放。现将原先自用的脚本分享给大家❤❤
     刷完视频再切换考试模式,即可连续考试。
';
adiv2.id = 'jsinfo';
adiv2.style = "position:relative;left:10px;top:5px;width:240px;font-size:13px;text-align: justify;border: 1px dashed #ff9595;padding:5px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv2);
}
if (typeof $ !== 'undefined') {
$('div:contains("观看视频完成后,才能进入考试")').eq(-1).text('建议360安全浏览器和脚本猫');
}
// 创建连续考试按钮的容器
let examBtnContainer = document.createElement('div');
examBtnContainer.id = 'continuousExamBtnContainer';
examBtnContainer.style = "text-align: center; margin: 10px 0;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(examBtnContainer);
}
};
function changelayout() {
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv) {
jjDiv.remove();
}
var photoImg = document.querySelector("img[id='photo']");
if (photoImg) {
photoImg.outerHTML = `
`;
photoImg.style.width = "120px";
photoImg.style.height = "120px";
}
var titleDivs = document.querySelectorAll("div[class='title']");
if (titleDivs[0] && titleDivs[0].children[0]) {
titleDivs[0].children[0].style = "color: #ff0000;font-weight: bold";
titleDivs[0].children[0].innerText = "支持作者";
}
var imgTextDivs = document.querySelector("div[class='imgtext']");
if (imgTextDivs && imgTextDivs.children[1]) {
imgTextDivs.children[1].style.width = "125px";
imgTextDivs.children[1].style = "color: #ff0000;padding-top:10px";
imgTextDivs.children[1].innerText = "作 者\n创作优化不易\n投点小费吧\n❤谢啦❤\n❤"
}
var topDiv = document.querySelector("div[class='top']");
if (topDiv) {
topDiv.outerHTML = '如服务器调整,脚本可能失效。反馈意见、免费增加课程请在Greasyfork私信或脚本反馈区联络。也欢迎投喂↓
';
}
};
function cleanKeyStorage() {//缓存清理
localStorage.removeItem(keyTest);
localStorage.removeItem(keyResult);
localStorage.removeItem(keyTestAnswer);
localStorage.removeItem(keyRightAnswer);
};
function examherftest() {//考试按钮激活状态检测
var examButton = document.getElementById("jrks");
var hreftest = examButton ? examButton.attributes["disabled"] : null;
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if ((state == "已完成" || state == "待考试" || !hreftest) && examButton) {//value不为#说明考试按钮已经激活
console.log("已经播放完了");
// 优先处理"视频+考试"模式下的"待考试"状态
var modeElement = document.querySelector("a[id='mode']");
if (modeElement && modeElement.innerText.indexOf("视频+考试") != -1 && state == "待考试") {
console.log("mode=2,准备进入考试");
// 重试机制:尝试5次进入考试
var retryCount = 0;
var maxRetries = 5;
function tryEnterExam() {
retryCount++;
console.log(`尝试进入考试 (第${retryCount}次)`);
try {
// 方法1:尝试点击考试按钮
if (document.getElementById("jrks") && !document.getElementById("jrks").disabled) {
document.getElementById("jrks").click();
console.log("成功点击考试按钮");
return true; // 成功进入考试
}
// 方法2:尝试备用方式
if (typeof cwrid !== 'undefined') {
window.open("/pages/exam_tip.aspx?cwrid=" + cwrid, "_self");
console.log("尝试备用方式进入考试");
return true;
}
// 方法3:尝试通过URL跳转
var currentUrl = window.location.href;
if (currentUrl.includes("course_ware")) {
var examUrl = currentUrl.replace("course_ware/course_ware_", "pages/exam.aspx?cwid=")
.split("?")[0] + "?cwid=" + getUrlParam("cwid");
window.location.href = examUrl;
console.log("尝试通过URL跳转进入考试");
return true;
}
} catch (error) {
console.log(`第${retryCount}次尝试失败:`, error);
}
return false; // 进入考试失败
}
// 立即尝试第一次
if (tryEnterExam()) {
return; // 成功进入考试,直接返回
}
// 设置重试间隔
var retryInterval = setInterval(function () {
if (retryCount >= maxRetries) {
clearInterval(retryInterval);
console.log(`尝试${maxRetries}次进入考试均失败,继续听课`);
// 继续执行后续的跳转到下一个视频的逻辑
proceedToNextVideo();
} else if (tryEnterExam()) {
clearInterval(retryInterval); // 成功进入考试,停止重试
}
}, 2000); // 每2秒重试一次
} else {
// 单刷视频模式或非待考试状态,直接继续听课
proceedToNextVideo();
};
} else {//#代表考试按钮还没激活
//继续播放,无需任何操作
}
}
// 跳转到下一个视频的函数
function proceedToNextVideo() {
console.log('🚀 准备跳转到下一个视频...');
const nextCwid = getNextCourseCwid();
if (nextCwid) {
console.log(`✅ 确定跳转到课程: ${nextCwid.substring(0, 8)}...`);
console.log(`🌐 跳转URL: course_ware.aspx?cwid=${nextCwid}`);
// 延迟跳转,让用户有时间查看日志
setTimeout(() => {
console.log('⏩ 正在跳转...');
window.location.href = `course_ware.aspx?cwid=${nextCwid}`;
}, 2000);
} else {
console.log('❌ 没有找到可用的课程,尝试刷新页面');
setTimeout(() => {
console.log('🔄 正在刷新页面...');
window.location.reload();
}, 2000);
}
}
// 辅助函数:获取URL参数
function getUrlParam(name) {
var urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
};
//课堂问答跳过,临时版
function sleep(timeout) {
return new Promise((resolve) => { setTimeout(resolve, timeout); });
console.log("课堂问答循环调用");
};
function asynckillsendQuestion() {
(async function () {
while (!window.player || !window.player.sendQuestion) {
await sleep(20);
};
//console.log("课堂问答跳过插入");
player.sendQuestion = function () {
//console.log("播放器尝试弹出课堂问答,已屏蔽。");
};
})();
};
function killsendQuestion2() {
if (typeof (isInteraction) == "undefined") {
//console.log('变量未定义');
} else {
console.log('isInteraction设置off');
isInteraction = "off";
};
};
function killsendQuestion3() { //点击跳过按钮版的跳过课堂答题
var clockms = setInterval(async function () {
try {
if (typeof $ !== 'undefined' && $('.pv-ask-head').length && $('.pv-ask-head').length > 0) {
console.log("检测到问题对话框,尝试跳过");
$(".pv-ask-skip").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.signBtn').length && $('.signBtn').length > 0) {
console.log("检测到签到对话框,尝试跳过");
$(".signBtn").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' &&
$("button[onclick='closeProcessbarTip()']").length &&
$("button[onclick='closeProcessbarTip()']").length > 0 &&
$("div[id='div_processbar_tip']").css("display") == "block") {
console.log("检测到温馨提示对话框(不能拖拽),尝试跳过");//
//*[@id="div_processbar_tip"]/div/div[2]/input
//document.querySelector("#div_processbar_tip > div > div.foot_sub > input")
//#div_processbar_tip > div > div.foot_sub > input
//
$("button[onclick='closeBangZhu()']").click();
$("button[onclick='closeProcessbarTip()']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $("button[class='btn_sign']").length && $("button[class='btn_sign']").length > 0) {
console.log("检测到温馨提示对话框(疲劳提醒),尝试跳过");
$("button[class='btn_sign']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.rig_btn').length && $('.rig_btn').length > 0) {
if ($('#div_processbar_tip').is(':visible')) {
console.log("检测到按钮(知道了),执行隐藏操作");
$('#div_processbar_tip').hide();
}
//$(".rig_btn").click();
};
} catch (err) {
console.log(err);
};
try {
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if (typeof $ !== 'undefined' &&
$('video').prop('paused') == true &&
state != "已完成" &&
state != "待考试") {
console.log("视频意外暂停,恢复播放");
$('video').get(0).play();
//$('video').prop('volumed') = 0;
$('video').prop('muted') = true;
} else if (state == "已完成") {
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.pause();
}
//clearInterval(clockms);
};
} catch (err) {
//console.log(err);
};
}, 10000);
};
function autoClickKnowButton() {
// 检测按钮是否加载完成
const observer = new MutationObserver(() => {
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
observer.disconnect(); // 停止观察
button.click(); // 点击按钮
}
});
// 开始观察文档的变化
observer.observe(document.body, {
childList: true,
subtree: true
});
// 如果按钮已经加载完成,直接点击
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
button.click();
}
}
// 在全局函数区添加以下函数
function saveCourseList() {
console.log('📋 开始保存/更新课程列表...');
// 尝试获取课程列表容器
const courseContainer = document.querySelector('.page-container');
if (!courseContainer) {
console.log('❌ 未找到课程列表容器');
return;
}
// 尝试获取课程项
const courseItems = document.querySelectorAll('.lis-inside-content');
if (courseItems.length === 0) {
console.log('❌ 未找到课程项');
return;
}
console.log(`📚 找到 ${courseItems.length} 个课程项,开始解析...`);
const currentCourseList = [];
let hasChanges = false;
courseItems.forEach((item, index) => {
const titleElement = item.querySelector('h2');
const statusButton = item.querySelector('button');
if (titleElement && statusButton) {
const title = titleElement.textContent.trim();
const status = statusButton.textContent.trim();
const statusColor = statusButton.style.background;
// 从onclick属性中提取cwid
const onclickAttr = titleElement.getAttribute('onclick');
let cwid = '';
if (onclickAttr) {
const match = onclickAttr.match(/cwid=([^']+)/);
if (match && match[1]) {
cwid = match[1];
}
}
if (cwid) {
currentCourseList.push({
title,
status,
statusColor,
cwid,
index
});
//console.log(` 课程 ${index + 1}: "${title}" - 状态: ${status}`);
}
}
});
if (currentCourseList.length === 0) {
console.log('❌ 未解析到任何课程信息');
return;
}
// 获取之前保存的课程列表
const previousCourseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
if (previousCourseList.length === 0) {
// 第一次保存
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`✅ 首次保存课程列表完成,共 ${currentCourseList.length} 个课程`);
return;
}
// 检查是否有变化
console.log('🔍 检查课程状态变化...');
for (let i = 0; i < currentCourseList.length; i++) {
const currentCourse=currentCourseList[i];
const previousCourse=previousCourseList[i];
if (!previousCourse) {
console.log(` 新增课程: "${currentCourse.title}" `);
hasChanges=true;
continue;
}
// 检查状态变化
if (currentCourse.status !==previousCourse.status) {
console.log(` 状态变化: "${currentCourse.title}" - ${previousCourse.status} → ${currentCourse.status}`);
hasChanges=true;
}
// 检查标题变化(可能课程有更新)
if (currentCourse.title !==previousCourse.title) {
console.log(` 标题变化: "${previousCourse.title}" → "${currentCourse.title}" `);
hasChanges=true;
}
// 检查cwid变化(理论上不应该变)
if (currentCourse.cwid !==previousCourse.cwid) {
console.log(` cwid变化: "${currentCourse.title}" `);
hasChanges=true;
}
}
// 检查课程数量变化
if (currentCourseList.length !==previousCourseList.length) {
console.log(` 课程数量变化: ${previousCourseList.length} → ${currentCourseList.length}`);
hasChanges=true;
}
if (hasChanges) {
// 更新课程列表
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`🔄 课程列表已更新,共 ${currentCourseList.length} 个课程`);
// 输出详细的课程状态
console.log('📊 当前所有课程状态:');
currentCourseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
} else {
console.log('✅ 课程列表无变化,无需更新');
// 即使无变化,也确保本地存储的是最新数据(防止数据损坏)
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
}
}
function getCurrentCourseCwid() {
// 从当前URL获取cwid
const urlParams = new URLSearchParams(window.location.search);
const cwid = urlParams.get('cwid');
console.log(`🔍 当前课程 cwid: ${cwid ? cwid.substring(0, 8) + '...' : '未找到'}`);
return cwid;
}
function getNextCourseCwid() {
console.log('🔄 开始查找下一个课程...');
// 尝试从localStorage获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
const currentCwid = getCurrentCourseCwid();
if (courseList.length === 0) {
console.log('❌ 未找到存储的课程列表');
return null;
}
console.log(`📊 课程列表中有 ${courseList.length} 个课程`);
// 找到当前课程的索引
const currentIndex = courseList.findIndex(course => course.cwid === currentCwid);
if (currentIndex === -1) {
console.log('❌ 未找到当前课程在列表中的位置');
console.log('当前课程可能不在列表中,将尝试第一个未完成的课程');
// 尝试查找第一个未完成的课程
for (let i = 0; i < courseList.length; i++) {
const course=courseList[i];
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到第一个未完成课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
return null;
}
console.log(`📍 当前课程位置: 第 ${currentIndex + 1} 个 - "${courseList[currentIndex].title}" `);
// 查找下一个未完成的课程(从当前位置向后找)
console.log('🔍 向后查找未完成的课程...');
for (let i=currentIndex + 1; i < courseList.length; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到下一个课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
// 如果后面没有未完成的课程,尝试从开头查找
console.log('🔍 向后未找到,从开头查找未完成的课程...');
for (let i=0; i < currentIndex; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到前面的课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
console.log('所有课程状态:');
courseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
return null;
}
//--------------------------插入悬浮框------------------------------------//
function advis() {
// 🔴 第一步:只在顶层窗口运行,iframe 中直接退出
if (window.self !== window.top) {
console.log('小助手:当前处于 iframe 中,不创建面板');
return;
}
// 🔴 第二步:检查是否已有面板,防止重复创建(即使脚本多次调用)
const existingPanel = document.getElementById('Div1');
if (existingPanel) {
console.log('已检测到小助手面板,防止重复创建');
return; // 或者 existingPanel.remove(); 再创建(推荐 return 即可)
}
// 🟡 第三步:创建新面板
let div1 = document.createElement("div");
div1.innerHTML = `
`;
document.body.append(div1);
// 绑定事件
let share1 = document.getElementById('Share1');
let share2 = document.getElementById('Share2');
let clo = document.getElementById('clo');
if (share1) {
share1.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/500010", "_blank");
};
}
if (share2) {
share2.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/555651", "_blank");
};
}
if (clo) {
clo.onclick = function () {
var panel = document.getElementById('Div1');
if (panel) {
panel.style.display = 'none';
}
};
}
// === 初始化:左对齐课程列表 ===
const panel = document.getElementById('Div1');
if (!panel) return;
const container = document.querySelector('.page-container') ||
document.querySelector('.lis-content') ||
document.querySelector('.container-inside-header');
let initialLeft = 140; // 默认值
if (container) {
const rect = container.getBoundingClientRect();
initialLeft = rect.left + window.pageXOffset;
}
panel.style.left = initialLeft + 'px';
// === 拖拽功能 ===
let isDragging = false;
let offsetX, offsetY;
panel.addEventListener('mousedown', function (e) {
if (e.target === clo ||
e.target.tagName === 'A' ||
e.target.tagName === 'IMG' ||
e.target.tagName === 'HR') return;
isDragging = true;
offsetX = e.clientX - panel.getBoundingClientRect().left;
offsetY = e.clientY - panel.getBoundingClientRect().top;
e.preventDefault();
});
document.addEventListener('mousemove', function (e) {
if (!isDragging) return;
panel.style.left = (e.clientX - offsetX) + 'px';
panel.style.top = (e.clientY - offsetY) + 'px';
});
document.addEventListener('mouseup', () => {
isDragging = false;
});
// 创建状态面板(默认隐藏)
//createStatusPanel();
//document.getElementById('examStatusPanel').style.display = 'none';
}
//--------------------------连续考试的函数------------------------------------//
// 修改 addContinuousExamButton 函数
function addContinuousExamButton() {
// 检查是否已存在连续考试按钮
if (document.getElementById('continuousExamBtn')) {
return;
}
// 创建连续考试按钮
let btn = document.createElement("a");
btn.innerHTML = '连续考试';
btn.style = btstyleA
btn.id = 'continuousExamBtn';
btn.onclick = function () {
console.log('🚀 开始连续考试流程...');
startContinuousExam();
};
// 找到建议提示框
const tipDiv = document.querySelector('div.r div[style*="border: 1px dashed #ff9595"]');
if (tipDiv) {
// 创建按钮容器
let btnContainer = document.createElement('div');
btnContainer.style = "text-align: center; margin: 10px 0;";
btnContainer.appendChild(btn);
// 将按钮容器插入到建议提示框后面
tipDiv.parentNode.insertBefore(btnContainer, tipDiv.nextSibling);
} else {
// 如果找不到建议提示框,使用预留的容器
const btnContainer = document.getElementById('continuousExamBtnContainer');
if (btnContainer) {
btnContainer.appendChild(btn);
} else {
// 如果容器也不存在,添加到页面底部
document.body.appendChild(btn);
}
}
}
// 新增:创建状态面板的函数
function createStatusPanel() {
// 检查是否存在 exam_phase
const examPhase = localStorage.getItem('exam_phase');
if (!examPhase) {
// 如果不存在 exam_phase,移除可能存在的面板
const existingPanel = document.getElementById('examStatusPanel');
if (existingPanel) {
existingPanel.remove();
}
return;
}
// 检查是否已存在状态面板
if (document.getElementById('examStatusPanel')) {
// 如果面板已存在,只需更新状态信息
updatePanelContent();
return;
}
// 创建状态面板
const panel = document.createElement('div');
panel.id = 'examStatusPanel';
panel.style = `
position: fixed;
top: 20px;
right: 20px;
width: 300px;
background-color: rgba(255, 255, 255, 0.95);
border: 2px solid #4cb0f9;
border-radius: 8px;
padding: 15px;
z-index: 10000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
font-family: 'Microsoft YaHei', sans-serif;
`;
panel.innerHTML = `
连续考试状态
加载中...
`;
// 确保面板正确插入到页面中
document.body.appendChild(panel);
// 添加取消按钮事件
var cancelBtn = document.getElementById('cancelExamBtn');
if (cancelBtn) {
cancelBtn.onclick = function () {
if (confirm('确定要取消连续考试吗?')) {
cancelContinuousExam();
}
};
}
// 更新面板内容
updatePanelContent();
// 辅助函数:更新面板内容
function updatePanelContent() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examPhase = localStorage.getItem('exam_phase');
let statusMessage = '';
if (examPhase === 'face_verification') {
statusMessage = `👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else if (examPhase === 'examination') {
statusMessage = `📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else {
statusMessage = '连续考试进行中...';
}
const contentElement = document.getElementById('examStatusContent');
if (contentElement) {
contentElement.innerHTML = statusMessage;
}
}
}
// 修改:更新状态提示的函数
function updateExamStatus(message, isError = false) {
createStatusPanel(); // 确保面板存在
const panel = document.getElementById('examStatusPanel');
// 添加存在性检查
if (!panel) {
console.log('状态面板不存在,跳过更新');
return;
}
panel.style.display = 'block';
const statusContent = document.getElementById('examStatusContent');
if (statusContent) {
statusContent.innerHTML = message;
statusContent.style.color = isError ? '#f15854' : '#333';
}
}
// 取消连续考试
function cancelContinuousExam() {
console.log('❌ 结束连续考试');
// 清除相关状态
localStorage.removeItem('exam_courses');
localStorage.removeItem('current_exam_index');
localStorage.removeItem('exam_phase');
// 只有在面板存在时才更新状态
const panel = document.getElementById('examStatusPanel');
if (panel) {
updateExamStatus('连续考试已取消');
// 3秒后隐藏状态面板
setTimeout(() => {
//panel.style.display = 'none';
}, 3000);
} else {
console.log('状态面板不存在,直接清除状态');
}
}
// 连续考试主函数
function startContinuousExam() {
// 强制设置为单刷视频模式,避免冲突
localStorage.setItem("华医mode", "1");
console.log('🚀 开始连续考试流程,模式强制设置为单刷视频');
localStorage.setItem('exam_phase', 'setup'); // 设置阶段为初始化
// 创建状态面板
createStatusPanel();
// 获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
// 筛选待考试的课程
const examCourses = courseList.filter(course => course.status === '待考试');
if (examCourses.length === 0) {
console.log('❌ 没有找到待考试的课程');
updateExamStatus('❌ 没有找到待考试的课程', true);
localStorage.removeItem('exam_phase');
return;
}
// 保存待考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
localStorage.setItem('exam_phase', 'face_verification'); // 设置阶段为刷脸
console.log(`📋 找到 ${examCourses.length} 个待考试课程`);
updateExamStatus(`找到 ${examCourses.length} 个待考试课程
准备开始刷脸流程...`);
// 开始刷脸流程
startFaceVerificationProcess();
}
// 刷脸流程
function startFaceVerificationProcess() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有课程刷脸完成,开始连续考试');
updateExamStatus('✅ 所有课程刷脸完成
开始连续考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startFaceVerificationProcess, 1000);
return;
}
console.log(`👤 开始第 ${currentIndex + 1} 个课程刷脸: ${currentCourse.title}`);
updateExamStatus(`👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开课程链接进行刷脸
window.location.href = `course_ware.aspx?cwid=${currentCourse.cwid}`;
}
// 监听页面加载,判断是否在刷脸后返回
function checkFaceVerificationReturn() {
const examPhase = localStorage.getItem('exam_phase');
const isInFaceVerification = examPhase === 'face_verification';
if (isInFaceVerification) {
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
// 只有当索引有效时才继续
if (currentIndex < examCourses.length) {
console.log('🔍 检测到刷脸后返回,继续下一个课程');
localStorage.setItem('current_exam_index', currentIndex + 1);
updateExamStatus(`✅ 刷脸完成 ${currentIndex + 1}/${examCourses.length}
准备下一个课程...`);
// 添加延迟防止过快跳转
setTimeout(startFaceVerificationProcess, 3000);
} else {
console.log('✅ 刷脸流程已完成');
updateExamStatus('✅ 刷脸流程已完成
准备开始考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
}
}
}
// 开始所有考试
function startAllExams() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
if (examCourses.length === 0) {
console.log('❌ 没有待考试的课程');
updateExamStatus('❌ 没有待考试的课程', true);
return;
}
console.log('🎯 开始连续考试流程');
updateExamStatus(`🎯 开始连续考试流程
共 ${examCourses.length} 个考试待完成`);
// 保存考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
// 开始第一个考试
startNextExam();
}
// 开始下一个考试
function startNextExam() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有考试完成!');
updateExamStatus('✅ 所有考试完成!
连续考试流程结束');
cancelContinuousExam();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startNextExam, 1000);
return;
}
console.log(`📝 开始第 ${currentIndex + 1} 个考试: ${currentCourse.title}`);
updateExamStatus(`📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开考试页面
window.location.href = `/pages/exam.aspx?cwid=${currentCourse.cwid}`;
}
// 在考试结果页面检查是否需要继续下一个考试
function checkExamContinuation() {
const examPhase = localStorage.getItem('exam_phase');
const isInExamMode = examPhase === 'examination';
if (isInExamMode) {
console.log('🔍 检测到考试完成,准备下一个考试');
// 增加索引
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
localStorage.setItem('current_exam_index', currentIndex + 1);
// 更新状态提示
updateExamStatus(`✅ 考试完成 ${currentIndex + 1}/${examCourses.length}
准备下一个考试...`);
// 短暂延迟后继续下一个考试
setTimeout(() => {
startNextExam();
}, 3000);
}
}
//---------------------------------全局函数区end------------------------------//
})();gwQOWPuloSKykYzlA6CZxbTEFRiWVVbcQ9nxyvmpirmdmlD/UAA/8MQzsAMGXECpceKpvAcHnEPEINwkLqIrLlf5pEMBIMA7PEM0YMAHJZwU/gM9gM97RAMuaNhMuM1JXVc+jJNT+IUnFgMJsMM6BCPVJeIrTiOBHdkFtIM+3Nc5xN4j7c35jQUR5MP0pcSfPU5JoYPctWLHpIOqOQCwfZ0ZHlECUiM9al3FXIc4NZx2zeMwiYNwrU8znIdTJIA63JA/HI4gwsReXGBNlMPmHV49RuSBqVimzAneIJkuZh5tOUszGKQ/oIPKNIXLhEmnxALdIGIy+shaHNfrSaRLnhmbvdsXYhBGbMqQfSR+NIXe1AhwzEX8vSRQBiXfGUk5kM84/xJMP1xAM6QTWXDAJjYFPoTHDT0DBjSTUF4lVrogdBhAMDQDBjhAkRzl2kCHsSDLHJ2DOoYEAZCUzpDAMEgOP2alXO4d6tkFMtSDO5SUKH4fBikJLBDWhIkD7PUDLBRkJPEDmaTlXC4mNyIHtIDJO1BA+LlYSCBDNPBkWSAAFL6I5XgjcLADLBgYY46mK6Ie59UDlfQEdK0RRhjAI8KMOpxAQsLEOdCVPEkLBYgmae4mGtZFc90Qk8ldX2KSJt2QO+hD4zVFOizlezyDO+SmYvKmdIranp2TdZUFBkwm9RwHfXghbSDHPzanH4VdXhRmmywYO1SYdk4ne3LdUqhFMP8ECZu0j26GFJuNQAJQQD4YQHShpJtdgHBVSZsU14s4Zh36xDpgiX+2J4PmHdXhQzDUAwLwgwjoA8JwZpoMg/kpWsWl5VBcgFTCDAnUUzKGRFRIKD+gw0nGZYO2qBo+HgHggwGcwDbuGVH8BQFwQDoNXTiJ3nV0JP34Q+SkJEiUQzsgwwno3g66KJOKGs2Ux5GMUxfOBNtYDgLAzYAqJlNQgEeWAJYUaIDE1Ho2KZmW4B+xzXk85Ez0VTsY5nuQx5imRFvY2OCtg8Ul44/dB8JEZ5n26VlVm19QjI3KxJ7dQ3GKhwPEaf50ILI8g2Sm3VJIR+p9IYv6qaX6HOu9FZ///kU5oMONsc/+cWJQKCXH4ZRsKipgaIkkFhGfXqqrThtvnAAhEYE6lIA+5CRnsgchsUMsDANyAuGrBquLVttHgAAuIAMu0ENWGN6ptcUsGIA+JIA4RJOwVmt7GmF3imV6wF+Ytqq1fusi6kXlRGkCvqc+Viq4pqv/AQuM8NxsrGQcqqu8YiX6tB6XoKr5DBg0kNyazau/XuWeAWo8hlSMxeu/HizCJqzCLizDNqzDPizERqzETizFVqzFXizGZqzGbizHdqzHfizIhqzIjizJlqzJnizKpqzKrizLtqzLvizMxqzMzizN1qzN3izO5qzO7izP9qzP/izQBq3QDi3RIhat0R4t0iat0i4t0zat0z4t1Eat1E4t1Vat1V4t1qJsQAAAOw==`;
var clock = null;
var testtest = true; //另一个可能会封号的功能,仅调试使用。
advis();
createStatusPanel(); //状态监视面板根据需要进行显示
// 修复错误:检查元素是否存在后再设置内容
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "当前网址已适配ヾ(๑╹◡╹)ノ"
失效请赞赏联系  ε(┬┬﹏┬┬)3";
}
if (urlTip == "course_ware_polyv.aspx") { //保利威播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(1);
} else if (urlTip == "course_ware_cc.aspx") { //CC播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(2);
} else if (urlTip == "face.aspx") { //刷脸
console.log("当前任务: 刷脸界面");
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "course.aspx" || urlTip == "cme.aspx") { //课程列表页面
console.log("当前任务: 课程列表");
huayi.courseList();
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "exam.aspx") { //考试页面
console.log("当前任务: 华医考试");
huayi.doTest();
} else if (urlTip == "exam_result.aspx") { //考试结果页面
console.log("当前任务: 华医考试结果审核");
huayi.doResult();
} else {
console.log("其它情况");
try {
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "此页面非视频、考试或未适配";
}
document.querySelector("img[id='Pic']").style.display = "block";
} catch (error) { };
};
function getHuayi() {
return {
courseList: function () {
addAnwserCopybtn();
addImportAnswerBtn();
DelAllAnwser();
},
seeVideo: function (e) {
var tr = localStorage.getItem(keyPlayRate);
//console.log("存储读取" + tr);//读取倍速
//var playRateNow = tr ? tr : vSpeed;
var playRateNow = 1;
cleanKeyStorage();
asynckillsendQuestion();//屏蔽课堂问答的函数;
killsendQuestion2();//屏蔽课堂问答的函数2;
killsendQuestion3(); //循环检测问答对话框是否弹出。
//addrateinfo();//插入一些按钮
//addratebtn(1);
//addratebtn(1.5);
//addratebtn(2);
//addSkipbtn();//跳过按钮
addinfo();//脚本信息
changelayout();
//速度调节部分
window.onload = function () {
localStorage.setItem(keyThisTitle, JSON.stringify(window.document.title));//储存章节标题
// console.log("准备激活加速");
ratechg(playRateNow);
if (autoSkip == true) {//秒过功能,已经不抵了,别尝试,没用的
setTimeout(function () {
skipVideo();
}, (submitTime + Math.ceil(Math.random() * randomX)));
console.log("秒过了!");
};
clock = setInterval(examherftest, 3000);//阿み杰此处要改11才能考试,循环法用examherftest检测考试按钮是否能点击
;
}
// 保存课程列表(每次都会检查并更新)
console.log('🎬 视频页面加载完成,开始保存/更新课程列表');
saveCourseList();
if (testtest) { addContinuousExamButton(); }// 添加连续考试按钮
// 检查是否是刷脸后返回
checkFaceVerificationReturn();
switch (e) {
case 1:
if (typeof window.s2j_onPlayerInitOver === 'function') {
window.s2j_onPlayerInitOver();
}
{
// 修复静音错误:先检查player对象是否存在
if (typeof player !== 'undefined' && player && player.j2s_setVolume) {
try {
player.j2s_setVolume(0);
console.log("保利威播放器静音成功");
} catch (error) {
console.log("保利威播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof player !== 'undefined' && player && player.j2s_resumeVideo) {
player.j2s_resumeVideo();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
killsendQuestion3();
break;
case 2:
if (typeof window.on_CCH5player_ready === 'function') {
window.on_CCH5player_ready();
}
{
// 修复静音错误:先检查cc_js_Player对象是否存在
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.setVolume) {
try {
cc_js_Player.setVolume(0);
console.log("CC播放器静音成功");
} catch (error) {
console.log("CC播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.play) {
cc_js_Player.play();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
break;
default:
console.log("其他播放器?");
};
},
doTest: function () {
var questions = JSON.parse(localStorage.getItem(keyTest)) || {};
var qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
if (JSON.stringify(qRightAnswer) == "{}") {
qRightAnswer = LoadRightAnwser();
};
var qTestAnswer = {};
var index = 0;
while (true) {
var question = document.querySelectorAll("table[class='tablestyle']")[index];
if (question == null) break;
else {
//var q = question.querySelector(".q_name").innerText.substring(2).replace(/\s*/g, "");//问题的具体文本
// 使用新的题目获取方式
var rawQuestion = question.querySelector(".q_name").innerText.substring(2);
var q = cleanQuestionText(rawQuestion);
console.log(q);
//thisQuestions=thisQuestions+q+"@"
if (qRightAnswer.hasOwnProperty(q)) { //当查询到记录了正确答案时的操作
//console.log("问题:"+ q + ",有答案:"+ qRightAnswer[q]);
var rightSelection = findAnwser("tbody", index, qRightAnswer[q]) //返回答案选项label
if (rightSelection) {
rightSelection.click();
}
} else {
if (questions.hasOwnProperty(q)) {
questions[q] = getNextChoice(questions[q]);//通过Unicode数字+1切换到下一个选项,返回的是字母选项
//console.log("不知道答案:"+ q+",测试:"+questions[q]);
} else { //如果系统没有记录
questions[q] = "A";
};
var answer = getChoiceCode(questions[q]);//将字母选项转换为Unicode数字并减去A代表的65,等于选项顺序,0是第一个选项
var element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
if (!element) { //选项除错机制
console.log("找不到选项,选项更改为A index: " + index + " answer: " + answer);
questions[q] = "A";
answer = getChoiceCode("A");
element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
//localStorage.removeItem(keyTest)
};
try {
var answerText = element.innerText.substring(3);//"A、"占用3个字符
//console.log("测试语法:" + (answerText == element.innerText.trim().substring(2)));
//element.nextSibling.innerText.trim().substring(2); //获得当前答案文本
qTestAnswer[q] = answerText;
//console.log("qTestAnswer:"+error);
} catch (error) { console.log("答案文本获取失败A:" + error); };
if (element) {
element.click();
}
};
index = index + 1;
};
};
//存储相关记录
localStorage.setItem(keyTest, JSON.stringify(questions));
localStorage.setItem(keyTestAnswer, JSON.stringify(qTestAnswer));
setTimeout(function () {
var submitButton = document.querySelector("#btn_submit");
if (submitButton) {
submitButton.click();
}
}, (submitTime + Math.ceil(Math.random() * randomX))); //交卷延时
///专用函数区
function findAnwser(qakey, index, rightAnwserText) {
var answerslist = document.querySelectorAll(qakey)[index];
if (!answerslist) return null;
var arr = answerslist.getElementsByTagName("label");
console.log(`查找答案: ${rightAnwserText}`);
// 精确匹配
for (var i = 0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText===rightAnwserText) {
console.log(`✅ 精确匹配: ${optionText}`);
return arr[i];
}
}
// 模糊匹配
for (var i=0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText.includes(rightAnwserText) || rightAnwserText.includes(optionText)) {
console.log(`🔍 模糊匹配: ${optionText}`);
return arr[i];
}
}
console.log(`❌ 未找到匹配答案,使用第一个选项`);
return arr[0];
}
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] ? $(".tips_text")[0].innerText : null;
var dds=$(".state_cour_lis");
localStorage.removeItem(keyResult);
if (res=="考试通过" || res=="考试通过!" || res=="完成项目学习可以申请学分了" ) {
console.log("考试通过");
saveRightAnwser();
SaveAllAnwser();
cleanKeyStorage();
checkExamContinuation();
setTimeout(function () {
// ...(原有代码)
}, 1000);
} else {
console.log("考试未通过")
var tipsTextElement=document.querySelector("p[class='tips_text' ]");
if (tipsTextElement) {
tipsTextElement.innerText="本次未通过,正在尝试更换答案\r\n(此为正常现象,脚本几秒后刷新,请勿操作)"
}
var qWrong={};
for (var i=0; i < dds.length; ++i) {
if (dds[i].querySelector("img") && !dds[i].querySelector("img").src.includes("bar_img")) {//这里表示否定
var rawQuestion=dds[i].querySelector("p").title;
var cleanedQuestion=cleanQuestionText(rawQuestion);
qWrong[cleanedQuestion]=i
};
};
if (qWrong !={}) {
localStorage.setItem(keyResult, JSON.stringify(qWrong));
saveRightAnwser();
setTimeout(function () {
$("input[type=button][value='重新考试' ]").click();
}, (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 qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) ||{};
var qTitle=JSON.parse(localStorage.getItem(keyThisTitle)) || "没有记录到章节名称" ;
if (qTitle=="没有记录到章节名称" ) {
console.log("没找到章节名称");
return {};
};
var qOldAnswer=qAllAnswer[qTitle] || {};
return qOldAnswer
};
// 修改题目处理逻辑,去除干扰的问号
// 统一的题目清洗函数
function cleanQuestionText(questionText) {
if (!questionText) return '' ;
// 去除各种特殊字符和空白
let cleaned=questionText
.replace(/[??]/g, '' )
.replace(/||[\u200B-\u200D\uFEFF]/g, '' ) // 去除零宽空格
.replace(/\s+/g, ' ' ) // 将多个空格合并为一个
.trim();
// 去除题目编号
cleaned=cleaned.replace(/^\d+、/, '' ).trim();
// 智能处理括号:
// 1. 只删除完全为空或只有空格的括号
// 2. 保留包含实际内容的括号
cleaned=cleaned.replace(/[((]\s*[))]/g, '' ) // 处理空括号
.replace(/[((]\s*([^))\s]+)\s*[))]/g, '$1' ) // 保留括号内的内容
.trim();
return cleaned;
}
// 修改题目获取方式,确保一致性
function getQuestionText(questionElement) {
try {
let rawText=questionElement.querySelector(".q_name").innerText;
// 去除编号部分(如"1、")
let textWithoutNumber=rawText.replace(/^\d+、/, '' );
return cleanQuestionText(textWithoutNumber);
} catch (error) {
console.log("获取题目文本错误:", error);
return "" ;
}
}
// 修改答案记录部分
function saveRightAnwser() {
var qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
var qTestAnswer=JSON.parse(localStorage.getItem(keyTestAnswer)) || {};
var qWrongs=JSON.parse(localStorage.getItem(keyResult)) || {};
console.log("开始保存正确答案...");
console.log("错题记录:", qWrongs);
console.log("测试答案:", qTestAnswer);
// 构建清理后的题目映射
var cleanedWrongs={};
for (var wrongQ in qWrongs) {
var cleanedWrongQ=cleanQuestionText(wrongQ);
cleanedWrongs[cleanedWrongQ]=true;
console.log(`错题清洗: "${wrongQ}" -> "${cleanedWrongQ}"`);
}
for (var q in qTestAnswer) {
var cleanedQ = cleanQuestionText(q);
console.log(`处理题目: "${q}" -> "${cleanedQ}", 答案: ${qTestAnswer[q]}`);
if (!cleanedWrongs[cleanedQ]) {
console.log(`✅ 正确答案: "${cleanedQ}" -> ${qTestAnswer[q]}`);
qRightAnswer[cleanedQ] = qTestAnswer[q];
} else {
console.log(`❌ 错误题目: "${cleanedQ}" -> ${qTestAnswer[q]}`);
}
}
localStorage.removeItem(keyTestAnswer);
if (Object.keys(qRightAnswer).length > 0) {
localStorage.setItem(keyRightAnswer, JSON.stringify(qRightAnswer));
console.log("✅ 正确答案已保存:", qRightAnswer);
} else {
console.log("❌ 没有正确答案需要保存");
}
}
//答案记录函数区结束//
//------------------答案复制相关按钮--------------------------------------------
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")
//Aout=encodeURIComponent(Aout);
//window.prompt("请复制",Aout);
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;
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(textout);
}
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.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);
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
//答案复制相关按钮 end
function skipVideo() {//这是跳过视频的代码
var oVideo = document.getElementsByTagName('video')[0];
if (oVideo) {
oVideo.currentTime = oVideo.duration - 1
};
};
// 在 courseList 函数中添加导入答案按钮
function addImportAnswerBtn() {
let alink = document.createElement("a");
alink.innerHTML = '导入答案';
alink.style = btstyleB;
alink.onclick = function (event) {
var input = prompt("请粘贴要导入的答案数据(JSON格式)");
if (input) {
try {
// 解析输入的JSON数据
var importedAnswers = JSON.parse(input);
// 获取现有的答案记录
var existingAnswers = JSON.parse(localStorage.getItem(keyAllAnswer)) || {};
// 合并答案
var mergedAnswers = mergeAnswerData(existingAnswers, importedAnswers);
// 保存合并后的答案
localStorage.setItem(keyAllAnswer, JSON.stringify(mergedAnswers));
alert("✅ 答案导入成功!\n已合并 " + Object.keys(importedAnswers).length + " 个章节的答案");
} catch (error) {
alert("❌ 导入失败:数据格式不正确\n" + error);
}
}
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
// 合并答案数据的函数
function mergeAnswerData(existing, imported) {
// 深拷贝现有答案
var merged = JSON.parse(JSON.stringify(existing));
// 遍历导入的答案
for (var chapter in imported) {
if (imported.hasOwnProperty(chapter)) {
// 如果章节不存在,直接添加
if (!merged[chapter]) {
merged[chapter] = imported[chapter];
} else {
// 合并章节内的题目答案
for (var question in imported[chapter]) {
if (imported[chapter].hasOwnProperty(question)) {
merged[chapter][question] = imported[chapter][question];
}
}
}
}
}
return merged;
};
//------------------看视频页面主要函数-------------------------------------------
function clickexam() { //延时点击考试按钮。
console.log("已点击考试按钮");
setTimeout(function () {
var examButton = document.querySelector("#jrks");
if (examButton) {
examButton.click();
}
}, (Math.ceil(Math.random() * randomX)));
//}, (examTime + Math.ceil(Math.random() * randomX)));
};
//按钮插入函数相关
function addSkipbtn() {//插入按钮快进视频按钮
let alink = document.createElement("a");
alink.innerHTML = '快进视频';
alink.style = btstyleA;
alink.onclick = function (event) {
skipVideo();
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
};
function addratebtn(ra) {//倍率调整按钮
let alink = document.createElement("a");
alink.innerHTML = '' + ra + 'x';
alink.style = btstyleB;
alink.className = "speed";
alink.id = ra + "x";
alink.onclick = function (event) {
ratechg(ra);
try {
var arr = document.querySelectorAll("a[class='speed']");
arr.forEach(function (item, index, arr) {
arr[index].style = btstyleB;
});
} catch (error) {
};
alink.style = btstyleC;
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
}
function ratechg(ra) {//倍率调整
var videoObj = document.querySelector("video")
if (videoObj) {
try {
clearInterval(nspeed);
nspeed = setInterval(() => {
videoObj.playbackRate = ra;
}, 1 * 1000);
localStorage.setItem(keyPlayRate, ra);
//document.querySelector("a[id=" + "'" + ra + "x']").style = btstyleC;
//document.getElementById("playrate").innerHTML = "当前播放速率" + ra + "x";
//console.log("倍率调整为" + ra);
} catch (error) { console.log("倍率调整错误" + error); };
}
};
function addrateinfo() {//插入说明
let adiv1 = document.createElement("div");
adiv1.innerHTML = '当前播放速率';
adiv1.id = 'playrate';
adiv1.style = "font-size: 15px;text-align: center;margin-top: 10px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv1);
}
};
function addinfo() {//插入说明
//模式切换按钮
var moderesult = localStorage.getItem("华医mode");
if (moderesult == 2) {
moderesult = "当前模式:视频+考试";
} else {//包括了结果为1或者无存储的情况
moderesult = "当前模式:单刷视频";
};
var checkbox = document.createElement('div');
checkbox.innerHTML = '' + moderesult + '
[点击此处切换] ';
// 添加到页面的 body 元素中
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(checkbox);
}
//插入说明部分
let mode1 = document.querySelector("a[id='mode']");
if (mode1) {
mode1.onclick = function () {
if (mode1.innerText == "当前模式:单刷视频\n[点击此处切换]") {
mode1.innerText = "当前模式:视频+考试\n[点击此处切换]";
localStorage.setItem("华医mode", "2");
} else {
mode1.innerText = "当前模式:单刷视频\n[点击此处切换]";
localStorage.setItem("华医mode", "1");
};
};
}
let adiv2 = document.createElement("div");
adiv2.innerHTML = '       本人医学研一学生,经常要帮师兄师姐刷华医视频,属实太累。偶然在抖音发现Dr.S的脚本,结果刷完1个视频立刻考试,导致频繁人脸识别跟手动区别不大。原作者已不更新,于是我自学修改了播放逻辑,实现无人值守连续播放。现将原先自用的脚本分享给大家❤❤
     刷完视频再切换考试模式,即可连续考试。
';
adiv2.id = 'jsinfo';
adiv2.style = "position:relative;left:10px;top:5px;width:240px;font-size:13px;text-align: justify;border: 1px dashed #ff9595;padding:5px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv2);
}
if (typeof $ !== 'undefined') {
$('div:contains("观看视频完成后,才能进入考试")').eq(-1).text('建议360安全浏览器和脚本猫');
}
// 创建连续考试按钮的容器
let examBtnContainer = document.createElement('div');
examBtnContainer.id = 'continuousExamBtnContainer';
examBtnContainer.style = "text-align: center; margin: 10px 0;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(examBtnContainer);
}
};
function changelayout() {
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv) {
jjDiv.remove();
}
var photoImg = document.querySelector("img[id='photo']");
if (photoImg) {
photoImg.outerHTML = `
`;
photoImg.style.width = "120px";
photoImg.style.height = "120px";
}
var titleDivs = document.querySelectorAll("div[class='title']");
if (titleDivs[0] && titleDivs[0].children[0]) {
titleDivs[0].children[0].style = "color: #ff0000;font-weight: bold";
titleDivs[0].children[0].innerText = "支持作者";
}
var imgTextDivs = document.querySelector("div[class='imgtext']");
if (imgTextDivs && imgTextDivs.children[1]) {
imgTextDivs.children[1].style.width = "125px";
imgTextDivs.children[1].style = "color: #ff0000;padding-top:10px";
imgTextDivs.children[1].innerText = "作 者\n创作优化不易\n投点小费吧\n❤谢啦❤\n❤"
}
var topDiv = document.querySelector("div[class='top']");
if (topDiv) {
topDiv.outerHTML = '如服务器调整,脚本可能失效。反馈意见、免费增加课程请在Greasyfork私信或脚本反馈区联络。也欢迎投喂↓
';
}
};
function cleanKeyStorage() {//缓存清理
localStorage.removeItem(keyTest);
localStorage.removeItem(keyResult);
localStorage.removeItem(keyTestAnswer);
localStorage.removeItem(keyRightAnswer);
};
function examherftest() {//考试按钮激活状态检测
var examButton = document.getElementById("jrks");
var hreftest = examButton ? examButton.attributes["disabled"] : null;
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if ((state == "已完成" || state == "待考试" || !hreftest) && examButton) {//value不为#说明考试按钮已经激活
console.log("已经播放完了");
// 优先处理"视频+考试"模式下的"待考试"状态
var modeElement = document.querySelector("a[id='mode']");
if (modeElement && modeElement.innerText.indexOf("视频+考试") != -1 && state == "待考试") {
console.log("mode=2,准备进入考试");
// 重试机制:尝试5次进入考试
var retryCount = 0;
var maxRetries = 5;
function tryEnterExam() {
retryCount++;
console.log(`尝试进入考试 (第${retryCount}次)`);
try {
// 方法1:尝试点击考试按钮
if (document.getElementById("jrks") && !document.getElementById("jrks").disabled) {
document.getElementById("jrks").click();
console.log("成功点击考试按钮");
return true; // 成功进入考试
}
// 方法2:尝试备用方式
if (typeof cwrid !== 'undefined') {
window.open("/pages/exam_tip.aspx?cwrid=" + cwrid, "_self");
console.log("尝试备用方式进入考试");
return true;
}
// 方法3:尝试通过URL跳转
var currentUrl = window.location.href;
if (currentUrl.includes("course_ware")) {
var examUrl = currentUrl.replace("course_ware/course_ware_", "pages/exam.aspx?cwid=")
.split("?")[0] + "?cwid=" + getUrlParam("cwid");
window.location.href = examUrl;
console.log("尝试通过URL跳转进入考试");
return true;
}
} catch (error) {
console.log(`第${retryCount}次尝试失败:`, error);
}
return false; // 进入考试失败
}
// 立即尝试第一次
if (tryEnterExam()) {
return; // 成功进入考试,直接返回
}
// 设置重试间隔
var retryInterval = setInterval(function () {
if (retryCount >= maxRetries) {
clearInterval(retryInterval);
console.log(`尝试${maxRetries}次进入考试均失败,继续听课`);
// 继续执行后续的跳转到下一个视频的逻辑
proceedToNextVideo();
} else if (tryEnterExam()) {
clearInterval(retryInterval); // 成功进入考试,停止重试
}
}, 2000); // 每2秒重试一次
} else {
// 单刷视频模式或非待考试状态,直接继续听课
proceedToNextVideo();
};
} else {//#代表考试按钮还没激活
//继续播放,无需任何操作
}
}
// 跳转到下一个视频的函数
function proceedToNextVideo() {
console.log('🚀 准备跳转到下一个视频...');
const nextCwid = getNextCourseCwid();
if (nextCwid) {
console.log(`✅ 确定跳转到课程: ${nextCwid.substring(0, 8)}...`);
console.log(`🌐 跳转URL: course_ware.aspx?cwid=${nextCwid}`);
// 延迟跳转,让用户有时间查看日志
setTimeout(() => {
console.log('⏩ 正在跳转...');
window.location.href = `course_ware.aspx?cwid=${nextCwid}`;
}, 2000);
} else {
console.log('❌ 没有找到可用的课程,尝试刷新页面');
setTimeout(() => {
console.log('🔄 正在刷新页面...');
window.location.reload();
}, 2000);
}
}
// 辅助函数:获取URL参数
function getUrlParam(name) {
var urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
};
//课堂问答跳过,临时版
function sleep(timeout) {
return new Promise((resolve) => { setTimeout(resolve, timeout); });
console.log("课堂问答循环调用");
};
function asynckillsendQuestion() {
(async function () {
while (!window.player || !window.player.sendQuestion) {
await sleep(20);
};
//console.log("课堂问答跳过插入");
player.sendQuestion = function () {
//console.log("播放器尝试弹出课堂问答,已屏蔽。");
};
})();
};
function killsendQuestion2() {
if (typeof (isInteraction) == "undefined") {
//console.log('变量未定义');
} else {
console.log('isInteraction设置off');
isInteraction = "off";
};
};
function killsendQuestion3() { //点击跳过按钮版的跳过课堂答题
var clockms = setInterval(async function () {
try {
if (typeof $ !== 'undefined' && $('.pv-ask-head').length && $('.pv-ask-head').length > 0) {
console.log("检测到问题对话框,尝试跳过");
$(".pv-ask-skip").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.signBtn').length && $('.signBtn').length > 0) {
console.log("检测到签到对话框,尝试跳过");
$(".signBtn").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' &&
$("button[onclick='closeProcessbarTip()']").length &&
$("button[onclick='closeProcessbarTip()']").length > 0 &&
$("div[id='div_processbar_tip']").css("display") == "block") {
console.log("检测到温馨提示对话框(不能拖拽),尝试跳过");//
//*[@id="div_processbar_tip"]/div/div[2]/input
//document.querySelector("#div_processbar_tip > div > div.foot_sub > input")
//#div_processbar_tip > div > div.foot_sub > input
//
$("button[onclick='closeBangZhu()']").click();
$("button[onclick='closeProcessbarTip()']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $("button[class='btn_sign']").length && $("button[class='btn_sign']").length > 0) {
console.log("检测到温馨提示对话框(疲劳提醒),尝试跳过");
$("button[class='btn_sign']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.rig_btn').length && $('.rig_btn').length > 0) {
if ($('#div_processbar_tip').is(':visible')) {
console.log("检测到按钮(知道了),执行隐藏操作");
$('#div_processbar_tip').hide();
}
//$(".rig_btn").click();
};
} catch (err) {
console.log(err);
};
try {
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if (typeof $ !== 'undefined' &&
$('video').prop('paused') == true &&
state != "已完成" &&
state != "待考试") {
console.log("视频意外暂停,恢复播放");
$('video').get(0).play();
//$('video').prop('volumed') = 0;
$('video').prop('muted') = true;
} else if (state == "已完成") {
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.pause();
}
//clearInterval(clockms);
};
} catch (err) {
//console.log(err);
};
}, 10000);
};
function autoClickKnowButton() {
// 检测按钮是否加载完成
const observer = new MutationObserver(() => {
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
observer.disconnect(); // 停止观察
button.click(); // 点击按钮
}
});
// 开始观察文档的变化
observer.observe(document.body, {
childList: true,
subtree: true
});
// 如果按钮已经加载完成,直接点击
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
button.click();
}
}
// 在全局函数区添加以下函数
function saveCourseList() {
console.log('📋 开始保存/更新课程列表...');
// 尝试获取课程列表容器
const courseContainer = document.querySelector('.page-container');
if (!courseContainer) {
console.log('❌ 未找到课程列表容器');
return;
}
// 尝试获取课程项
const courseItems = document.querySelectorAll('.lis-inside-content');
if (courseItems.length === 0) {
console.log('❌ 未找到课程项');
return;
}
console.log(`📚 找到 ${courseItems.length} 个课程项,开始解析...`);
const currentCourseList = [];
let hasChanges = false;
courseItems.forEach((item, index) => {
const titleElement = item.querySelector('h2');
const statusButton = item.querySelector('button');
if (titleElement && statusButton) {
const title = titleElement.textContent.trim();
const status = statusButton.textContent.trim();
const statusColor = statusButton.style.background;
// 从onclick属性中提取cwid
const onclickAttr = titleElement.getAttribute('onclick');
let cwid = '';
if (onclickAttr) {
const match = onclickAttr.match(/cwid=([^']+)/);
if (match && match[1]) {
cwid = match[1];
}
}
if (cwid) {
currentCourseList.push({
title,
status,
statusColor,
cwid,
index
});
//console.log(` 课程 ${index + 1}: "${title}" - 状态: ${status}`);
}
}
});
if (currentCourseList.length === 0) {
console.log('❌ 未解析到任何课程信息');
return;
}
// 获取之前保存的课程列表
const previousCourseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
if (previousCourseList.length === 0) {
// 第一次保存
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`✅ 首次保存课程列表完成,共 ${currentCourseList.length} 个课程`);
return;
}
// 检查是否有变化
console.log('🔍 检查课程状态变化...');
for (let i = 0; i < currentCourseList.length; i++) {
const currentCourse=currentCourseList[i];
const previousCourse=previousCourseList[i];
if (!previousCourse) {
console.log(` 新增课程: "${currentCourse.title}" `);
hasChanges=true;
continue;
}
// 检查状态变化
if (currentCourse.status !==previousCourse.status) {
console.log(` 状态变化: "${currentCourse.title}" - ${previousCourse.status} → ${currentCourse.status}`);
hasChanges=true;
}
// 检查标题变化(可能课程有更新)
if (currentCourse.title !==previousCourse.title) {
console.log(` 标题变化: "${previousCourse.title}" → "${currentCourse.title}" `);
hasChanges=true;
}
// 检查cwid变化(理论上不应该变)
if (currentCourse.cwid !==previousCourse.cwid) {
console.log(` cwid变化: "${currentCourse.title}" `);
hasChanges=true;
}
}
// 检查课程数量变化
if (currentCourseList.length !==previousCourseList.length) {
console.log(` 课程数量变化: ${previousCourseList.length} → ${currentCourseList.length}`);
hasChanges=true;
}
if (hasChanges) {
// 更新课程列表
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`🔄 课程列表已更新,共 ${currentCourseList.length} 个课程`);
// 输出详细的课程状态
console.log('📊 当前所有课程状态:');
currentCourseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
} else {
console.log('✅ 课程列表无变化,无需更新');
// 即使无变化,也确保本地存储的是最新数据(防止数据损坏)
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
}
}
function getCurrentCourseCwid() {
// 从当前URL获取cwid
const urlParams = new URLSearchParams(window.location.search);
const cwid = urlParams.get('cwid');
console.log(`🔍 当前课程 cwid: ${cwid ? cwid.substring(0, 8) + '...' : '未找到'}`);
return cwid;
}
function getNextCourseCwid() {
console.log('🔄 开始查找下一个课程...');
// 尝试从localStorage获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
const currentCwid = getCurrentCourseCwid();
if (courseList.length === 0) {
console.log('❌ 未找到存储的课程列表');
return null;
}
console.log(`📊 课程列表中有 ${courseList.length} 个课程`);
// 找到当前课程的索引
const currentIndex = courseList.findIndex(course => course.cwid === currentCwid);
if (currentIndex === -1) {
console.log('❌ 未找到当前课程在列表中的位置');
console.log('当前课程可能不在列表中,将尝试第一个未完成的课程');
// 尝试查找第一个未完成的课程
for (let i = 0; i < courseList.length; i++) {
const course=courseList[i];
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到第一个未完成课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
return null;
}
console.log(`📍 当前课程位置: 第 ${currentIndex + 1} 个 - "${courseList[currentIndex].title}" `);
// 查找下一个未完成的课程(从当前位置向后找)
console.log('🔍 向后查找未完成的课程...');
for (let i=currentIndex + 1; i < courseList.length; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到下一个课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
// 如果后面没有未完成的课程,尝试从开头查找
console.log('🔍 向后未找到,从开头查找未完成的课程...');
for (let i=0; i < currentIndex; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到前面的课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
console.log('所有课程状态:');
courseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
return null;
}
//--------------------------插入悬浮框------------------------------------//
function advis() {
// 🔴 第一步:只在顶层窗口运行,iframe 中直接退出
if (window.self !== window.top) {
console.log('小助手:当前处于 iframe 中,不创建面板');
return;
}
// 🔴 第二步:检查是否已有面板,防止重复创建(即使脚本多次调用)
const existingPanel = document.getElementById('Div1');
if (existingPanel) {
console.log('已检测到小助手面板,防止重复创建');
return; // 或者 existingPanel.remove(); 再创建(推荐 return 即可)
}
// 🟡 第三步:创建新面板
let div1 = document.createElement("div");
div1.innerHTML = `
`;
document.body.append(div1);
// 绑定事件
let share1 = document.getElementById('Share1');
let share2 = document.getElementById('Share2');
let clo = document.getElementById('clo');
if (share1) {
share1.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/500010", "_blank");
};
}
if (share2) {
share2.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/555651", "_blank");
};
}
if (clo) {
clo.onclick = function () {
var panel = document.getElementById('Div1');
if (panel) {
panel.style.display = 'none';
}
};
}
// === 初始化:左对齐课程列表 ===
const panel = document.getElementById('Div1');
if (!panel) return;
const container = document.querySelector('.page-container') ||
document.querySelector('.lis-content') ||
document.querySelector('.container-inside-header');
let initialLeft = 140; // 默认值
if (container) {
const rect = container.getBoundingClientRect();
initialLeft = rect.left + window.pageXOffset;
}
panel.style.left = initialLeft + 'px';
// === 拖拽功能 ===
let isDragging = false;
let offsetX, offsetY;
panel.addEventListener('mousedown', function (e) {
if (e.target === clo ||
e.target.tagName === 'A' ||
e.target.tagName === 'IMG' ||
e.target.tagName === 'HR') return;
isDragging = true;
offsetX = e.clientX - panel.getBoundingClientRect().left;
offsetY = e.clientY - panel.getBoundingClientRect().top;
e.preventDefault();
});
document.addEventListener('mousemove', function (e) {
if (!isDragging) return;
panel.style.left = (e.clientX - offsetX) + 'px';
panel.style.top = (e.clientY - offsetY) + 'px';
});
document.addEventListener('mouseup', () => {
isDragging = false;
});
// 创建状态面板(默认隐藏)
//createStatusPanel();
//document.getElementById('examStatusPanel').style.display = 'none';
}
//--------------------------连续考试的函数------------------------------------//
// 修改 addContinuousExamButton 函数
function addContinuousExamButton() {
// 检查是否已存在连续考试按钮
if (document.getElementById('continuousExamBtn')) {
return;
}
// 创建连续考试按钮
let btn = document.createElement("a");
btn.innerHTML = '连续考试';
btn.style = btstyleA
btn.id = 'continuousExamBtn';
btn.onclick = function () {
console.log('🚀 开始连续考试流程...');
startContinuousExam();
};
// 找到建议提示框
const tipDiv = document.querySelector('div.r div[style*="border: 1px dashed #ff9595"]');
if (tipDiv) {
// 创建按钮容器
let btnContainer = document.createElement('div');
btnContainer.style = "text-align: center; margin: 10px 0;";
btnContainer.appendChild(btn);
// 将按钮容器插入到建议提示框后面
tipDiv.parentNode.insertBefore(btnContainer, tipDiv.nextSibling);
} else {
// 如果找不到建议提示框,使用预留的容器
const btnContainer = document.getElementById('continuousExamBtnContainer');
if (btnContainer) {
btnContainer.appendChild(btn);
} else {
// 如果容器也不存在,添加到页面底部
document.body.appendChild(btn);
}
}
}
// 新增:创建状态面板的函数
function createStatusPanel() {
// 检查是否存在 exam_phase
const examPhase = localStorage.getItem('exam_phase');
if (!examPhase) {
// 如果不存在 exam_phase,移除可能存在的面板
const existingPanel = document.getElementById('examStatusPanel');
if (existingPanel) {
existingPanel.remove();
}
return;
}
// 检查是否已存在状态面板
if (document.getElementById('examStatusPanel')) {
// 如果面板已存在,只需更新状态信息
updatePanelContent();
return;
}
// 创建状态面板
const panel = document.createElement('div');
panel.id = 'examStatusPanel';
panel.style = `
position: fixed;
top: 20px;
right: 20px;
width: 300px;
background-color: rgba(255, 255, 255, 0.95);
border: 2px solid #4cb0f9;
border-radius: 8px;
padding: 15px;
z-index: 10000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
font-family: 'Microsoft YaHei', sans-serif;
`;
panel.innerHTML = `
连续考试状态
加载中...
`;
// 确保面板正确插入到页面中
document.body.appendChild(panel);
// 添加取消按钮事件
var cancelBtn = document.getElementById('cancelExamBtn');
if (cancelBtn) {
cancelBtn.onclick = function () {
if (confirm('确定要取消连续考试吗?')) {
cancelContinuousExam();
}
};
}
// 更新面板内容
updatePanelContent();
// 辅助函数:更新面板内容
function updatePanelContent() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examPhase = localStorage.getItem('exam_phase');
let statusMessage = '';
if (examPhase === 'face_verification') {
statusMessage = `👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else if (examPhase === 'examination') {
statusMessage = `📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else {
statusMessage = '连续考试进行中...';
}
const contentElement = document.getElementById('examStatusContent');
if (contentElement) {
contentElement.innerHTML = statusMessage;
}
}
}
// 修改:更新状态提示的函数
function updateExamStatus(message, isError = false) {
createStatusPanel(); // 确保面板存在
const panel = document.getElementById('examStatusPanel');
// 添加存在性检查
if (!panel) {
console.log('状态面板不存在,跳过更新');
return;
}
panel.style.display = 'block';
const statusContent = document.getElementById('examStatusContent');
if (statusContent) {
statusContent.innerHTML = message;
statusContent.style.color = isError ? '#f15854' : '#333';
}
}
// 取消连续考试
function cancelContinuousExam() {
console.log('❌ 结束连续考试');
// 清除相关状态
localStorage.removeItem('exam_courses');
localStorage.removeItem('current_exam_index');
localStorage.removeItem('exam_phase');
// 只有在面板存在时才更新状态
const panel = document.getElementById('examStatusPanel');
if (panel) {
updateExamStatus('连续考试已取消');
// 3秒后隐藏状态面板
setTimeout(() => {
//panel.style.display = 'none';
}, 3000);
} else {
console.log('状态面板不存在,直接清除状态');
}
}
// 连续考试主函数
function startContinuousExam() {
// 强制设置为单刷视频模式,避免冲突
localStorage.setItem("华医mode", "1");
console.log('🚀 开始连续考试流程,模式强制设置为单刷视频');
localStorage.setItem('exam_phase', 'setup'); // 设置阶段为初始化
// 创建状态面板
createStatusPanel();
// 获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
// 筛选待考试的课程
const examCourses = courseList.filter(course => course.status === '待考试');
if (examCourses.length === 0) {
console.log('❌ 没有找到待考试的课程');
updateExamStatus('❌ 没有找到待考试的课程', true);
localStorage.removeItem('exam_phase');
return;
}
// 保存待考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
localStorage.setItem('exam_phase', 'face_verification'); // 设置阶段为刷脸
console.log(`📋 找到 ${examCourses.length} 个待考试课程`);
updateExamStatus(`找到 ${examCourses.length} 个待考试课程
准备开始刷脸流程...`);
// 开始刷脸流程
startFaceVerificationProcess();
}
// 刷脸流程
function startFaceVerificationProcess() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有课程刷脸完成,开始连续考试');
updateExamStatus('✅ 所有课程刷脸完成
开始连续考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startFaceVerificationProcess, 1000);
return;
}
console.log(`👤 开始第 ${currentIndex + 1} 个课程刷脸: ${currentCourse.title}`);
updateExamStatus(`👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开课程链接进行刷脸
window.location.href = `course_ware.aspx?cwid=${currentCourse.cwid}`;
}
// 监听页面加载,判断是否在刷脸后返回
function checkFaceVerificationReturn() {
const examPhase = localStorage.getItem('exam_phase');
const isInFaceVerification = examPhase === 'face_verification';
if (isInFaceVerification) {
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
// 只有当索引有效时才继续
if (currentIndex < examCourses.length) {
console.log('🔍 检测到刷脸后返回,继续下一个课程');
localStorage.setItem('current_exam_index', currentIndex + 1);
updateExamStatus(`✅ 刷脸完成 ${currentIndex + 1}/${examCourses.length}
准备下一个课程...`);
// 添加延迟防止过快跳转
setTimeout(startFaceVerificationProcess, 3000);
} else {
console.log('✅ 刷脸流程已完成');
updateExamStatus('✅ 刷脸流程已完成
准备开始考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
}
}
}
// 开始所有考试
function startAllExams() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
if (examCourses.length === 0) {
console.log('❌ 没有待考试的课程');
updateExamStatus('❌ 没有待考试的课程', true);
return;
}
console.log('🎯 开始连续考试流程');
updateExamStatus(`🎯 开始连续考试流程
共 ${examCourses.length} 个考试待完成`);
// 保存考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
// 开始第一个考试
startNextExam();
}
// 开始下一个考试
function startNextExam() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有考试完成!');
updateExamStatus('✅ 所有考试完成!
连续考试流程结束');
cancelContinuousExam();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startNextExam, 1000);
return;
}
console.log(`📝 开始第 ${currentIndex + 1} 个考试: ${currentCourse.title}`);
updateExamStatus(`📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开考试页面
window.location.href = `/pages/exam.aspx?cwid=${currentCourse.cwid}`;
}
// 在考试结果页面检查是否需要继续下一个考试
function checkExamContinuation() {
const examPhase = localStorage.getItem('exam_phase');
const isInExamMode = examPhase === 'examination';
if (isInExamMode) {
console.log('🔍 检测到考试完成,准备下一个考试');
// 增加索引
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
localStorage.setItem('current_exam_index', currentIndex + 1);
// 更新状态提示
updateExamStatus(`✅ 考试完成 ${currentIndex + 1}/${examCourses.length}
准备下一个考试...`);
// 短暂延迟后继续下一个考试
setTimeout(() => {
startNextExam();
}, 3000);
}
}
//---------------------------------全局函数区end------------------------------//
})();gwQOWPuloSKykYzlA6CZxbTEFRiWVVbcQ9nxyvmpirmdmlD/UAA/8MQzsAMGXECpceKpvAcHnEPEINwkLqIrLlf5pEMBIMA7PEM0YMAHJZwU/gM9gM97RAMuaNhMuM1JXVc+jJNT+IUnFgMJsMM6BCPVJeIrTiOBHdkFtIM+3Nc5xN4j7c35jQUR5MP0pcSfPU5JoYPctWLHpIOqOQCwfZ0ZHlECUiM9al3FXIc4NZx2zeMwiYNwrU8znIdTJIA63JA/HI4gwsReXGBNlMPmHV49RuSBqVimzAneIJkuZh5tOUszGKQ/oIPKNIXLhEmnxALdIGIy+shaHNfrSaRLnhmbvdsXYhBGbMqQfSR+NIXe1AhwzEX8vSRQBiXfGUk5kM84/xJMP1xAM6QTWXDAJjYFPoTHDT0DBjSTUF4lVrogdBhAMDQDBjhAkRzl2kCHsSDLHJ2DOoYEAZCUzpDAMEgOP2alXO4d6tkFMtSDO5SUKH4fBikJLBDWhIkD7PUDLBRkJPEDmaTlXC4mNyIHtIDJO1BA+LlYSCBDNPBkWSAAFL6I5XgjcLADLBgYY46mK6Ie59UDlfQEdK0RRhjAI8KMOpxAQsLEOdCVPEkLBYgmae4mGtZFc90Qk8ldX2KSJt2QO+hD4zVFOizlezyDO+SmYvKmdIranp2TdZUFBkwm9RwHfXghbSDHPzanH4VdXhRmmywYO1SYdk4ne3LdUqhFMP8ECZu0j26GFJuNQAJQQD4YQHShpJtdgHBVSZsU14s4Zh36xDpgiX+2J4PmHdXhQzDUAwLwgwjoA8JwZpoMg/kpWsWl5VBcgFTCDAnUUzKGRFRIKD+gw0nGZYO2qBo+HgHggwGcwDbuGVH8BQFwQDoNXTiJ3nV0JP34Q+SkJEiUQzsgwwno3g66KJOKGs2Ux5GMUxfOBNtYDgLAzYAqJlNQgEeWAJYUaIDE1Ho2KZmW4B+xzXk85Ez0VTsY5nuQx5imRFvY2OCtg8Ul44/dB8JEZ5n26VlVm19QjI3KxJ7dQ3GKhwPEaf50ILI8g2Sm3VJIR+p9IYv6qaX6HOu9FZ///kU5oMONsc/+cWJQKCXH4ZRsKipgaIkkFhGfXqqrThtvnAAhEYE6lIA+5CRnsgchsUMsDANyAuGrBquLVttHgAAuIAMu0ENWGN6ptcUsGIA+JIA4RJOwVmt7GmF3imV6wF+Ytqq1fusi6kXlRGkCvqc+Viq4pqv/AQuM8NxsrGQcqqu8YiX6tB6XoKr5DBg0kNyazau/XuWeAWo8hlSMxeu/HizCJqzCLizDNqzDPizERqzETizFVqzFXizGZqzGbizHdqzHfizIhqzIjizJlqzJnizKpqzKrizLtqzLvizMxqzMzizN1qzN3izO5qzO7izP9qzP/izQBq3QDi3RIhat0R4t0iat0i4t0zat0z4t1Eat1E4t1Vat1V4t1qJsQAAAOw==`;
var clock = null;
var testtest = true; //另一个可能会封号的功能,仅调试使用。
advis();
createStatusPanel(); //状态监视面板根据需要进行显示
// 修复错误:检查元素是否存在后再设置内容
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "当前网址已适配ヾ(๑╹◡╹)ノ"
失效请赞赏联系  ε(┬┬﹏┬┬)3";
}
if (urlTip == "course_ware_polyv.aspx") { //保利威播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(1);
} else if (urlTip == "course_ware_cc.aspx") { //CC播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(2);
} else if (urlTip == "face.aspx") { //刷脸
console.log("当前任务: 刷脸界面");
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "course.aspx" || urlTip == "cme.aspx") { //课程列表页面
console.log("当前任务: 课程列表");
huayi.courseList();
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "exam.aspx") { //考试页面
console.log("当前任务: 华医考试");
huayi.doTest();
} else if (urlTip == "exam_result.aspx") { //考试结果页面
console.log("当前任务: 华医考试结果审核");
huayi.doResult();
} else {
console.log("其它情况");
try {
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "此页面非视频、考试或未适配";
}
document.querySelector("img[id='Pic']").style.display = "block";
} catch (error) { };
};
function getHuayi() {
return {
courseList: function () {
addAnwserCopybtn();
addImportAnswerBtn();
DelAllAnwser();
},
seeVideo: function (e) {
var tr = localStorage.getItem(keyPlayRate);
//console.log("存储读取" + tr);//读取倍速
//var playRateNow = tr ? tr : vSpeed;
var playRateNow = 1;
cleanKeyStorage();
asynckillsendQuestion();//屏蔽课堂问答的函数;
killsendQuestion2();//屏蔽课堂问答的函数2;
killsendQuestion3(); //循环检测问答对话框是否弹出。
//addrateinfo();//插入一些按钮
//addratebtn(1);
//addratebtn(1.5);
//addratebtn(2);
//addSkipbtn();//跳过按钮
addinfo();//脚本信息
changelayout();
//速度调节部分
window.onload = function () {
localStorage.setItem(keyThisTitle, JSON.stringify(window.document.title));//储存章节标题
// console.log("准备激活加速");
ratechg(playRateNow);
if (autoSkip == true) {//秒过功能,已经不抵了,别尝试,没用的
setTimeout(function () {
skipVideo();
}, (submitTime + Math.ceil(Math.random() * randomX)));
console.log("秒过了!");
};
clock = setInterval(examherftest, 3000);//阿み杰此处要改11才能考试,循环法用examherftest检测考试按钮是否能点击
;
}
// 保存课程列表(每次都会检查并更新)
console.log('🎬 视频页面加载完成,开始保存/更新课程列表');
saveCourseList();
if (testtest) { addContinuousExamButton(); }// 添加连续考试按钮
// 检查是否是刷脸后返回
checkFaceVerificationReturn();
switch (e) {
case 1:
if (typeof window.s2j_onPlayerInitOver === 'function') {
window.s2j_onPlayerInitOver();
}
{
// 修复静音错误:先检查player对象是否存在
if (typeof player !== 'undefined' && player && player.j2s_setVolume) {
try {
player.j2s_setVolume(0);
console.log("保利威播放器静音成功");
} catch (error) {
console.log("保利威播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof player !== 'undefined' && player && player.j2s_resumeVideo) {
player.j2s_resumeVideo();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
killsendQuestion3();
break;
case 2:
if (typeof window.on_CCH5player_ready === 'function') {
window.on_CCH5player_ready();
}
{
// 修复静音错误:先检查cc_js_Player对象是否存在
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.setVolume) {
try {
cc_js_Player.setVolume(0);
console.log("CC播放器静音成功");
} catch (error) {
console.log("CC播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.play) {
cc_js_Player.play();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
break;
default:
console.log("其他播放器?");
};
},
doTest: function () {
var questions = JSON.parse(localStorage.getItem(keyTest)) || {};
var qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
if (JSON.stringify(qRightAnswer) == "{}") {
qRightAnswer = LoadRightAnwser();
};
var qTestAnswer = {};
var index = 0;
while (true) {
var question = document.querySelectorAll("table[class='tablestyle']")[index];
if (question == null) break;
else {
//var q = question.querySelector(".q_name").innerText.substring(2).replace(/\s*/g, "");//问题的具体文本
// 使用新的题目获取方式
var rawQuestion = question.querySelector(".q_name").innerText.substring(2);
var q = cleanQuestionText(rawQuestion);
console.log(q);
//thisQuestions=thisQuestions+q+"@"
if (qRightAnswer.hasOwnProperty(q)) { //当查询到记录了正确答案时的操作
//console.log("问题:"+ q + ",有答案:"+ qRightAnswer[q]);
var rightSelection = findAnwser("tbody", index, qRightAnswer[q]) //返回答案选项label
if (rightSelection) {
rightSelection.click();
}
} else {
if (questions.hasOwnProperty(q)) {
questions[q] = getNextChoice(questions[q]);//通过Unicode数字+1切换到下一个选项,返回的是字母选项
//console.log("不知道答案:"+ q+",测试:"+questions[q]);
} else { //如果系统没有记录
questions[q] = "A";
};
var answer = getChoiceCode(questions[q]);//将字母选项转换为Unicode数字并减去A代表的65,等于选项顺序,0是第一个选项
var element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
if (!element) { //选项除错机制
console.log("找不到选项,选项更改为A index: " + index + " answer: " + answer);
questions[q] = "A";
answer = getChoiceCode("A");
element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
//localStorage.removeItem(keyTest)
};
try {
var answerText = element.innerText.substring(3);//"A、"占用3个字符
//console.log("测试语法:" + (answerText == element.innerText.trim().substring(2)));
//element.nextSibling.innerText.trim().substring(2); //获得当前答案文本
qTestAnswer[q] = answerText;
//console.log("qTestAnswer:"+error);
} catch (error) { console.log("答案文本获取失败A:" + error); };
if (element) {
element.click();
}
};
index = index + 1;
};
};
//存储相关记录
localStorage.setItem(keyTest, JSON.stringify(questions));
localStorage.setItem(keyTestAnswer, JSON.stringify(qTestAnswer));
setTimeout(function () {
var submitButton = document.querySelector("#btn_submit");
if (submitButton) {
submitButton.click();
}
}, (submitTime + Math.ceil(Math.random() * randomX))); //交卷延时
///专用函数区
function findAnwser(qakey, index, rightAnwserText) {
var answerslist = document.querySelectorAll(qakey)[index];
if (!answerslist) return null;
var arr = answerslist.getElementsByTagName("label");
console.log(`查找答案: ${rightAnwserText}`);
// 精确匹配
for (var i = 0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText===rightAnwserText) {
console.log(`✅ 精确匹配: ${optionText}`);
return arr[i];
}
}
// 模糊匹配
for (var i=0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText.includes(rightAnwserText) || rightAnwserText.includes(optionText)) {
console.log(`🔍 模糊匹配: ${optionText}`);
return arr[i];
}
}
console.log(`❌ 未找到匹配答案,使用第一个选项`);
return arr[0];
}
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] ? $(".tips_text")[0].innerText : null;
var dds=$(".state_cour_lis");
localStorage.removeItem(keyResult);
if (res=="考试通过" || res=="考试通过!" || res=="完成项目学习可以申请学分了" ) {
console.log("考试通过");
saveRightAnwser();
SaveAllAnwser();
cleanKeyStorage();
checkExamContinuation();
setTimeout(function () {
// ...(原有代码)
}, 1000);
} else {
console.log("考试未通过")
var tipsTextElement=document.querySelector("p[class='tips_text' ]");
if (tipsTextElement) {
tipsTextElement.innerText="本次未通过,正在尝试更换答案\r\n(此为正常现象,脚本几秒后刷新,请勿操作)"
}
var qWrong={};
for (var i=0; i < dds.length; ++i) {
if (dds[i].querySelector("img") && !dds[i].querySelector("img").src.includes("bar_img")) {//这里表示否定
var rawQuestion=dds[i].querySelector("p").title;
var cleanedQuestion=cleanQuestionText(rawQuestion);
qWrong[cleanedQuestion]=i
};
};
if (qWrong !={}) {
localStorage.setItem(keyResult, JSON.stringify(qWrong));
saveRightAnwser();
setTimeout(function () {
$("input[type=button][value='重新考试' ]").click();
}, (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 qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) ||{};
var qTitle=JSON.parse(localStorage.getItem(keyThisTitle)) || "没有记录到章节名称" ;
if (qTitle=="没有记录到章节名称" ) {
console.log("没找到章节名称");
return {};
};
var qOldAnswer=qAllAnswer[qTitle] || {};
return qOldAnswer
};
// 修改题目处理逻辑,去除干扰的问号
// 统一的题目清洗函数
function cleanQuestionText(questionText) {
if (!questionText) return '' ;
// 去除各种特殊字符和空白
let cleaned=questionText
.replace(/[??]/g, '' )
.replace(/||[\u200B-\u200D\uFEFF]/g, '' ) // 去除零宽空格
.replace(/\s+/g, ' ' ) // 将多个空格合并为一个
.trim();
// 去除题目编号
cleaned=cleaned.replace(/^\d+、/, '' ).trim();
// 智能处理括号:
// 1. 只删除完全为空或只有空格的括号
// 2. 保留包含实际内容的括号
cleaned=cleaned.replace(/[((]\s*[))]/g, '' ) // 处理空括号
.replace(/[((]\s*([^))\s]+)\s*[))]/g, '$1' ) // 保留括号内的内容
.trim();
return cleaned;
}
// 修改题目获取方式,确保一致性
function getQuestionText(questionElement) {
try {
let rawText=questionElement.querySelector(".q_name").innerText;
// 去除编号部分(如"1、")
let textWithoutNumber=rawText.replace(/^\d+、/, '' );
return cleanQuestionText(textWithoutNumber);
} catch (error) {
console.log("获取题目文本错误:", error);
return "" ;
}
}
// 修改答案记录部分
function saveRightAnwser() {
var qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
var qTestAnswer=JSON.parse(localStorage.getItem(keyTestAnswer)) || {};
var qWrongs=JSON.parse(localStorage.getItem(keyResult)) || {};
console.log("开始保存正确答案...");
console.log("错题记录:", qWrongs);
console.log("测试答案:", qTestAnswer);
// 构建清理后的题目映射
var cleanedWrongs={};
for (var wrongQ in qWrongs) {
var cleanedWrongQ=cleanQuestionText(wrongQ);
cleanedWrongs[cleanedWrongQ]=true;
console.log(`错题清洗: "${wrongQ}" -> "${cleanedWrongQ}"`);
}
for (var q in qTestAnswer) {
var cleanedQ = cleanQuestionText(q);
console.log(`处理题目: "${q}" -> "${cleanedQ}", 答案: ${qTestAnswer[q]}`);
if (!cleanedWrongs[cleanedQ]) {
console.log(`✅ 正确答案: "${cleanedQ}" -> ${qTestAnswer[q]}`);
qRightAnswer[cleanedQ] = qTestAnswer[q];
} else {
console.log(`❌ 错误题目: "${cleanedQ}" -> ${qTestAnswer[q]}`);
}
}
localStorage.removeItem(keyTestAnswer);
if (Object.keys(qRightAnswer).length > 0) {
localStorage.setItem(keyRightAnswer, JSON.stringify(qRightAnswer));
console.log("✅ 正确答案已保存:", qRightAnswer);
} else {
console.log("❌ 没有正确答案需要保存");
}
}
//答案记录函数区结束//
//------------------答案复制相关按钮--------------------------------------------
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")
//Aout=encodeURIComponent(Aout);
//window.prompt("请复制",Aout);
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;
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(textout);
}
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.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);
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
//答案复制相关按钮 end
function skipVideo() {//这是跳过视频的代码
var oVideo = document.getElementsByTagName('video')[0];
if (oVideo) {
oVideo.currentTime = oVideo.duration - 1
};
};
// 在 courseList 函数中添加导入答案按钮
function addImportAnswerBtn() {
let alink = document.createElement("a");
alink.innerHTML = '导入答案';
alink.style = btstyleB;
alink.onclick = function (event) {
var input = prompt("请粘贴要导入的答案数据(JSON格式)");
if (input) {
try {
// 解析输入的JSON数据
var importedAnswers = JSON.parse(input);
// 获取现有的答案记录
var existingAnswers = JSON.parse(localStorage.getItem(keyAllAnswer)) || {};
// 合并答案
var mergedAnswers = mergeAnswerData(existingAnswers, importedAnswers);
// 保存合并后的答案
localStorage.setItem(keyAllAnswer, JSON.stringify(mergedAnswers));
alert("✅ 答案导入成功!\n已合并 " + Object.keys(importedAnswers).length + " 个章节的答案");
} catch (error) {
alert("❌ 导入失败:数据格式不正确\n" + error);
}
}
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
// 合并答案数据的函数
function mergeAnswerData(existing, imported) {
// 深拷贝现有答案
var merged = JSON.parse(JSON.stringify(existing));
// 遍历导入的答案
for (var chapter in imported) {
if (imported.hasOwnProperty(chapter)) {
// 如果章节不存在,直接添加
if (!merged[chapter]) {
merged[chapter] = imported[chapter];
} else {
// 合并章节内的题目答案
for (var question in imported[chapter]) {
if (imported[chapter].hasOwnProperty(question)) {
merged[chapter][question] = imported[chapter][question];
}
}
}
}
}
return merged;
};
//------------------看视频页面主要函数-------------------------------------------
function clickexam() { //延时点击考试按钮。
console.log("已点击考试按钮");
setTimeout(function () {
var examButton = document.querySelector("#jrks");
if (examButton) {
examButton.click();
}
}, (Math.ceil(Math.random() * randomX)));
//}, (examTime + Math.ceil(Math.random() * randomX)));
};
//按钮插入函数相关
function addSkipbtn() {//插入按钮快进视频按钮
let alink = document.createElement("a");
alink.innerHTML = '快进视频';
alink.style = btstyleA;
alink.onclick = function (event) {
skipVideo();
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
};
function addratebtn(ra) {//倍率调整按钮
let alink = document.createElement("a");
alink.innerHTML = '' + ra + 'x';
alink.style = btstyleB;
alink.className = "speed";
alink.id = ra + "x";
alink.onclick = function (event) {
ratechg(ra);
try {
var arr = document.querySelectorAll("a[class='speed']");
arr.forEach(function (item, index, arr) {
arr[index].style = btstyleB;
});
} catch (error) {
};
alink.style = btstyleC;
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
}
function ratechg(ra) {//倍率调整
var videoObj = document.querySelector("video")
if (videoObj) {
try {
clearInterval(nspeed);
nspeed = setInterval(() => {
videoObj.playbackRate = ra;
}, 1 * 1000);
localStorage.setItem(keyPlayRate, ra);
//document.querySelector("a[id=" + "'" + ra + "x']").style = btstyleC;
//document.getElementById("playrate").innerHTML = "当前播放速率" + ra + "x";
//console.log("倍率调整为" + ra);
} catch (error) { console.log("倍率调整错误" + error); };
}
};
function addrateinfo() {//插入说明
let adiv1 = document.createElement("div");
adiv1.innerHTML = '当前播放速率';
adiv1.id = 'playrate';
adiv1.style = "font-size: 15px;text-align: center;margin-top: 10px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv1);
}
};
function addinfo() {//插入说明
//模式切换按钮
var moderesult = localStorage.getItem("华医mode");
if (moderesult == 2) {
moderesult = "当前模式:视频+考试";
} else {//包括了结果为1或者无存储的情况
moderesult = "当前模式:单刷视频";
};
var checkbox = document.createElement('div');
checkbox.innerHTML = '' + moderesult + '
[点击此处切换] ';
// 添加到页面的 body 元素中
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(checkbox);
}
//插入说明部分
let mode1 = document.querySelector("a[id='mode']");
if (mode1) {
mode1.onclick = function () {
if (mode1.innerText == "当前模式:单刷视频\n[点击此处切换]") {
mode1.innerText = "当前模式:视频+考试\n[点击此处切换]";
localStorage.setItem("华医mode", "2");
} else {
mode1.innerText = "当前模式:单刷视频\n[点击此处切换]";
localStorage.setItem("华医mode", "1");
};
};
}
let adiv2 = document.createElement("div");
adiv2.innerHTML = '       本人医学研一学生,经常要帮师兄师姐刷华医视频,属实太累。偶然在抖音发现Dr.S的脚本,结果刷完1个视频立刻考试,导致频繁人脸识别跟手动区别不大。原作者已不更新,于是我自学修改了播放逻辑,实现无人值守连续播放。现将原先自用的脚本分享给大家❤❤
     刷完视频再切换考试模式,即可连续考试。
';
adiv2.id = 'jsinfo';
adiv2.style = "position:relative;left:10px;top:5px;width:240px;font-size:13px;text-align: justify;border: 1px dashed #ff9595;padding:5px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv2);
}
if (typeof $ !== 'undefined') {
$('div:contains("观看视频完成后,才能进入考试")').eq(-1).text('建议360安全浏览器和脚本猫');
}
// 创建连续考试按钮的容器
let examBtnContainer = document.createElement('div');
examBtnContainer.id = 'continuousExamBtnContainer';
examBtnContainer.style = "text-align: center; margin: 10px 0;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(examBtnContainer);
}
};
function changelayout() {
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv) {
jjDiv.remove();
}
var photoImg = document.querySelector("img[id='photo']");
if (photoImg) {
photoImg.outerHTML = `
`;
photoImg.style.width = "120px";
photoImg.style.height = "120px";
}
var titleDivs = document.querySelectorAll("div[class='title']");
if (titleDivs[0] && titleDivs[0].children[0]) {
titleDivs[0].children[0].style = "color: #ff0000;font-weight: bold";
titleDivs[0].children[0].innerText = "支持作者";
}
var imgTextDivs = document.querySelector("div[class='imgtext']");
if (imgTextDivs && imgTextDivs.children[1]) {
imgTextDivs.children[1].style.width = "125px";
imgTextDivs.children[1].style = "color: #ff0000;padding-top:10px";
imgTextDivs.children[1].innerText = "作 者\n创作优化不易\n投点小费吧\n❤谢啦❤\n❤"
}
var topDiv = document.querySelector("div[class='top']");
if (topDiv) {
topDiv.outerHTML = '如服务器调整,脚本可能失效。反馈意见、免费增加课程请在Greasyfork私信或脚本反馈区联络。也欢迎投喂↓
';
}
};
function cleanKeyStorage() {//缓存清理
localStorage.removeItem(keyTest);
localStorage.removeItem(keyResult);
localStorage.removeItem(keyTestAnswer);
localStorage.removeItem(keyRightAnswer);
};
function examherftest() {//考试按钮激活状态检测
var examButton = document.getElementById("jrks");
var hreftest = examButton ? examButton.attributes["disabled"] : null;
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if ((state == "已完成" || state == "待考试" || !hreftest) && examButton) {//value不为#说明考试按钮已经激活
console.log("已经播放完了");
// 优先处理"视频+考试"模式下的"待考试"状态
var modeElement = document.querySelector("a[id='mode']");
if (modeElement && modeElement.innerText.indexOf("视频+考试") != -1 && state == "待考试") {
console.log("mode=2,准备进入考试");
// 重试机制:尝试5次进入考试
var retryCount = 0;
var maxRetries = 5;
function tryEnterExam() {
retryCount++;
console.log(`尝试进入考试 (第${retryCount}次)`);
try {
// 方法1:尝试点击考试按钮
if (document.getElementById("jrks") && !document.getElementById("jrks").disabled) {
document.getElementById("jrks").click();
console.log("成功点击考试按钮");
return true; // 成功进入考试
}
// 方法2:尝试备用方式
if (typeof cwrid !== 'undefined') {
window.open("/pages/exam_tip.aspx?cwrid=" + cwrid, "_self");
console.log("尝试备用方式进入考试");
return true;
}
// 方法3:尝试通过URL跳转
var currentUrl = window.location.href;
if (currentUrl.includes("course_ware")) {
var examUrl = currentUrl.replace("course_ware/course_ware_", "pages/exam.aspx?cwid=")
.split("?")[0] + "?cwid=" + getUrlParam("cwid");
window.location.href = examUrl;
console.log("尝试通过URL跳转进入考试");
return true;
}
} catch (error) {
console.log(`第${retryCount}次尝试失败:`, error);
}
return false; // 进入考试失败
}
// 立即尝试第一次
if (tryEnterExam()) {
return; // 成功进入考试,直接返回
}
// 设置重试间隔
var retryInterval = setInterval(function () {
if (retryCount >= maxRetries) {
clearInterval(retryInterval);
console.log(`尝试${maxRetries}次进入考试均失败,继续听课`);
// 继续执行后续的跳转到下一个视频的逻辑
proceedToNextVideo();
} else if (tryEnterExam()) {
clearInterval(retryInterval); // 成功进入考试,停止重试
}
}, 2000); // 每2秒重试一次
} else {
// 单刷视频模式或非待考试状态,直接继续听课
proceedToNextVideo();
};
} else {//#代表考试按钮还没激活
//继续播放,无需任何操作
}
}
// 跳转到下一个视频的函数
function proceedToNextVideo() {
console.log('🚀 准备跳转到下一个视频...');
const nextCwid = getNextCourseCwid();
if (nextCwid) {
console.log(`✅ 确定跳转到课程: ${nextCwid.substring(0, 8)}...`);
console.log(`🌐 跳转URL: course_ware.aspx?cwid=${nextCwid}`);
// 延迟跳转,让用户有时间查看日志
setTimeout(() => {
console.log('⏩ 正在跳转...');
window.location.href = `course_ware.aspx?cwid=${nextCwid}`;
}, 2000);
} else {
console.log('❌ 没有找到可用的课程,尝试刷新页面');
setTimeout(() => {
console.log('🔄 正在刷新页面...');
window.location.reload();
}, 2000);
}
}
// 辅助函数:获取URL参数
function getUrlParam(name) {
var urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
};
//课堂问答跳过,临时版
function sleep(timeout) {
return new Promise((resolve) => { setTimeout(resolve, timeout); });
console.log("课堂问答循环调用");
};
function asynckillsendQuestion() {
(async function () {
while (!window.player || !window.player.sendQuestion) {
await sleep(20);
};
//console.log("课堂问答跳过插入");
player.sendQuestion = function () {
//console.log("播放器尝试弹出课堂问答,已屏蔽。");
};
})();
};
function killsendQuestion2() {
if (typeof (isInteraction) == "undefined") {
//console.log('变量未定义');
} else {
console.log('isInteraction设置off');
isInteraction = "off";
};
};
function killsendQuestion3() { //点击跳过按钮版的跳过课堂答题
var clockms = setInterval(async function () {
try {
if (typeof $ !== 'undefined' && $('.pv-ask-head').length && $('.pv-ask-head').length > 0) {
console.log("检测到问题对话框,尝试跳过");
$(".pv-ask-skip").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.signBtn').length && $('.signBtn').length > 0) {
console.log("检测到签到对话框,尝试跳过");
$(".signBtn").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' &&
$("button[onclick='closeProcessbarTip()']").length &&
$("button[onclick='closeProcessbarTip()']").length > 0 &&
$("div[id='div_processbar_tip']").css("display") == "block") {
console.log("检测到温馨提示对话框(不能拖拽),尝试跳过");//
//*[@id="div_processbar_tip"]/div/div[2]/input
//document.querySelector("#div_processbar_tip > div > div.foot_sub > input")
//#div_processbar_tip > div > div.foot_sub > input
//
$("button[onclick='closeBangZhu()']").click();
$("button[onclick='closeProcessbarTip()']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $("button[class='btn_sign']").length && $("button[class='btn_sign']").length > 0) {
console.log("检测到温馨提示对话框(疲劳提醒),尝试跳过");
$("button[class='btn_sign']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.rig_btn').length && $('.rig_btn').length > 0) {
if ($('#div_processbar_tip').is(':visible')) {
console.log("检测到按钮(知道了),执行隐藏操作");
$('#div_processbar_tip').hide();
}
//$(".rig_btn").click();
};
} catch (err) {
console.log(err);
};
try {
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if (typeof $ !== 'undefined' &&
$('video').prop('paused') == true &&
state != "已完成" &&
state != "待考试") {
console.log("视频意外暂停,恢复播放");
$('video').get(0).play();
//$('video').prop('volumed') = 0;
$('video').prop('muted') = true;
} else if (state == "已完成") {
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.pause();
}
//clearInterval(clockms);
};
} catch (err) {
//console.log(err);
};
}, 10000);
};
function autoClickKnowButton() {
// 检测按钮是否加载完成
const observer = new MutationObserver(() => {
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
observer.disconnect(); // 停止观察
button.click(); // 点击按钮
}
});
// 开始观察文档的变化
observer.observe(document.body, {
childList: true,
subtree: true
});
// 如果按钮已经加载完成,直接点击
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
button.click();
}
}
// 在全局函数区添加以下函数
function saveCourseList() {
console.log('📋 开始保存/更新课程列表...');
// 尝试获取课程列表容器
const courseContainer = document.querySelector('.page-container');
if (!courseContainer) {
console.log('❌ 未找到课程列表容器');
return;
}
// 尝试获取课程项
const courseItems = document.querySelectorAll('.lis-inside-content');
if (courseItems.length === 0) {
console.log('❌ 未找到课程项');
return;
}
console.log(`📚 找到 ${courseItems.length} 个课程项,开始解析...`);
const currentCourseList = [];
let hasChanges = false;
courseItems.forEach((item, index) => {
const titleElement = item.querySelector('h2');
const statusButton = item.querySelector('button');
if (titleElement && statusButton) {
const title = titleElement.textContent.trim();
const status = statusButton.textContent.trim();
const statusColor = statusButton.style.background;
// 从onclick属性中提取cwid
const onclickAttr = titleElement.getAttribute('onclick');
let cwid = '';
if (onclickAttr) {
const match = onclickAttr.match(/cwid=([^']+)/);
if (match && match[1]) {
cwid = match[1];
}
}
if (cwid) {
currentCourseList.push({
title,
status,
statusColor,
cwid,
index
});
//console.log(` 课程 ${index + 1}: "${title}" - 状态: ${status}`);
}
}
});
if (currentCourseList.length === 0) {
console.log('❌ 未解析到任何课程信息');
return;
}
// 获取之前保存的课程列表
const previousCourseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
if (previousCourseList.length === 0) {
// 第一次保存
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`✅ 首次保存课程列表完成,共 ${currentCourseList.length} 个课程`);
return;
}
// 检查是否有变化
console.log('🔍 检查课程状态变化...');
for (let i = 0; i < currentCourseList.length; i++) {
const currentCourse=currentCourseList[i];
const previousCourse=previousCourseList[i];
if (!previousCourse) {
console.log(` 新增课程: "${currentCourse.title}" `);
hasChanges=true;
continue;
}
// 检查状态变化
if (currentCourse.status !==previousCourse.status) {
console.log(` 状态变化: "${currentCourse.title}" - ${previousCourse.status} → ${currentCourse.status}`);
hasChanges=true;
}
// 检查标题变化(可能课程有更新)
if (currentCourse.title !==previousCourse.title) {
console.log(` 标题变化: "${previousCourse.title}" → "${currentCourse.title}" `);
hasChanges=true;
}
// 检查cwid变化(理论上不应该变)
if (currentCourse.cwid !==previousCourse.cwid) {
console.log(` cwid变化: "${currentCourse.title}" `);
hasChanges=true;
}
}
// 检查课程数量变化
if (currentCourseList.length !==previousCourseList.length) {
console.log(` 课程数量变化: ${previousCourseList.length} → ${currentCourseList.length}`);
hasChanges=true;
}
if (hasChanges) {
// 更新课程列表
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`🔄 课程列表已更新,共 ${currentCourseList.length} 个课程`);
// 输出详细的课程状态
console.log('📊 当前所有课程状态:');
currentCourseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
} else {
console.log('✅ 课程列表无变化,无需更新');
// 即使无变化,也确保本地存储的是最新数据(防止数据损坏)
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
}
}
function getCurrentCourseCwid() {
// 从当前URL获取cwid
const urlParams = new URLSearchParams(window.location.search);
const cwid = urlParams.get('cwid');
console.log(`🔍 当前课程 cwid: ${cwid ? cwid.substring(0, 8) + '...' : '未找到'}`);
return cwid;
}
function getNextCourseCwid() {
console.log('🔄 开始查找下一个课程...');
// 尝试从localStorage获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
const currentCwid = getCurrentCourseCwid();
if (courseList.length === 0) {
console.log('❌ 未找到存储的课程列表');
return null;
}
console.log(`📊 课程列表中有 ${courseList.length} 个课程`);
// 找到当前课程的索引
const currentIndex = courseList.findIndex(course => course.cwid === currentCwid);
if (currentIndex === -1) {
console.log('❌ 未找到当前课程在列表中的位置');
console.log('当前课程可能不在列表中,将尝试第一个未完成的课程');
// 尝试查找第一个未完成的课程
for (let i = 0; i < courseList.length; i++) {
const course=courseList[i];
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到第一个未完成课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
return null;
}
console.log(`📍 当前课程位置: 第 ${currentIndex + 1} 个 - "${courseList[currentIndex].title}" `);
// 查找下一个未完成的课程(从当前位置向后找)
console.log('🔍 向后查找未完成的课程...');
for (let i=currentIndex + 1; i < courseList.length; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到下一个课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
// 如果后面没有未完成的课程,尝试从开头查找
console.log('🔍 向后未找到,从开头查找未完成的课程...');
for (let i=0; i < currentIndex; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到前面的课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
console.log('所有课程状态:');
courseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
return null;
}
//--------------------------插入悬浮框------------------------------------//
function advis() {
// 🔴 第一步:只在顶层窗口运行,iframe 中直接退出
if (window.self !== window.top) {
console.log('小助手:当前处于 iframe 中,不创建面板');
return;
}
// 🔴 第二步:检查是否已有面板,防止重复创建(即使脚本多次调用)
const existingPanel = document.getElementById('Div1');
if (existingPanel) {
console.log('已检测到小助手面板,防止重复创建');
return; // 或者 existingPanel.remove(); 再创建(推荐 return 即可)
}
// 🟡 第三步:创建新面板
let div1 = document.createElement("div");
div1.innerHTML = `
`;
document.body.append(div1);
// 绑定事件
let share1 = document.getElementById('Share1');
let share2 = document.getElementById('Share2');
let clo = document.getElementById('clo');
if (share1) {
share1.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/500010", "_blank");
};
}
if (share2) {
share2.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/555651", "_blank");
};
}
if (clo) {
clo.onclick = function () {
var panel = document.getElementById('Div1');
if (panel) {
panel.style.display = 'none';
}
};
}
// === 初始化:左对齐课程列表 ===
const panel = document.getElementById('Div1');
if (!panel) return;
const container = document.querySelector('.page-container') ||
document.querySelector('.lis-content') ||
document.querySelector('.container-inside-header');
let initialLeft = 140; // 默认值
if (container) {
const rect = container.getBoundingClientRect();
initialLeft = rect.left + window.pageXOffset;
}
panel.style.left = initialLeft + 'px';
// === 拖拽功能 ===
let isDragging = false;
let offsetX, offsetY;
panel.addEventListener('mousedown', function (e) {
if (e.target === clo ||
e.target.tagName === 'A' ||
e.target.tagName === 'IMG' ||
e.target.tagName === 'HR') return;
isDragging = true;
offsetX = e.clientX - panel.getBoundingClientRect().left;
offsetY = e.clientY - panel.getBoundingClientRect().top;
e.preventDefault();
});
document.addEventListener('mousemove', function (e) {
if (!isDragging) return;
panel.style.left = (e.clientX - offsetX) + 'px';
panel.style.top = (e.clientY - offsetY) + 'px';
});
document.addEventListener('mouseup', () => {
isDragging = false;
});
// 创建状态面板(默认隐藏)
//createStatusPanel();
//document.getElementById('examStatusPanel').style.display = 'none';
}
//--------------------------连续考试的函数------------------------------------//
// 修改 addContinuousExamButton 函数
function addContinuousExamButton() {
// 检查是否已存在连续考试按钮
if (document.getElementById('continuousExamBtn')) {
return;
}
// 创建连续考试按钮
let btn = document.createElement("a");
btn.innerHTML = '连续考试';
btn.style = btstyleA
btn.id = 'continuousExamBtn';
btn.onclick = function () {
console.log('🚀 开始连续考试流程...');
startContinuousExam();
};
// 找到建议提示框
const tipDiv = document.querySelector('div.r div[style*="border: 1px dashed #ff9595"]');
if (tipDiv) {
// 创建按钮容器
let btnContainer = document.createElement('div');
btnContainer.style = "text-align: center; margin: 10px 0;";
btnContainer.appendChild(btn);
// 将按钮容器插入到建议提示框后面
tipDiv.parentNode.insertBefore(btnContainer, tipDiv.nextSibling);
} else {
// 如果找不到建议提示框,使用预留的容器
const btnContainer = document.getElementById('continuousExamBtnContainer');
if (btnContainer) {
btnContainer.appendChild(btn);
} else {
// 如果容器也不存在,添加到页面底部
document.body.appendChild(btn);
}
}
}
// 新增:创建状态面板的函数
function createStatusPanel() {
// 检查是否存在 exam_phase
const examPhase = localStorage.getItem('exam_phase');
if (!examPhase) {
// 如果不存在 exam_phase,移除可能存在的面板
const existingPanel = document.getElementById('examStatusPanel');
if (existingPanel) {
existingPanel.remove();
}
return;
}
// 检查是否已存在状态面板
if (document.getElementById('examStatusPanel')) {
// 如果面板已存在,只需更新状态信息
updatePanelContent();
return;
}
// 创建状态面板
const panel = document.createElement('div');
panel.id = 'examStatusPanel';
panel.style = `
position: fixed;
top: 20px;
right: 20px;
width: 300px;
background-color: rgba(255, 255, 255, 0.95);
border: 2px solid #4cb0f9;
border-radius: 8px;
padding: 15px;
z-index: 10000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
font-family: 'Microsoft YaHei', sans-serif;
`;
panel.innerHTML = `
连续考试状态
加载中...
`;
// 确保面板正确插入到页面中
document.body.appendChild(panel);
// 添加取消按钮事件
var cancelBtn = document.getElementById('cancelExamBtn');
if (cancelBtn) {
cancelBtn.onclick = function () {
if (confirm('确定要取消连续考试吗?')) {
cancelContinuousExam();
}
};
}
// 更新面板内容
updatePanelContent();
// 辅助函数:更新面板内容
function updatePanelContent() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examPhase = localStorage.getItem('exam_phase');
let statusMessage = '';
if (examPhase === 'face_verification') {
statusMessage = `👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else if (examPhase === 'examination') {
statusMessage = `📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else {
statusMessage = '连续考试进行中...';
}
const contentElement = document.getElementById('examStatusContent');
if (contentElement) {
contentElement.innerHTML = statusMessage;
}
}
}
// 修改:更新状态提示的函数
function updateExamStatus(message, isError = false) {
createStatusPanel(); // 确保面板存在
const panel = document.getElementById('examStatusPanel');
// 添加存在性检查
if (!panel) {
console.log('状态面板不存在,跳过更新');
return;
}
panel.style.display = 'block';
const statusContent = document.getElementById('examStatusContent');
if (statusContent) {
statusContent.innerHTML = message;
statusContent.style.color = isError ? '#f15854' : '#333';
}
}
// 取消连续考试
function cancelContinuousExam() {
console.log('❌ 结束连续考试');
// 清除相关状态
localStorage.removeItem('exam_courses');
localStorage.removeItem('current_exam_index');
localStorage.removeItem('exam_phase');
// 只有在面板存在时才更新状态
const panel = document.getElementById('examStatusPanel');
if (panel) {
updateExamStatus('连续考试已取消');
// 3秒后隐藏状态面板
setTimeout(() => {
//panel.style.display = 'none';
}, 3000);
} else {
console.log('状态面板不存在,直接清除状态');
}
}
// 连续考试主函数
function startContinuousExam() {
// 强制设置为单刷视频模式,避免冲突
localStorage.setItem("华医mode", "1");
console.log('🚀 开始连续考试流程,模式强制设置为单刷视频');
localStorage.setItem('exam_phase', 'setup'); // 设置阶段为初始化
// 创建状态面板
createStatusPanel();
// 获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
// 筛选待考试的课程
const examCourses = courseList.filter(course => course.status === '待考试');
if (examCourses.length === 0) {
console.log('❌ 没有找到待考试的课程');
updateExamStatus('❌ 没有找到待考试的课程', true);
localStorage.removeItem('exam_phase');
return;
}
// 保存待考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
localStorage.setItem('exam_phase', 'face_verification'); // 设置阶段为刷脸
console.log(`📋 找到 ${examCourses.length} 个待考试课程`);
updateExamStatus(`找到 ${examCourses.length} 个待考试课程
准备开始刷脸流程...`);
// 开始刷脸流程
startFaceVerificationProcess();
}
// 刷脸流程
function startFaceVerificationProcess() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有课程刷脸完成,开始连续考试');
updateExamStatus('✅ 所有课程刷脸完成
开始连续考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startFaceVerificationProcess, 1000);
return;
}
console.log(`👤 开始第 ${currentIndex + 1} 个课程刷脸: ${currentCourse.title}`);
updateExamStatus(`👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开课程链接进行刷脸
window.location.href = `course_ware.aspx?cwid=${currentCourse.cwid}`;
}
// 监听页面加载,判断是否在刷脸后返回
function checkFaceVerificationReturn() {
const examPhase = localStorage.getItem('exam_phase');
const isInFaceVerification = examPhase === 'face_verification';
if (isInFaceVerification) {
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
// 只有当索引有效时才继续
if (currentIndex < examCourses.length) {
console.log('🔍 检测到刷脸后返回,继续下一个课程');
localStorage.setItem('current_exam_index', currentIndex + 1);
updateExamStatus(`✅ 刷脸完成 ${currentIndex + 1}/${examCourses.length}
准备下一个课程...`);
// 添加延迟防止过快跳转
setTimeout(startFaceVerificationProcess, 3000);
} else {
console.log('✅ 刷脸流程已完成');
updateExamStatus('✅ 刷脸流程已完成
准备开始考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
}
}
}
// 开始所有考试
function startAllExams() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
if (examCourses.length === 0) {
console.log('❌ 没有待考试的课程');
updateExamStatus('❌ 没有待考试的课程', true);
return;
}
console.log('🎯 开始连续考试流程');
updateExamStatus(`🎯 开始连续考试流程
共 ${examCourses.length} 个考试待完成`);
// 保存考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
// 开始第一个考试
startNextExam();
}
// 开始下一个考试
function startNextExam() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有考试完成!');
updateExamStatus('✅ 所有考试完成!
连续考试流程结束');
cancelContinuousExam();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startNextExam, 1000);
return;
}
console.log(`📝 开始第 ${currentIndex + 1} 个考试: ${currentCourse.title}`);
updateExamStatus(`📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开考试页面
window.location.href = `/pages/exam.aspx?cwid=${currentCourse.cwid}`;
}
// 在考试结果页面检查是否需要继续下一个考试
function checkExamContinuation() {
const examPhase = localStorage.getItem('exam_phase');
const isInExamMode = examPhase === 'examination';
if (isInExamMode) {
console.log('🔍 检测到考试完成,准备下一个考试');
// 增加索引
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
localStorage.setItem('current_exam_index', currentIndex + 1);
// 更新状态提示
updateExamStatus(`✅ 考试完成 ${currentIndex + 1}/${examCourses.length}
准备下一个考试...`);
// 短暂延迟后继续下一个考试
setTimeout(() => {
startNextExam();
}, 3000);
}
}
//---------------------------------全局函数区end------------------------------//
})();gwQOWPuloSKykYzlA6CZxbTEFRiWVVbcQ9nxyvmpirmdmlD/UAA/8MQzsAMGXECpceKpvAcHnEPEINwkLqIrLlf5pEMBIMA7PEM0YMAHJZwU/gM9gM97RAMuaNhMuM1JXVc+jJNT+IUnFgMJsMM6BCPVJeIrTiOBHdkFtIM+3Nc5xN4j7c35jQUR5MP0pcSfPU5JoYPctWLHpIOqOQCwfZ0ZHlECUiM9al3FXIc4NZx2zeMwiYNwrU8znIdTJIA63JA/HI4gwsReXGBNlMPmHV49RuSBqVimzAneIJkuZh5tOUszGKQ/oIPKNIXLhEmnxALdIGIy+shaHNfrSaRLnhmbvdsXYhBGbMqQfSR+NIXe1AhwzEX8vSRQBiXfGUk5kM84/xJMP1xAM6QTWXDAJjYFPoTHDT0DBjSTUF4lVrogdBhAMDQDBjhAkRzl2kCHsSDLHJ2DOoYEAZCUzpDAMEgOP2alXO4d6tkFMtSDO5SUKH4fBikJLBDWhIkD7PUDLBRkJPEDmaTlXC4mNyIHtIDJO1BA+LlYSCBDNPBkWSAAFL6I5XgjcLADLBgYY46mK6Ie59UDlfQEdK0RRhjAI8KMOpxAQsLEOdCVPEkLBYgmae4mGtZFc90Qk8ldX2KSJt2QO+hD4zVFOizlezyDO+SmYvKmdIranp2TdZUFBkwm9RwHfXghbSDHPzanH4VdXhRmmywYO1SYdk4ne3LdUqhFMP8ECZu0j26GFJuNQAJQQD4YQHShpJtdgHBVSZsU14s4Zh36xDpgiX+2J4PmHdXhQzDUAwLwgwjoA8JwZpoMg/kpWsWl5VBcgFTCDAnUUzKGRFRIKD+gw0nGZYO2qBo+HgHggwGcwDbuGVH8BQFwQDoNXTiJ3nV0JP34Q+SkJEiUQzsgwwno3g66KJOKGs2Ux5GMUxfOBNtYDgLAzYAqJlNQgEeWAJYUaIDE1Ho2KZmW4B+xzXk85Ez0VTsY5nuQx5imRFvY2OCtg8Ul44/dB8JEZ5n26VlVm19QjI3KxJ7dQ3GKhwPEaf50ILI8g2Sm3VJIR+p9IYv6qaX6HOu9FZ///kU5oMONsc/+cWJQKCXH4ZRsKipgaIkkFhGfXqqrThtvnAAhEYE6lIA+5CRnsgchsUMsDANyAuGrBquLVttHgAAuIAMu0ENWGN6ptcUsGIA+JIA4RJOwVmt7GmF3imV6wF+Ytqq1fusi6kXlRGkCvqc+Viq4pqv/AQuM8NxsrGQcqqu8YiX6tB6XoKr5DBg0kNyazau/XuWeAWo8hlSMxeu/HizCJqzCLizDNqzDPizERqzETizFVqzFXizGZqzGbizHdqzHfizIhqzIjizJlqzJnizKpqzKrizLtqzLvizMxqzMzizN1qzN3izO5qzO7izP9qzP/izQBq3QDi3RIhat0R4t0iat0i4t0zat0z4t1Eat1E4t1Vat1V4t1qJsQAAAOw==`;
var clock = null;
var testtest = true; //另一个可能会封号的功能,仅调试使用。
advis();
createStatusPanel(); //状态监视面板根据需要进行显示
// 修复错误:检查元素是否存在后再设置内容
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "当前网址已适配ヾ(๑╹◡╹)ノ"
失效请赞赏联系  ε(┬┬﹏┬┬)3";
}
if (urlTip == "course_ware_polyv.aspx") { //保利威播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(1);
} else if (urlTip == "course_ware_cc.aspx") { //CC播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(2);
} else if (urlTip == "face.aspx") { //刷脸
console.log("当前任务: 刷脸界面");
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "course.aspx" || urlTip == "cme.aspx") { //课程列表页面
console.log("当前任务: 课程列表");
huayi.courseList();
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "exam.aspx") { //考试页面
console.log("当前任务: 华医考试");
huayi.doTest();
} else if (urlTip == "exam_result.aspx") { //考试结果页面
console.log("当前任务: 华医考试结果审核");
huayi.doResult();
} else {
console.log("其它情况");
try {
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "此页面非视频、考试或未适配";
}
document.querySelector("img[id='Pic']").style.display = "block";
} catch (error) { };
};
function getHuayi() {
return {
courseList: function () {
addAnwserCopybtn();
addImportAnswerBtn();
DelAllAnwser();
},
seeVideo: function (e) {
var tr = localStorage.getItem(keyPlayRate);
//console.log("存储读取" + tr);//读取倍速
//var playRateNow = tr ? tr : vSpeed;
var playRateNow = 1;
cleanKeyStorage();
asynckillsendQuestion();//屏蔽课堂问答的函数;
killsendQuestion2();//屏蔽课堂问答的函数2;
killsendQuestion3(); //循环检测问答对话框是否弹出。
//addrateinfo();//插入一些按钮
//addratebtn(1);
//addratebtn(1.5);
//addratebtn(2);
//addSkipbtn();//跳过按钮
addinfo();//脚本信息
changelayout();
//速度调节部分
window.onload = function () {
localStorage.setItem(keyThisTitle, JSON.stringify(window.document.title));//储存章节标题
// console.log("准备激活加速");
ratechg(playRateNow);
if (autoSkip == true) {//秒过功能,已经不抵了,别尝试,没用的
setTimeout(function () {
skipVideo();
}, (submitTime + Math.ceil(Math.random() * randomX)));
console.log("秒过了!");
};
clock = setInterval(examherftest, 3000);//阿み杰此处要改11才能考试,循环法用examherftest检测考试按钮是否能点击
;
}
// 保存课程列表(每次都会检查并更新)
console.log('🎬 视频页面加载完成,开始保存/更新课程列表');
saveCourseList();
if (testtest) { addContinuousExamButton(); }// 添加连续考试按钮
// 检查是否是刷脸后返回
checkFaceVerificationReturn();
switch (e) {
case 1:
if (typeof window.s2j_onPlayerInitOver === 'function') {
window.s2j_onPlayerInitOver();
}
{
// 修复静音错误:先检查player对象是否存在
if (typeof player !== 'undefined' && player && player.j2s_setVolume) {
try {
player.j2s_setVolume(0);
console.log("保利威播放器静音成功");
} catch (error) {
console.log("保利威播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof player !== 'undefined' && player && player.j2s_resumeVideo) {
player.j2s_resumeVideo();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
killsendQuestion3();
break;
case 2:
if (typeof window.on_CCH5player_ready === 'function') {
window.on_CCH5player_ready();
}
{
// 修复静音错误:先检查cc_js_Player对象是否存在
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.setVolume) {
try {
cc_js_Player.setVolume(0);
console.log("CC播放器静音成功");
} catch (error) {
console.log("CC播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.play) {
cc_js_Player.play();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
break;
default:
console.log("其他播放器?");
};
},
doTest: function () {
var questions = JSON.parse(localStorage.getItem(keyTest)) || {};
var qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
if (JSON.stringify(qRightAnswer) == "{}") {
qRightAnswer = LoadRightAnwser();
};
var qTestAnswer = {};
var index = 0;
while (true) {
var question = document.querySelectorAll("table[class='tablestyle']")[index];
if (question == null) break;
else {
//var q = question.querySelector(".q_name").innerText.substring(2).replace(/\s*/g, "");//问题的具体文本
// 使用新的题目获取方式
var rawQuestion = question.querySelector(".q_name").innerText.substring(2);
var q = cleanQuestionText(rawQuestion);
console.log(q);
//thisQuestions=thisQuestions+q+"@"
if (qRightAnswer.hasOwnProperty(q)) { //当查询到记录了正确答案时的操作
//console.log("问题:"+ q + ",有答案:"+ qRightAnswer[q]);
var rightSelection = findAnwser("tbody", index, qRightAnswer[q]) //返回答案选项label
if (rightSelection) {
rightSelection.click();
}
} else {
if (questions.hasOwnProperty(q)) {
questions[q] = getNextChoice(questions[q]);//通过Unicode数字+1切换到下一个选项,返回的是字母选项
//console.log("不知道答案:"+ q+",测试:"+questions[q]);
} else { //如果系统没有记录
questions[q] = "A";
};
var answer = getChoiceCode(questions[q]);//将字母选项转换为Unicode数字并减去A代表的65,等于选项顺序,0是第一个选项
var element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
if (!element) { //选项除错机制
console.log("找不到选项,选项更改为A index: " + index + " answer: " + answer);
questions[q] = "A";
answer = getChoiceCode("A");
element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
//localStorage.removeItem(keyTest)
};
try {
var answerText = element.innerText.substring(3);//"A、"占用3个字符
//console.log("测试语法:" + (answerText == element.innerText.trim().substring(2)));
//element.nextSibling.innerText.trim().substring(2); //获得当前答案文本
qTestAnswer[q] = answerText;
//console.log("qTestAnswer:"+error);
} catch (error) { console.log("答案文本获取失败A:" + error); };
if (element) {
element.click();
}
};
index = index + 1;
};
};
//存储相关记录
localStorage.setItem(keyTest, JSON.stringify(questions));
localStorage.setItem(keyTestAnswer, JSON.stringify(qTestAnswer));
setTimeout(function () {
var submitButton = document.querySelector("#btn_submit");
if (submitButton) {
submitButton.click();
}
}, (submitTime + Math.ceil(Math.random() * randomX))); //交卷延时
///专用函数区
function findAnwser(qakey, index, rightAnwserText) {
var answerslist = document.querySelectorAll(qakey)[index];
if (!answerslist) return null;
var arr = answerslist.getElementsByTagName("label");
console.log(`查找答案: ${rightAnwserText}`);
// 精确匹配
for (var i = 0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText===rightAnwserText) {
console.log(`✅ 精确匹配: ${optionText}`);
return arr[i];
}
}
// 模糊匹配
for (var i=0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText.includes(rightAnwserText) || rightAnwserText.includes(optionText)) {
console.log(`🔍 模糊匹配: ${optionText}`);
return arr[i];
}
}
console.log(`❌ 未找到匹配答案,使用第一个选项`);
return arr[0];
}
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] ? $(".tips_text")[0].innerText : null;
var dds=$(".state_cour_lis");
localStorage.removeItem(keyResult);
if (res=="考试通过" || res=="考试通过!" || res=="完成项目学习可以申请学分了" ) {
console.log("考试通过");
saveRightAnwser();
SaveAllAnwser();
cleanKeyStorage();
checkExamContinuation();
setTimeout(function () {
// ...(原有代码)
}, 1000);
} else {
console.log("考试未通过")
var tipsTextElement=document.querySelector("p[class='tips_text' ]");
if (tipsTextElement) {
tipsTextElement.innerText="本次未通过,正在尝试更换答案\r\n(此为正常现象,脚本几秒后刷新,请勿操作)"
}
var qWrong={};
for (var i=0; i < dds.length; ++i) {
if (dds[i].querySelector("img") && !dds[i].querySelector("img").src.includes("bar_img")) {//这里表示否定
var rawQuestion=dds[i].querySelector("p").title;
var cleanedQuestion=cleanQuestionText(rawQuestion);
qWrong[cleanedQuestion]=i
};
};
if (qWrong !={}) {
localStorage.setItem(keyResult, JSON.stringify(qWrong));
saveRightAnwser();
setTimeout(function () {
$("input[type=button][value='重新考试' ]").click();
}, (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 qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) ||{};
var qTitle=JSON.parse(localStorage.getItem(keyThisTitle)) || "没有记录到章节名称" ;
if (qTitle=="没有记录到章节名称" ) {
console.log("没找到章节名称");
return {};
};
var qOldAnswer=qAllAnswer[qTitle] || {};
return qOldAnswer
};
// 修改题目处理逻辑,去除干扰的问号
// 统一的题目清洗函数
function cleanQuestionText(questionText) {
if (!questionText) return '' ;
// 去除各种特殊字符和空白
let cleaned=questionText
.replace(/[??]/g, '' )
.replace(/||[\u200B-\u200D\uFEFF]/g, '' ) // 去除零宽空格
.replace(/\s+/g, ' ' ) // 将多个空格合并为一个
.trim();
// 去除题目编号
cleaned=cleaned.replace(/^\d+、/, '' ).trim();
// 智能处理括号:
// 1. 只删除完全为空或只有空格的括号
// 2. 保留包含实际内容的括号
cleaned=cleaned.replace(/[((]\s*[))]/g, '' ) // 处理空括号
.replace(/[((]\s*([^))\s]+)\s*[))]/g, '$1' ) // 保留括号内的内容
.trim();
return cleaned;
}
// 修改题目获取方式,确保一致性
function getQuestionText(questionElement) {
try {
let rawText=questionElement.querySelector(".q_name").innerText;
// 去除编号部分(如"1、")
let textWithoutNumber=rawText.replace(/^\d+、/, '' );
return cleanQuestionText(textWithoutNumber);
} catch (error) {
console.log("获取题目文本错误:", error);
return "" ;
}
}
// 修改答案记录部分
function saveRightAnwser() {
var qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
var qTestAnswer=JSON.parse(localStorage.getItem(keyTestAnswer)) || {};
var qWrongs=JSON.parse(localStorage.getItem(keyResult)) || {};
console.log("开始保存正确答案...");
console.log("错题记录:", qWrongs);
console.log("测试答案:", qTestAnswer);
// 构建清理后的题目映射
var cleanedWrongs={};
for (var wrongQ in qWrongs) {
var cleanedWrongQ=cleanQuestionText(wrongQ);
cleanedWrongs[cleanedWrongQ]=true;
console.log(`错题清洗: "${wrongQ}" -> "${cleanedWrongQ}"`);
}
for (var q in qTestAnswer) {
var cleanedQ = cleanQuestionText(q);
console.log(`处理题目: "${q}" -> "${cleanedQ}", 答案: ${qTestAnswer[q]}`);
if (!cleanedWrongs[cleanedQ]) {
console.log(`✅ 正确答案: "${cleanedQ}" -> ${qTestAnswer[q]}`);
qRightAnswer[cleanedQ] = qTestAnswer[q];
} else {
console.log(`❌ 错误题目: "${cleanedQ}" -> ${qTestAnswer[q]}`);
}
}
localStorage.removeItem(keyTestAnswer);
if (Object.keys(qRightAnswer).length > 0) {
localStorage.setItem(keyRightAnswer, JSON.stringify(qRightAnswer));
console.log("✅ 正确答案已保存:", qRightAnswer);
} else {
console.log("❌ 没有正确答案需要保存");
}
}
//答案记录函数区结束//
//------------------答案复制相关按钮--------------------------------------------
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")
//Aout=encodeURIComponent(Aout);
//window.prompt("请复制",Aout);
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;
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(textout);
}
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.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);
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
//答案复制相关按钮 end
function skipVideo() {//这是跳过视频的代码
var oVideo = document.getElementsByTagName('video')[0];
if (oVideo) {
oVideo.currentTime = oVideo.duration - 1
};
};
// 在 courseList 函数中添加导入答案按钮
function addImportAnswerBtn() {
let alink = document.createElement("a");
alink.innerHTML = '导入答案';
alink.style = btstyleB;
alink.onclick = function (event) {
var input = prompt("请粘贴要导入的答案数据(JSON格式)");
if (input) {
try {
// 解析输入的JSON数据
var importedAnswers = JSON.parse(input);
// 获取现有的答案记录
var existingAnswers = JSON.parse(localStorage.getItem(keyAllAnswer)) || {};
// 合并答案
var mergedAnswers = mergeAnswerData(existingAnswers, importedAnswers);
// 保存合并后的答案
localStorage.setItem(keyAllAnswer, JSON.stringify(mergedAnswers));
alert("✅ 答案导入成功!\n已合并 " + Object.keys(importedAnswers).length + " 个章节的答案");
} catch (error) {
alert("❌ 导入失败:数据格式不正确\n" + error);
}
}
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
// 合并答案数据的函数
function mergeAnswerData(existing, imported) {
// 深拷贝现有答案
var merged = JSON.parse(JSON.stringify(existing));
// 遍历导入的答案
for (var chapter in imported) {
if (imported.hasOwnProperty(chapter)) {
// 如果章节不存在,直接添加
if (!merged[chapter]) {
merged[chapter] = imported[chapter];
} else {
// 合并章节内的题目答案
for (var question in imported[chapter]) {
if (imported[chapter].hasOwnProperty(question)) {
merged[chapter][question] = imported[chapter][question];
}
}
}
}
}
return merged;
};
//------------------看视频页面主要函数-------------------------------------------
function clickexam() { //延时点击考试按钮。
console.log("已点击考试按钮");
setTimeout(function () {
var examButton = document.querySelector("#jrks");
if (examButton) {
examButton.click();
}
}, (Math.ceil(Math.random() * randomX)));
//}, (examTime + Math.ceil(Math.random() * randomX)));
};
//按钮插入函数相关
function addSkipbtn() {//插入按钮快进视频按钮
let alink = document.createElement("a");
alink.innerHTML = '快进视频';
alink.style = btstyleA;
alink.onclick = function (event) {
skipVideo();
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
};
function addratebtn(ra) {//倍率调整按钮
let alink = document.createElement("a");
alink.innerHTML = '' + ra + 'x';
alink.style = btstyleB;
alink.className = "speed";
alink.id = ra + "x";
alink.onclick = function (event) {
ratechg(ra);
try {
var arr = document.querySelectorAll("a[class='speed']");
arr.forEach(function (item, index, arr) {
arr[index].style = btstyleB;
});
} catch (error) {
};
alink.style = btstyleC;
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
}
function ratechg(ra) {//倍率调整
var videoObj = document.querySelector("video")
if (videoObj) {
try {
clearInterval(nspeed);
nspeed = setInterval(() => {
videoObj.playbackRate = ra;
}, 1 * 1000);
localStorage.setItem(keyPlayRate, ra);
//document.querySelector("a[id=" + "'" + ra + "x']").style = btstyleC;
//document.getElementById("playrate").innerHTML = "当前播放速率" + ra + "x";
//console.log("倍率调整为" + ra);
} catch (error) { console.log("倍率调整错误" + error); };
}
};
function addrateinfo() {//插入说明
let adiv1 = document.createElement("div");
adiv1.innerHTML = '当前播放速率';
adiv1.id = 'playrate';
adiv1.style = "font-size: 15px;text-align: center;margin-top: 10px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv1);
}
};
function addinfo() {//插入说明
//模式切换按钮
var moderesult = localStorage.getItem("华医mode");
if (moderesult == 2) {
moderesult = "当前模式:视频+考试";
} else {//包括了结果为1或者无存储的情况
moderesult = "当前模式:单刷视频";
};
var checkbox = document.createElement('div');
checkbox.innerHTML = '' + moderesult + '
[点击此处切换] ';
// 添加到页面的 body 元素中
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(checkbox);
}
//插入说明部分
let mode1 = document.querySelector("a[id='mode']");
if (mode1) {
mode1.onclick = function () {
if (mode1.innerText == "当前模式:单刷视频\n[点击此处切换]") {
mode1.innerText = "当前模式:视频+考试\n[点击此处切换]";
localStorage.setItem("华医mode", "2");
} else {
mode1.innerText = "当前模式:单刷视频\n[点击此处切换]";
localStorage.setItem("华医mode", "1");
};
};
}
let adiv2 = document.createElement("div");
adiv2.innerHTML = '       本人医学研一学生,经常要帮师兄师姐刷华医视频,属实太累。偶然在抖音发现Dr.S的脚本,结果刷完1个视频立刻考试,导致频繁人脸识别跟手动区别不大。原作者已不更新,于是我自学修改了播放逻辑,实现无人值守连续播放。现将原先自用的脚本分享给大家❤❤
     刷完视频再切换考试模式,即可连续考试。
';
adiv2.id = 'jsinfo';
adiv2.style = "position:relative;left:10px;top:5px;width:240px;font-size:13px;text-align: justify;border: 1px dashed #ff9595;padding:5px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv2);
}
if (typeof $ !== 'undefined') {
$('div:contains("观看视频完成后,才能进入考试")').eq(-1).text('建议360安全浏览器和脚本猫');
}
// 创建连续考试按钮的容器
let examBtnContainer = document.createElement('div');
examBtnContainer.id = 'continuousExamBtnContainer';
examBtnContainer.style = "text-align: center; margin: 10px 0;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(examBtnContainer);
}
};
function changelayout() {
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv) {
jjDiv.remove();
}
var photoImg = document.querySelector("img[id='photo']");
if (photoImg) {
photoImg.outerHTML = `
`;
photoImg.style.width = "120px";
photoImg.style.height = "120px";
}
var titleDivs = document.querySelectorAll("div[class='title']");
if (titleDivs[0] && titleDivs[0].children[0]) {
titleDivs[0].children[0].style = "color: #ff0000;font-weight: bold";
titleDivs[0].children[0].innerText = "支持作者";
}
var imgTextDivs = document.querySelector("div[class='imgtext']");
if (imgTextDivs && imgTextDivs.children[1]) {
imgTextDivs.children[1].style.width = "125px";
imgTextDivs.children[1].style = "color: #ff0000;padding-top:10px";
imgTextDivs.children[1].innerText = "作 者\n创作优化不易\n投点小费吧\n❤谢啦❤\n❤"
}
var topDiv = document.querySelector("div[class='top']");
if (topDiv) {
topDiv.outerHTML = '如服务器调整,脚本可能失效。反馈意见、免费增加课程请在Greasyfork私信或脚本反馈区联络。也欢迎投喂↓
';
}
};
function cleanKeyStorage() {//缓存清理
localStorage.removeItem(keyTest);
localStorage.removeItem(keyResult);
localStorage.removeItem(keyTestAnswer);
localStorage.removeItem(keyRightAnswer);
};
function examherftest() {//考试按钮激活状态检测
var examButton = document.getElementById("jrks");
var hreftest = examButton ? examButton.attributes["disabled"] : null;
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if ((state == "已完成" || state == "待考试" || !hreftest) && examButton) {//value不为#说明考试按钮已经激活
console.log("已经播放完了");
// 优先处理"视频+考试"模式下的"待考试"状态
var modeElement = document.querySelector("a[id='mode']");
if (modeElement && modeElement.innerText.indexOf("视频+考试") != -1 && state == "待考试") {
console.log("mode=2,准备进入考试");
// 重试机制:尝试5次进入考试
var retryCount = 0;
var maxRetries = 5;
function tryEnterExam() {
retryCount++;
console.log(`尝试进入考试 (第${retryCount}次)`);
try {
// 方法1:尝试点击考试按钮
if (document.getElementById("jrks") && !document.getElementById("jrks").disabled) {
document.getElementById("jrks").click();
console.log("成功点击考试按钮");
return true; // 成功进入考试
}
// 方法2:尝试备用方式
if (typeof cwrid !== 'undefined') {
window.open("/pages/exam_tip.aspx?cwrid=" + cwrid, "_self");
console.log("尝试备用方式进入考试");
return true;
}
// 方法3:尝试通过URL跳转
var currentUrl = window.location.href;
if (currentUrl.includes("course_ware")) {
var examUrl = currentUrl.replace("course_ware/course_ware_", "pages/exam.aspx?cwid=")
.split("?")[0] + "?cwid=" + getUrlParam("cwid");
window.location.href = examUrl;
console.log("尝试通过URL跳转进入考试");
return true;
}
} catch (error) {
console.log(`第${retryCount}次尝试失败:`, error);
}
return false; // 进入考试失败
}
// 立即尝试第一次
if (tryEnterExam()) {
return; // 成功进入考试,直接返回
}
// 设置重试间隔
var retryInterval = setInterval(function () {
if (retryCount >= maxRetries) {
clearInterval(retryInterval);
console.log(`尝试${maxRetries}次进入考试均失败,继续听课`);
// 继续执行后续的跳转到下一个视频的逻辑
proceedToNextVideo();
} else if (tryEnterExam()) {
clearInterval(retryInterval); // 成功进入考试,停止重试
}
}, 2000); // 每2秒重试一次
} else {
// 单刷视频模式或非待考试状态,直接继续听课
proceedToNextVideo();
};
} else {//#代表考试按钮还没激活
//继续播放,无需任何操作
}
}
// 跳转到下一个视频的函数
function proceedToNextVideo() {
console.log('🚀 准备跳转到下一个视频...');
const nextCwid = getNextCourseCwid();
if (nextCwid) {
console.log(`✅ 确定跳转到课程: ${nextCwid.substring(0, 8)}...`);
console.log(`🌐 跳转URL: course_ware.aspx?cwid=${nextCwid}`);
// 延迟跳转,让用户有时间查看日志
setTimeout(() => {
console.log('⏩ 正在跳转...');
window.location.href = `course_ware.aspx?cwid=${nextCwid}`;
}, 2000);
} else {
console.log('❌ 没有找到可用的课程,尝试刷新页面');
setTimeout(() => {
console.log('🔄 正在刷新页面...');
window.location.reload();
}, 2000);
}
}
// 辅助函数:获取URL参数
function getUrlParam(name) {
var urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
};
//课堂问答跳过,临时版
function sleep(timeout) {
return new Promise((resolve) => { setTimeout(resolve, timeout); });
console.log("课堂问答循环调用");
};
function asynckillsendQuestion() {
(async function () {
while (!window.player || !window.player.sendQuestion) {
await sleep(20);
};
//console.log("课堂问答跳过插入");
player.sendQuestion = function () {
//console.log("播放器尝试弹出课堂问答,已屏蔽。");
};
})();
};
function killsendQuestion2() {
if (typeof (isInteraction) == "undefined") {
//console.log('变量未定义');
} else {
console.log('isInteraction设置off');
isInteraction = "off";
};
};
function killsendQuestion3() { //点击跳过按钮版的跳过课堂答题
var clockms = setInterval(async function () {
try {
if (typeof $ !== 'undefined' && $('.pv-ask-head').length && $('.pv-ask-head').length > 0) {
console.log("检测到问题对话框,尝试跳过");
$(".pv-ask-skip").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.signBtn').length && $('.signBtn').length > 0) {
console.log("检测到签到对话框,尝试跳过");
$(".signBtn").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' &&
$("button[onclick='closeProcessbarTip()']").length &&
$("button[onclick='closeProcessbarTip()']").length > 0 &&
$("div[id='div_processbar_tip']").css("display") == "block") {
console.log("检测到温馨提示对话框(不能拖拽),尝试跳过");//
//*[@id="div_processbar_tip"]/div/div[2]/input
//document.querySelector("#div_processbar_tip > div > div.foot_sub > input")
//#div_processbar_tip > div > div.foot_sub > input
//
$("button[onclick='closeBangZhu()']").click();
$("button[onclick='closeProcessbarTip()']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $("button[class='btn_sign']").length && $("button[class='btn_sign']").length > 0) {
console.log("检测到温馨提示对话框(疲劳提醒),尝试跳过");
$("button[class='btn_sign']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.rig_btn').length && $('.rig_btn').length > 0) {
if ($('#div_processbar_tip').is(':visible')) {
console.log("检测到按钮(知道了),执行隐藏操作");
$('#div_processbar_tip').hide();
}
//$(".rig_btn").click();
};
} catch (err) {
console.log(err);
};
try {
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if (typeof $ !== 'undefined' &&
$('video').prop('paused') == true &&
state != "已完成" &&
state != "待考试") {
console.log("视频意外暂停,恢复播放");
$('video').get(0).play();
//$('video').prop('volumed') = 0;
$('video').prop('muted') = true;
} else if (state == "已完成") {
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.pause();
}
//clearInterval(clockms);
};
} catch (err) {
//console.log(err);
};
}, 10000);
};
function autoClickKnowButton() {
// 检测按钮是否加载完成
const observer = new MutationObserver(() => {
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
observer.disconnect(); // 停止观察
button.click(); // 点击按钮
}
});
// 开始观察文档的变化
observer.observe(document.body, {
childList: true,
subtree: true
});
// 如果按钮已经加载完成,直接点击
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
button.click();
}
}
// 在全局函数区添加以下函数
function saveCourseList() {
console.log('📋 开始保存/更新课程列表...');
// 尝试获取课程列表容器
const courseContainer = document.querySelector('.page-container');
if (!courseContainer) {
console.log('❌ 未找到课程列表容器');
return;
}
// 尝试获取课程项
const courseItems = document.querySelectorAll('.lis-inside-content');
if (courseItems.length === 0) {
console.log('❌ 未找到课程项');
return;
}
console.log(`📚 找到 ${courseItems.length} 个课程项,开始解析...`);
const currentCourseList = [];
let hasChanges = false;
courseItems.forEach((item, index) => {
const titleElement = item.querySelector('h2');
const statusButton = item.querySelector('button');
if (titleElement && statusButton) {
const title = titleElement.textContent.trim();
const status = statusButton.textContent.trim();
const statusColor = statusButton.style.background;
// 从onclick属性中提取cwid
const onclickAttr = titleElement.getAttribute('onclick');
let cwid = '';
if (onclickAttr) {
const match = onclickAttr.match(/cwid=([^']+)/);
if (match && match[1]) {
cwid = match[1];
}
}
if (cwid) {
currentCourseList.push({
title,
status,
statusColor,
cwid,
index
});
//console.log(` 课程 ${index + 1}: "${title}" - 状态: ${status}`);
}
}
});
if (currentCourseList.length === 0) {
console.log('❌ 未解析到任何课程信息');
return;
}
// 获取之前保存的课程列表
const previousCourseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
if (previousCourseList.length === 0) {
// 第一次保存
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`✅ 首次保存课程列表完成,共 ${currentCourseList.length} 个课程`);
return;
}
// 检查是否有变化
console.log('🔍 检查课程状态变化...');
for (let i = 0; i < currentCourseList.length; i++) {
const currentCourse=currentCourseList[i];
const previousCourse=previousCourseList[i];
if (!previousCourse) {
console.log(` 新增课程: "${currentCourse.title}" `);
hasChanges=true;
continue;
}
// 检查状态变化
if (currentCourse.status !==previousCourse.status) {
console.log(` 状态变化: "${currentCourse.title}" - ${previousCourse.status} → ${currentCourse.status}`);
hasChanges=true;
}
// 检查标题变化(可能课程有更新)
if (currentCourse.title !==previousCourse.title) {
console.log(` 标题变化: "${previousCourse.title}" → "${currentCourse.title}" `);
hasChanges=true;
}
// 检查cwid变化(理论上不应该变)
if (currentCourse.cwid !==previousCourse.cwid) {
console.log(` cwid变化: "${currentCourse.title}" `);
hasChanges=true;
}
}
// 检查课程数量变化
if (currentCourseList.length !==previousCourseList.length) {
console.log(` 课程数量变化: ${previousCourseList.length} → ${currentCourseList.length}`);
hasChanges=true;
}
if (hasChanges) {
// 更新课程列表
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`🔄 课程列表已更新,共 ${currentCourseList.length} 个课程`);
// 输出详细的课程状态
console.log('📊 当前所有课程状态:');
currentCourseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
} else {
console.log('✅ 课程列表无变化,无需更新');
// 即使无变化,也确保本地存储的是最新数据(防止数据损坏)
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
}
}
function getCurrentCourseCwid() {
// 从当前URL获取cwid
const urlParams = new URLSearchParams(window.location.search);
const cwid = urlParams.get('cwid');
console.log(`🔍 当前课程 cwid: ${cwid ? cwid.substring(0, 8) + '...' : '未找到'}`);
return cwid;
}
function getNextCourseCwid() {
console.log('🔄 开始查找下一个课程...');
// 尝试从localStorage获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
const currentCwid = getCurrentCourseCwid();
if (courseList.length === 0) {
console.log('❌ 未找到存储的课程列表');
return null;
}
console.log(`📊 课程列表中有 ${courseList.length} 个课程`);
// 找到当前课程的索引
const currentIndex = courseList.findIndex(course => course.cwid === currentCwid);
if (currentIndex === -1) {
console.log('❌ 未找到当前课程在列表中的位置');
console.log('当前课程可能不在列表中,将尝试第一个未完成的课程');
// 尝试查找第一个未完成的课程
for (let i = 0; i < courseList.length; i++) {
const course=courseList[i];
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到第一个未完成课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
return null;
}
console.log(`📍 当前课程位置: 第 ${currentIndex + 1} 个 - "${courseList[currentIndex].title}" `);
// 查找下一个未完成的课程(从当前位置向后找)
console.log('🔍 向后查找未完成的课程...');
for (let i=currentIndex + 1; i < courseList.length; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到下一个课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
// 如果后面没有未完成的课程,尝试从开头查找
console.log('🔍 向后未找到,从开头查找未完成的课程...');
for (let i=0; i < currentIndex; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到前面的课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
console.log('所有课程状态:');
courseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
return null;
}
//--------------------------插入悬浮框------------------------------------//
function advis() {
// 🔴 第一步:只在顶层窗口运行,iframe 中直接退出
if (window.self !== window.top) {
console.log('小助手:当前处于 iframe 中,不创建面板');
return;
}
// 🔴 第二步:检查是否已有面板,防止重复创建(即使脚本多次调用)
const existingPanel = document.getElementById('Div1');
if (existingPanel) {
console.log('已检测到小助手面板,防止重复创建');
return; // 或者 existingPanel.remove(); 再创建(推荐 return 即可)
}
// 🟡 第三步:创建新面板
let div1 = document.createElement("div");
div1.innerHTML = `
`;
document.body.append(div1);
// 绑定事件
let share1 = document.getElementById('Share1');
let share2 = document.getElementById('Share2');
let clo = document.getElementById('clo');
if (share1) {
share1.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/500010", "_blank");
};
}
if (share2) {
share2.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/555651", "_blank");
};
}
if (clo) {
clo.onclick = function () {
var panel = document.getElementById('Div1');
if (panel) {
panel.style.display = 'none';
}
};
}
// === 初始化:左对齐课程列表 ===
const panel = document.getElementById('Div1');
if (!panel) return;
const container = document.querySelector('.page-container') ||
document.querySelector('.lis-content') ||
document.querySelector('.container-inside-header');
let initialLeft = 140; // 默认值
if (container) {
const rect = container.getBoundingClientRect();
initialLeft = rect.left + window.pageXOffset;
}
panel.style.left = initialLeft + 'px';
// === 拖拽功能 ===
let isDragging = false;
let offsetX, offsetY;
panel.addEventListener('mousedown', function (e) {
if (e.target === clo ||
e.target.tagName === 'A' ||
e.target.tagName === 'IMG' ||
e.target.tagName === 'HR') return;
isDragging = true;
offsetX = e.clientX - panel.getBoundingClientRect().left;
offsetY = e.clientY - panel.getBoundingClientRect().top;
e.preventDefault();
});
document.addEventListener('mousemove', function (e) {
if (!isDragging) return;
panel.style.left = (e.clientX - offsetX) + 'px';
panel.style.top = (e.clientY - offsetY) + 'px';
});
document.addEventListener('mouseup', () => {
isDragging = false;
});
// 创建状态面板(默认隐藏)
//createStatusPanel();
//document.getElementById('examStatusPanel').style.display = 'none';
}
//--------------------------连续考试的函数------------------------------------//
// 修改 addContinuousExamButton 函数
function addContinuousExamButton() {
// 检查是否已存在连续考试按钮
if (document.getElementById('continuousExamBtn')) {
return;
}
// 创建连续考试按钮
let btn = document.createElement("a");
btn.innerHTML = '连续考试';
btn.style = btstyleA
btn.id = 'continuousExamBtn';
btn.onclick = function () {
console.log('🚀 开始连续考试流程...');
startContinuousExam();
};
// 找到建议提示框
const tipDiv = document.querySelector('div.r div[style*="border: 1px dashed #ff9595"]');
if (tipDiv) {
// 创建按钮容器
let btnContainer = document.createElement('div');
btnContainer.style = "text-align: center; margin: 10px 0;";
btnContainer.appendChild(btn);
// 将按钮容器插入到建议提示框后面
tipDiv.parentNode.insertBefore(btnContainer, tipDiv.nextSibling);
} else {
// 如果找不到建议提示框,使用预留的容器
const btnContainer = document.getElementById('continuousExamBtnContainer');
if (btnContainer) {
btnContainer.appendChild(btn);
} else {
// 如果容器也不存在,添加到页面底部
document.body.appendChild(btn);
}
}
}
// 新增:创建状态面板的函数
function createStatusPanel() {
// 检查是否存在 exam_phase
const examPhase = localStorage.getItem('exam_phase');
if (!examPhase) {
// 如果不存在 exam_phase,移除可能存在的面板
const existingPanel = document.getElementById('examStatusPanel');
if (existingPanel) {
existingPanel.remove();
}
return;
}
// 检查是否已存在状态面板
if (document.getElementById('examStatusPanel')) {
// 如果面板已存在,只需更新状态信息
updatePanelContent();
return;
}
// 创建状态面板
const panel = document.createElement('div');
panel.id = 'examStatusPanel';
panel.style = `
position: fixed;
top: 20px;
right: 20px;
width: 300px;
background-color: rgba(255, 255, 255, 0.95);
border: 2px solid #4cb0f9;
border-radius: 8px;
padding: 15px;
z-index: 10000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
font-family: 'Microsoft YaHei', sans-serif;
`;
panel.innerHTML = `
连续考试状态
加载中...
`;
// 确保面板正确插入到页面中
document.body.appendChild(panel);
// 添加取消按钮事件
var cancelBtn = document.getElementById('cancelExamBtn');
if (cancelBtn) {
cancelBtn.onclick = function () {
if (confirm('确定要取消连续考试吗?')) {
cancelContinuousExam();
}
};
}
// 更新面板内容
updatePanelContent();
// 辅助函数:更新面板内容
function updatePanelContent() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examPhase = localStorage.getItem('exam_phase');
let statusMessage = '';
if (examPhase === 'face_verification') {
statusMessage = `👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else if (examPhase === 'examination') {
statusMessage = `📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else {
statusMessage = '连续考试进行中...';
}
const contentElement = document.getElementById('examStatusContent');
if (contentElement) {
contentElement.innerHTML = statusMessage;
}
}
}
// 修改:更新状态提示的函数
function updateExamStatus(message, isError = false) {
createStatusPanel(); // 确保面板存在
const panel = document.getElementById('examStatusPanel');
// 添加存在性检查
if (!panel) {
console.log('状态面板不存在,跳过更新');
return;
}
panel.style.display = 'block';
const statusContent = document.getElementById('examStatusContent');
if (statusContent) {
statusContent.innerHTML = message;
statusContent.style.color = isError ? '#f15854' : '#333';
}
}
// 取消连续考试
function cancelContinuousExam() {
console.log('❌ 结束连续考试');
// 清除相关状态
localStorage.removeItem('exam_courses');
localStorage.removeItem('current_exam_index');
localStorage.removeItem('exam_phase');
// 只有在面板存在时才更新状态
const panel = document.getElementById('examStatusPanel');
if (panel) {
updateExamStatus('连续考试已取消');
// 3秒后隐藏状态面板
setTimeout(() => {
//panel.style.display = 'none';
}, 3000);
} else {
console.log('状态面板不存在,直接清除状态');
}
}
// 连续考试主函数
function startContinuousExam() {
// 强制设置为单刷视频模式,避免冲突
localStorage.setItem("华医mode", "1");
console.log('🚀 开始连续考试流程,模式强制设置为单刷视频');
localStorage.setItem('exam_phase', 'setup'); // 设置阶段为初始化
// 创建状态面板
createStatusPanel();
// 获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
// 筛选待考试的课程
const examCourses = courseList.filter(course => course.status === '待考试');
if (examCourses.length === 0) {
console.log('❌ 没有找到待考试的课程');
updateExamStatus('❌ 没有找到待考试的课程', true);
localStorage.removeItem('exam_phase');
return;
}
// 保存待考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
localStorage.setItem('exam_phase', 'face_verification'); // 设置阶段为刷脸
console.log(`📋 找到 ${examCourses.length} 个待考试课程`);
updateExamStatus(`找到 ${examCourses.length} 个待考试课程
准备开始刷脸流程...`);
// 开始刷脸流程
startFaceVerificationProcess();
}
// 刷脸流程
function startFaceVerificationProcess() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有课程刷脸完成,开始连续考试');
updateExamStatus('✅ 所有课程刷脸完成
开始连续考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startFaceVerificationProcess, 1000);
return;
}
console.log(`👤 开始第 ${currentIndex + 1} 个课程刷脸: ${currentCourse.title}`);
updateExamStatus(`👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开课程链接进行刷脸
window.location.href = `course_ware.aspx?cwid=${currentCourse.cwid}`;
}
// 监听页面加载,判断是否在刷脸后返回
function checkFaceVerificationReturn() {
const examPhase = localStorage.getItem('exam_phase');
const isInFaceVerification = examPhase === 'face_verification';
if (isInFaceVerification) {
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
// 只有当索引有效时才继续
if (currentIndex < examCourses.length) {
console.log('🔍 检测到刷脸后返回,继续下一个课程');
localStorage.setItem('current_exam_index', currentIndex + 1);
updateExamStatus(`✅ 刷脸完成 ${currentIndex + 1}/${examCourses.length}
准备下一个课程...`);
// 添加延迟防止过快跳转
setTimeout(startFaceVerificationProcess, 3000);
} else {
console.log('✅ 刷脸流程已完成');
updateExamStatus('✅ 刷脸流程已完成
准备开始考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
}
}
}
// 开始所有考试
function startAllExams() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
if (examCourses.length === 0) {
console.log('❌ 没有待考试的课程');
updateExamStatus('❌ 没有待考试的课程', true);
return;
}
console.log('🎯 开始连续考试流程');
updateExamStatus(`🎯 开始连续考试流程
共 ${examCourses.length} 个考试待完成`);
// 保存考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
// 开始第一个考试
startNextExam();
}
// 开始下一个考试
function startNextExam() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有考试完成!');
updateExamStatus('✅ 所有考试完成!
连续考试流程结束');
cancelContinuousExam();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startNextExam, 1000);
return;
}
console.log(`📝 开始第 ${currentIndex + 1} 个考试: ${currentCourse.title}`);
updateExamStatus(`📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开考试页面
window.location.href = `/pages/exam.aspx?cwid=${currentCourse.cwid}`;
}
// 在考试结果页面检查是否需要继续下一个考试
function checkExamContinuation() {
const examPhase = localStorage.getItem('exam_phase');
const isInExamMode = examPhase === 'examination';
if (isInExamMode) {
console.log('🔍 检测到考试完成,准备下一个考试');
// 增加索引
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
localStorage.setItem('current_exam_index', currentIndex + 1);
// 更新状态提示
updateExamStatus(`✅ 考试完成 ${currentIndex + 1}/${examCourses.length}
准备下一个考试...`);
// 短暂延迟后继续下一个考试
setTimeout(() => {
startNextExam();
}, 3000);
}
}
//---------------------------------全局函数区end------------------------------//
})();gwQOWPuloSKykYzlA6CZxbTEFRiWVVbcQ9nxyvmpirmdmlD/UAA/8MQzsAMGXECpceKpvAcHnEPEINwkLqIrLlf5pEMBIMA7PEM0YMAHJZwU/gM9gM97RAMuaNhMuM1JXVc+jJNT+IUnFgMJsMM6BCPVJeIrTiOBHdkFtIM+3Nc5xN4j7c35jQUR5MP0pcSfPU5JoYPctWLHpIOqOQCwfZ0ZHlECUiM9al3FXIc4NZx2zeMwiYNwrU8znIdTJIA63JA/HI4gwsReXGBNlMPmHV49RuSBqVimzAneIJkuZh5tOUszGKQ/oIPKNIXLhEmnxALdIGIy+shaHNfrSaRLnhmbvdsXYhBGbMqQfSR+NIXe1AhwzEX8vSRQBiXfGUk5kM84/xJMP1xAM6QTWXDAJjYFPoTHDT0DBjSTUF4lVrogdBhAMDQDBjhAkRzl2kCHsSDLHJ2DOoYEAZCUzpDAMEgOP2alXO4d6tkFMtSDO5SUKH4fBikJLBDWhIkD7PUDLBRkJPEDmaTlXC4mNyIHtIDJO1BA+LlYSCBDNPBkWSAAFL6I5XgjcLADLBgYY46mK6Ie59UDlfQEdK0RRhjAI8KMOpxAQsLEOdCVPEkLBYgmae4mGtZFc90Qk8ldX2KSJt2QO+hD4zVFOizlezyDO+SmYvKmdIranp2TdZUFBkwm9RwHfXghbSDHPzanH4VdXhRmmywYO1SYdk4ne3LdUqhFMP8ECZu0j26GFJuNQAJQQD4YQHShpJtdgHBVSZsU14s4Zh36xDpgiX+2J4PmHdXhQzDUAwLwgwjoA8JwZpoMg/kpWsWl5VBcgFTCDAnUUzKGRFRIKD+gw0nGZYO2qBo+HgHggwGcwDbuGVH8BQFwQDoNXTiJ3nV0JP34Q+SkJEiUQzsgwwno3g66KJOKGs2Ux5GMUxfOBNtYDgLAzYAqJlNQgEeWAJYUaIDE1Ho2KZmW4B+xzXk85Ez0VTsY5nuQx5imRFvY2OCtg8Ul44/dB8JEZ5n26VlVm19QjI3KxJ7dQ3GKhwPEaf50ILI8g2Sm3VJIR+p9IYv6qaX6HOu9FZ///kU5oMONsc/+cWJQKCXH4ZRsKipgaIkkFhGfXqqrThtvnAAhEYE6lIA+5CRnsgchsUMsDANyAuGrBquLVttHgAAuIAMu0ENWGN6ptcUsGIA+JIA4RJOwVmt7GmF3imV6wF+Ytqq1fusi6kXlRGkCvqc+Viq4pqv/AQuM8NxsrGQcqqu8YiX6tB6XoKr5DBg0kNyazau/XuWeAWo8hlSMxeu/HizCJqzCLizDNqzDPizERqzETizFVqzFXizGZqzGbizHdqzHfizIhqzIjizJlqzJnizKpqzKrizLtqzLvizMxqzMzizN1qzN3izO5qzO7izP9qzP/izQBq3QDi3RIhat0R4t0iat0i4t0zat0z4t1Eat1E4t1Vat1V4t1qJsQAAAOw==`;
var clock = null;
var testtest = true; //另一个可能会封号的功能,仅调试使用。
advis();
createStatusPanel(); //状态监视面板根据需要进行显示
// 修复错误:检查元素是否存在后再设置内容
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "当前网址已适配ヾ(๑╹◡╹)ノ"
失效请赞赏联系  ε(┬┬﹏┬┬)3";
}
if (urlTip == "course_ware_polyv.aspx") { //保利威播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(1);
} else if (urlTip == "course_ware_cc.aspx") { //CC播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(2);
} else if (urlTip == "face.aspx") { //刷脸
console.log("当前任务: 刷脸界面");
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "course.aspx" || urlTip == "cme.aspx") { //课程列表页面
console.log("当前任务: 课程列表");
huayi.courseList();
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "exam.aspx") { //考试页面
console.log("当前任务: 华医考试");
huayi.doTest();
} else if (urlTip == "exam_result.aspx") { //考试结果页面
console.log("当前任务: 华医考试结果审核");
huayi.doResult();
} else {
console.log("其它情况");
try {
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "此页面非视频、考试或未适配";
}
document.querySelector("img[id='Pic']").style.display = "block";
} catch (error) { };
};
function getHuayi() {
return {
courseList: function () {
addAnwserCopybtn();
addImportAnswerBtn();
DelAllAnwser();
},
seeVideo: function (e) {
var tr = localStorage.getItem(keyPlayRate);
//console.log("存储读取" + tr);//读取倍速
//var playRateNow = tr ? tr : vSpeed;
var playRateNow = 1;
cleanKeyStorage();
asynckillsendQuestion();//屏蔽课堂问答的函数;
killsendQuestion2();//屏蔽课堂问答的函数2;
killsendQuestion3(); //循环检测问答对话框是否弹出。
//addrateinfo();//插入一些按钮
//addratebtn(1);
//addratebtn(1.5);
//addratebtn(2);
//addSkipbtn();//跳过按钮
addinfo();//脚本信息
changelayout();
//速度调节部分
window.onload = function () {
localStorage.setItem(keyThisTitle, JSON.stringify(window.document.title));//储存章节标题
// console.log("准备激活加速");
ratechg(playRateNow);
if (autoSkip == true) {//秒过功能,已经不抵了,别尝试,没用的
setTimeout(function () {
skipVideo();
}, (submitTime + Math.ceil(Math.random() * randomX)));
console.log("秒过了!");
};
clock = setInterval(examherftest, 3000);//阿み杰此处要改11才能考试,循环法用examherftest检测考试按钮是否能点击
;
}
// 保存课程列表(每次都会检查并更新)
console.log('🎬 视频页面加载完成,开始保存/更新课程列表');
saveCourseList();
if (testtest) { addContinuousExamButton(); }// 添加连续考试按钮
// 检查是否是刷脸后返回
checkFaceVerificationReturn();
switch (e) {
case 1:
if (typeof window.s2j_onPlayerInitOver === 'function') {
window.s2j_onPlayerInitOver();
}
{
// 修复静音错误:先检查player对象是否存在
if (typeof player !== 'undefined' && player && player.j2s_setVolume) {
try {
player.j2s_setVolume(0);
console.log("保利威播放器静音成功");
} catch (error) {
console.log("保利威播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof player !== 'undefined' && player && player.j2s_resumeVideo) {
player.j2s_resumeVideo();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
killsendQuestion3();
break;
case 2:
if (typeof window.on_CCH5player_ready === 'function') {
window.on_CCH5player_ready();
}
{
// 修复静音错误:先检查cc_js_Player对象是否存在
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.setVolume) {
try {
cc_js_Player.setVolume(0);
console.log("CC播放器静音成功");
} catch (error) {
console.log("CC播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.play) {
cc_js_Player.play();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
break;
default:
console.log("其他播放器?");
};
},
doTest: function () {
var questions = JSON.parse(localStorage.getItem(keyTest)) || {};
var qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
if (JSON.stringify(qRightAnswer) == "{}") {
qRightAnswer = LoadRightAnwser();
};
var qTestAnswer = {};
var index = 0;
while (true) {
var question = document.querySelectorAll("table[class='tablestyle']")[index];
if (question == null) break;
else {
//var q = question.querySelector(".q_name").innerText.substring(2).replace(/\s*/g, "");//问题的具体文本
// 使用新的题目获取方式
var rawQuestion = question.querySelector(".q_name").innerText.substring(2);
var q = cleanQuestionText(rawQuestion);
console.log(q);
//thisQuestions=thisQuestions+q+"@"
if (qRightAnswer.hasOwnProperty(q)) { //当查询到记录了正确答案时的操作
//console.log("问题:"+ q + ",有答案:"+ qRightAnswer[q]);
var rightSelection = findAnwser("tbody", index, qRightAnswer[q]) //返回答案选项label
if (rightSelection) {
rightSelection.click();
}
} else {
if (questions.hasOwnProperty(q)) {
questions[q] = getNextChoice(questions[q]);//通过Unicode数字+1切换到下一个选项,返回的是字母选项
//console.log("不知道答案:"+ q+",测试:"+questions[q]);
} else { //如果系统没有记录
questions[q] = "A";
};
var answer = getChoiceCode(questions[q]);//将字母选项转换为Unicode数字并减去A代表的65,等于选项顺序,0是第一个选项
var element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
if (!element) { //选项除错机制
console.log("找不到选项,选项更改为A index: " + index + " answer: " + answer);
questions[q] = "A";
answer = getChoiceCode("A");
element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
//localStorage.removeItem(keyTest)
};
try {
var answerText = element.innerText.substring(3);//"A、"占用3个字符
//console.log("测试语法:" + (answerText == element.innerText.trim().substring(2)));
//element.nextSibling.innerText.trim().substring(2); //获得当前答案文本
qTestAnswer[q] = answerText;
//console.log("qTestAnswer:"+error);
} catch (error) { console.log("答案文本获取失败A:" + error); };
if (element) {
element.click();
}
};
index = index + 1;
};
};
//存储相关记录
localStorage.setItem(keyTest, JSON.stringify(questions));
localStorage.setItem(keyTestAnswer, JSON.stringify(qTestAnswer));
setTimeout(function () {
var submitButton = document.querySelector("#btn_submit");
if (submitButton) {
submitButton.click();
}
}, (submitTime + Math.ceil(Math.random() * randomX))); //交卷延时
///专用函数区
function findAnwser(qakey, index, rightAnwserText) {
var answerslist = document.querySelectorAll(qakey)[index];
if (!answerslist) return null;
var arr = answerslist.getElementsByTagName("label");
console.log(`查找答案: ${rightAnwserText}`);
// 精确匹配
for (var i = 0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText===rightAnwserText) {
console.log(`✅ 精确匹配: ${optionText}`);
return arr[i];
}
}
// 模糊匹配
for (var i=0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText.includes(rightAnwserText) || rightAnwserText.includes(optionText)) {
console.log(`🔍 模糊匹配: ${optionText}`);
return arr[i];
}
}
console.log(`❌ 未找到匹配答案,使用第一个选项`);
return arr[0];
}
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] ? $(".tips_text")[0].innerText : null;
var dds=$(".state_cour_lis");
localStorage.removeItem(keyResult);
if (res=="考试通过" || res=="考试通过!" || res=="完成项目学习可以申请学分了" ) {
console.log("考试通过");
saveRightAnwser();
SaveAllAnwser();
cleanKeyStorage();
checkExamContinuation();
setTimeout(function () {
// ...(原有代码)
}, 1000);
} else {
console.log("考试未通过")
var tipsTextElement=document.querySelector("p[class='tips_text' ]");
if (tipsTextElement) {
tipsTextElement.innerText="本次未通过,正在尝试更换答案\r\n(此为正常现象,脚本几秒后刷新,请勿操作)"
}
var qWrong={};
for (var i=0; i < dds.length; ++i) {
if (dds[i].querySelector("img") && !dds[i].querySelector("img").src.includes("bar_img")) {//这里表示否定
var rawQuestion=dds[i].querySelector("p").title;
var cleanedQuestion=cleanQuestionText(rawQuestion);
qWrong[cleanedQuestion]=i
};
};
if (qWrong !={}) {
localStorage.setItem(keyResult, JSON.stringify(qWrong));
saveRightAnwser();
setTimeout(function () {
$("input[type=button][value='重新考试' ]").click();
}, (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 qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) ||{};
var qTitle=JSON.parse(localStorage.getItem(keyThisTitle)) || "没有记录到章节名称" ;
if (qTitle=="没有记录到章节名称" ) {
console.log("没找到章节名称");
return {};
};
var qOldAnswer=qAllAnswer[qTitle] || {};
return qOldAnswer
};
// 修改题目处理逻辑,去除干扰的问号
// 统一的题目清洗函数
function cleanQuestionText(questionText) {
if (!questionText) return '' ;
// 去除各种特殊字符和空白
let cleaned=questionText
.replace(/[??]/g, '' )
.replace(/||[\u200B-\u200D\uFEFF]/g, '' ) // 去除零宽空格
.replace(/\s+/g, ' ' ) // 将多个空格合并为一个
.trim();
// 去除题目编号
cleaned=cleaned.replace(/^\d+、/, '' ).trim();
// 智能处理括号:
// 1. 只删除完全为空或只有空格的括号
// 2. 保留包含实际内容的括号
cleaned=cleaned.replace(/[((]\s*[))]/g, '' ) // 处理空括号
.replace(/[((]\s*([^))\s]+)\s*[))]/g, '$1' ) // 保留括号内的内容
.trim();
return cleaned;
}
// 修改题目获取方式,确保一致性
function getQuestionText(questionElement) {
try {
let rawText=questionElement.querySelector(".q_name").innerText;
// 去除编号部分(如"1、")
let textWithoutNumber=rawText.replace(/^\d+、/, '' );
return cleanQuestionText(textWithoutNumber);
} catch (error) {
console.log("获取题目文本错误:", error);
return "" ;
}
}
// 修改答案记录部分
function saveRightAnwser() {
var qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
var qTestAnswer=JSON.parse(localStorage.getItem(keyTestAnswer)) || {};
var qWrongs=JSON.parse(localStorage.getItem(keyResult)) || {};
console.log("开始保存正确答案...");
console.log("错题记录:", qWrongs);
console.log("测试答案:", qTestAnswer);
// 构建清理后的题目映射
var cleanedWrongs={};
for (var wrongQ in qWrongs) {
var cleanedWrongQ=cleanQuestionText(wrongQ);
cleanedWrongs[cleanedWrongQ]=true;
console.log(`错题清洗: "${wrongQ}" -> "${cleanedWrongQ}"`);
}
for (var q in qTestAnswer) {
var cleanedQ = cleanQuestionText(q);
console.log(`处理题目: "${q}" -> "${cleanedQ}", 答案: ${qTestAnswer[q]}`);
if (!cleanedWrongs[cleanedQ]) {
console.log(`✅ 正确答案: "${cleanedQ}" -> ${qTestAnswer[q]}`);
qRightAnswer[cleanedQ] = qTestAnswer[q];
} else {
console.log(`❌ 错误题目: "${cleanedQ}" -> ${qTestAnswer[q]}`);
}
}
localStorage.removeItem(keyTestAnswer);
if (Object.keys(qRightAnswer).length > 0) {
localStorage.setItem(keyRightAnswer, JSON.stringify(qRightAnswer));
console.log("✅ 正确答案已保存:", qRightAnswer);
} else {
console.log("❌ 没有正确答案需要保存");
}
}
//答案记录函数区结束//
//------------------答案复制相关按钮--------------------------------------------
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")
//Aout=encodeURIComponent(Aout);
//window.prompt("请复制",Aout);
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;
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(textout);
}
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.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);
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
//答案复制相关按钮 end
function skipVideo() {//这是跳过视频的代码
var oVideo = document.getElementsByTagName('video')[0];
if (oVideo) {
oVideo.currentTime = oVideo.duration - 1
};
};
// 在 courseList 函数中添加导入答案按钮
function addImportAnswerBtn() {
let alink = document.createElement("a");
alink.innerHTML = '导入答案';
alink.style = btstyleB;
alink.onclick = function (event) {
var input = prompt("请粘贴要导入的答案数据(JSON格式)");
if (input) {
try {
// 解析输入的JSON数据
var importedAnswers = JSON.parse(input);
// 获取现有的答案记录
var existingAnswers = JSON.parse(localStorage.getItem(keyAllAnswer)) || {};
// 合并答案
var mergedAnswers = mergeAnswerData(existingAnswers, importedAnswers);
// 保存合并后的答案
localStorage.setItem(keyAllAnswer, JSON.stringify(mergedAnswers));
alert("✅ 答案导入成功!\n已合并 " + Object.keys(importedAnswers).length + " 个章节的答案");
} catch (error) {
alert("❌ 导入失败:数据格式不正确\n" + error);
}
}
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
// 合并答案数据的函数
function mergeAnswerData(existing, imported) {
// 深拷贝现有答案
var merged = JSON.parse(JSON.stringify(existing));
// 遍历导入的答案
for (var chapter in imported) {
if (imported.hasOwnProperty(chapter)) {
// 如果章节不存在,直接添加
if (!merged[chapter]) {
merged[chapter] = imported[chapter];
} else {
// 合并章节内的题目答案
for (var question in imported[chapter]) {
if (imported[chapter].hasOwnProperty(question)) {
merged[chapter][question] = imported[chapter][question];
}
}
}
}
}
return merged;
};
//------------------看视频页面主要函数-------------------------------------------
function clickexam() { //延时点击考试按钮。
console.log("已点击考试按钮");
setTimeout(function () {
var examButton = document.querySelector("#jrks");
if (examButton) {
examButton.click();
}
}, (Math.ceil(Math.random() * randomX)));
//}, (examTime + Math.ceil(Math.random() * randomX)));
};
//按钮插入函数相关
function addSkipbtn() {//插入按钮快进视频按钮
let alink = document.createElement("a");
alink.innerHTML = '快进视频';
alink.style = btstyleA;
alink.onclick = function (event) {
skipVideo();
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
};
function addratebtn(ra) {//倍率调整按钮
let alink = document.createElement("a");
alink.innerHTML = '' + ra + 'x';
alink.style = btstyleB;
alink.className = "speed";
alink.id = ra + "x";
alink.onclick = function (event) {
ratechg(ra);
try {
var arr = document.querySelectorAll("a[class='speed']");
arr.forEach(function (item, index, arr) {
arr[index].style = btstyleB;
});
} catch (error) {
};
alink.style = btstyleC;
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
}
function ratechg(ra) {//倍率调整
var videoObj = document.querySelector("video")
if (videoObj) {
try {
clearInterval(nspeed);
nspeed = setInterval(() => {
videoObj.playbackRate = ra;
}, 1 * 1000);
localStorage.setItem(keyPlayRate, ra);
//document.querySelector("a[id=" + "'" + ra + "x']").style = btstyleC;
//document.getElementById("playrate").innerHTML = "当前播放速率" + ra + "x";
//console.log("倍率调整为" + ra);
} catch (error) { console.log("倍率调整错误" + error); };
}
};
function addrateinfo() {//插入说明
let adiv1 = document.createElement("div");
adiv1.innerHTML = '当前播放速率';
adiv1.id = 'playrate';
adiv1.style = "font-size: 15px;text-align: center;margin-top: 10px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv1);
}
};
function addinfo() {//插入说明
//模式切换按钮
var moderesult = localStorage.getItem("华医mode");
if (moderesult == 2) {
moderesult = "当前模式:视频+考试";
} else {//包括了结果为1或者无存储的情况
moderesult = "当前模式:单刷视频";
};
var checkbox = document.createElement('div');
checkbox.innerHTML = '' + moderesult + '
[点击此处切换] ';
// 添加到页面的 body 元素中
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(checkbox);
}
//插入说明部分
let mode1 = document.querySelector("a[id='mode']");
if (mode1) {
mode1.onclick = function () {
if (mode1.innerText == "当前模式:单刷视频\n[点击此处切换]") {
mode1.innerText = "当前模式:视频+考试\n[点击此处切换]";
localStorage.setItem("华医mode", "2");
} else {
mode1.innerText = "当前模式:单刷视频\n[点击此处切换]";
localStorage.setItem("华医mode", "1");
};
};
}
let adiv2 = document.createElement("div");
adiv2.innerHTML = '       本人医学研一学生,经常要帮师兄师姐刷华医视频,属实太累。偶然在抖音发现Dr.S的脚本,结果刷完1个视频立刻考试,导致频繁人脸识别跟手动区别不大。原作者已不更新,于是我自学修改了播放逻辑,实现无人值守连续播放。现将原先自用的脚本分享给大家❤❤
     刷完视频再切换考试模式,即可连续考试。
';
adiv2.id = 'jsinfo';
adiv2.style = "position:relative;left:10px;top:5px;width:240px;font-size:13px;text-align: justify;border: 1px dashed #ff9595;padding:5px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv2);
}
if (typeof $ !== 'undefined') {
$('div:contains("观看视频完成后,才能进入考试")').eq(-1).text('建议360安全浏览器和脚本猫');
}
// 创建连续考试按钮的容器
let examBtnContainer = document.createElement('div');
examBtnContainer.id = 'continuousExamBtnContainer';
examBtnContainer.style = "text-align: center; margin: 10px 0;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(examBtnContainer);
}
};
function changelayout() {
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv) {
jjDiv.remove();
}
var photoImg = document.querySelector("img[id='photo']");
if (photoImg) {
photoImg.outerHTML = `
`;
photoImg.style.width = "120px";
photoImg.style.height = "120px";
}
var titleDivs = document.querySelectorAll("div[class='title']");
if (titleDivs[0] && titleDivs[0].children[0]) {
titleDivs[0].children[0].style = "color: #ff0000;font-weight: bold";
titleDivs[0].children[0].innerText = "支持作者";
}
var imgTextDivs = document.querySelector("div[class='imgtext']");
if (imgTextDivs && imgTextDivs.children[1]) {
imgTextDivs.children[1].style.width = "125px";
imgTextDivs.children[1].style = "color: #ff0000;padding-top:10px";
imgTextDivs.children[1].innerText = "作 者\n创作优化不易\n投点小费吧\n❤谢啦❤\n❤"
}
var topDiv = document.querySelector("div[class='top']");
if (topDiv) {
topDiv.outerHTML = '如服务器调整,脚本可能失效。反馈意见、免费增加课程请在Greasyfork私信或脚本反馈区联络。也欢迎投喂↓
';
}
};
function cleanKeyStorage() {//缓存清理
localStorage.removeItem(keyTest);
localStorage.removeItem(keyResult);
localStorage.removeItem(keyTestAnswer);
localStorage.removeItem(keyRightAnswer);
};
function examherftest() {//考试按钮激活状态检测
var examButton = document.getElementById("jrks");
var hreftest = examButton ? examButton.attributes["disabled"] : null;
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if ((state == "已完成" || state == "待考试" || !hreftest) && examButton) {//value不为#说明考试按钮已经激活
console.log("已经播放完了");
// 优先处理"视频+考试"模式下的"待考试"状态
var modeElement = document.querySelector("a[id='mode']");
if (modeElement && modeElement.innerText.indexOf("视频+考试") != -1 && state == "待考试") {
console.log("mode=2,准备进入考试");
// 重试机制:尝试5次进入考试
var retryCount = 0;
var maxRetries = 5;
function tryEnterExam() {
retryCount++;
console.log(`尝试进入考试 (第${retryCount}次)`);
try {
// 方法1:尝试点击考试按钮
if (document.getElementById("jrks") && !document.getElementById("jrks").disabled) {
document.getElementById("jrks").click();
console.log("成功点击考试按钮");
return true; // 成功进入考试
}
// 方法2:尝试备用方式
if (typeof cwrid !== 'undefined') {
window.open("/pages/exam_tip.aspx?cwrid=" + cwrid, "_self");
console.log("尝试备用方式进入考试");
return true;
}
// 方法3:尝试通过URL跳转
var currentUrl = window.location.href;
if (currentUrl.includes("course_ware")) {
var examUrl = currentUrl.replace("course_ware/course_ware_", "pages/exam.aspx?cwid=")
.split("?")[0] + "?cwid=" + getUrlParam("cwid");
window.location.href = examUrl;
console.log("尝试通过URL跳转进入考试");
return true;
}
} catch (error) {
console.log(`第${retryCount}次尝试失败:`, error);
}
return false; // 进入考试失败
}
// 立即尝试第一次
if (tryEnterExam()) {
return; // 成功进入考试,直接返回
}
// 设置重试间隔
var retryInterval = setInterval(function () {
if (retryCount >= maxRetries) {
clearInterval(retryInterval);
console.log(`尝试${maxRetries}次进入考试均失败,继续听课`);
// 继续执行后续的跳转到下一个视频的逻辑
proceedToNextVideo();
} else if (tryEnterExam()) {
clearInterval(retryInterval); // 成功进入考试,停止重试
}
}, 2000); // 每2秒重试一次
} else {
// 单刷视频模式或非待考试状态,直接继续听课
proceedToNextVideo();
};
} else {//#代表考试按钮还没激活
//继续播放,无需任何操作
}
}
// 跳转到下一个视频的函数
function proceedToNextVideo() {
console.log('🚀 准备跳转到下一个视频...');
const nextCwid = getNextCourseCwid();
if (nextCwid) {
console.log(`✅ 确定跳转到课程: ${nextCwid.substring(0, 8)}...`);
console.log(`🌐 跳转URL: course_ware.aspx?cwid=${nextCwid}`);
// 延迟跳转,让用户有时间查看日志
setTimeout(() => {
console.log('⏩ 正在跳转...');
window.location.href = `course_ware.aspx?cwid=${nextCwid}`;
}, 2000);
} else {
console.log('❌ 没有找到可用的课程,尝试刷新页面');
setTimeout(() => {
console.log('🔄 正在刷新页面...');
window.location.reload();
}, 2000);
}
}
// 辅助函数:获取URL参数
function getUrlParam(name) {
var urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
};
//课堂问答跳过,临时版
function sleep(timeout) {
return new Promise((resolve) => { setTimeout(resolve, timeout); });
console.log("课堂问答循环调用");
};
function asynckillsendQuestion() {
(async function () {
while (!window.player || !window.player.sendQuestion) {
await sleep(20);
};
//console.log("课堂问答跳过插入");
player.sendQuestion = function () {
//console.log("播放器尝试弹出课堂问答,已屏蔽。");
};
})();
};
function killsendQuestion2() {
if (typeof (isInteraction) == "undefined") {
//console.log('变量未定义');
} else {
console.log('isInteraction设置off');
isInteraction = "off";
};
};
function killsendQuestion3() { //点击跳过按钮版的跳过课堂答题
var clockms = setInterval(async function () {
try {
if (typeof $ !== 'undefined' && $('.pv-ask-head').length && $('.pv-ask-head').length > 0) {
console.log("检测到问题对话框,尝试跳过");
$(".pv-ask-skip").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.signBtn').length && $('.signBtn').length > 0) {
console.log("检测到签到对话框,尝试跳过");
$(".signBtn").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' &&
$("button[onclick='closeProcessbarTip()']").length &&
$("button[onclick='closeProcessbarTip()']").length > 0 &&
$("div[id='div_processbar_tip']").css("display") == "block") {
console.log("检测到温馨提示对话框(不能拖拽),尝试跳过");//
//*[@id="div_processbar_tip"]/div/div[2]/input
//document.querySelector("#div_processbar_tip > div > div.foot_sub > input")
//#div_processbar_tip > div > div.foot_sub > input
//
$("button[onclick='closeBangZhu()']").click();
$("button[onclick='closeProcessbarTip()']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $("button[class='btn_sign']").length && $("button[class='btn_sign']").length > 0) {
console.log("检测到温馨提示对话框(疲劳提醒),尝试跳过");
$("button[class='btn_sign']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.rig_btn').length && $('.rig_btn').length > 0) {
if ($('#div_processbar_tip').is(':visible')) {
console.log("检测到按钮(知道了),执行隐藏操作");
$('#div_processbar_tip').hide();
}
//$(".rig_btn").click();
};
} catch (err) {
console.log(err);
};
try {
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if (typeof $ !== 'undefined' &&
$('video').prop('paused') == true &&
state != "已完成" &&
state != "待考试") {
console.log("视频意外暂停,恢复播放");
$('video').get(0).play();
//$('video').prop('volumed') = 0;
$('video').prop('muted') = true;
} else if (state == "已完成") {
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.pause();
}
//clearInterval(clockms);
};
} catch (err) {
//console.log(err);
};
}, 10000);
};
function autoClickKnowButton() {
// 检测按钮是否加载完成
const observer = new MutationObserver(() => {
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
observer.disconnect(); // 停止观察
button.click(); // 点击按钮
}
});
// 开始观察文档的变化
observer.observe(document.body, {
childList: true,
subtree: true
});
// 如果按钮已经加载完成,直接点击
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
button.click();
}
}
// 在全局函数区添加以下函数
function saveCourseList() {
console.log('📋 开始保存/更新课程列表...');
// 尝试获取课程列表容器
const courseContainer = document.querySelector('.page-container');
if (!courseContainer) {
console.log('❌ 未找到课程列表容器');
return;
}
// 尝试获取课程项
const courseItems = document.querySelectorAll('.lis-inside-content');
if (courseItems.length === 0) {
console.log('❌ 未找到课程项');
return;
}
console.log(`📚 找到 ${courseItems.length} 个课程项,开始解析...`);
const currentCourseList = [];
let hasChanges = false;
courseItems.forEach((item, index) => {
const titleElement = item.querySelector('h2');
const statusButton = item.querySelector('button');
if (titleElement && statusButton) {
const title = titleElement.textContent.trim();
const status = statusButton.textContent.trim();
const statusColor = statusButton.style.background;
// 从onclick属性中提取cwid
const onclickAttr = titleElement.getAttribute('onclick');
let cwid = '';
if (onclickAttr) {
const match = onclickAttr.match(/cwid=([^']+)/);
if (match && match[1]) {
cwid = match[1];
}
}
if (cwid) {
currentCourseList.push({
title,
status,
statusColor,
cwid,
index
});
//console.log(` 课程 ${index + 1}: "${title}" - 状态: ${status}`);
}
}
});
if (currentCourseList.length === 0) {
console.log('❌ 未解析到任何课程信息');
return;
}
// 获取之前保存的课程列表
const previousCourseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
if (previousCourseList.length === 0) {
// 第一次保存
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`✅ 首次保存课程列表完成,共 ${currentCourseList.length} 个课程`);
return;
}
// 检查是否有变化
console.log('🔍 检查课程状态变化...');
for (let i = 0; i < currentCourseList.length; i++) {
const currentCourse=currentCourseList[i];
const previousCourse=previousCourseList[i];
if (!previousCourse) {
console.log(` 新增课程: "${currentCourse.title}" `);
hasChanges=true;
continue;
}
// 检查状态变化
if (currentCourse.status !==previousCourse.status) {
console.log(` 状态变化: "${currentCourse.title}" - ${previousCourse.status} → ${currentCourse.status}`);
hasChanges=true;
}
// 检查标题变化(可能课程有更新)
if (currentCourse.title !==previousCourse.title) {
console.log(` 标题变化: "${previousCourse.title}" → "${currentCourse.title}" `);
hasChanges=true;
}
// 检查cwid变化(理论上不应该变)
if (currentCourse.cwid !==previousCourse.cwid) {
console.log(` cwid变化: "${currentCourse.title}" `);
hasChanges=true;
}
}
// 检查课程数量变化
if (currentCourseList.length !==previousCourseList.length) {
console.log(` 课程数量变化: ${previousCourseList.length} → ${currentCourseList.length}`);
hasChanges=true;
}
if (hasChanges) {
// 更新课程列表
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`🔄 课程列表已更新,共 ${currentCourseList.length} 个课程`);
// 输出详细的课程状态
console.log('📊 当前所有课程状态:');
currentCourseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
} else {
console.log('✅ 课程列表无变化,无需更新');
// 即使无变化,也确保本地存储的是最新数据(防止数据损坏)
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
}
}
function getCurrentCourseCwid() {
// 从当前URL获取cwid
const urlParams = new URLSearchParams(window.location.search);
const cwid = urlParams.get('cwid');
console.log(`🔍 当前课程 cwid: ${cwid ? cwid.substring(0, 8) + '...' : '未找到'}`);
return cwid;
}
function getNextCourseCwid() {
console.log('🔄 开始查找下一个课程...');
// 尝试从localStorage获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
const currentCwid = getCurrentCourseCwid();
if (courseList.length === 0) {
console.log('❌ 未找到存储的课程列表');
return null;
}
console.log(`📊 课程列表中有 ${courseList.length} 个课程`);
// 找到当前课程的索引
const currentIndex = courseList.findIndex(course => course.cwid === currentCwid);
if (currentIndex === -1) {
console.log('❌ 未找到当前课程在列表中的位置');
console.log('当前课程可能不在列表中,将尝试第一个未完成的课程');
// 尝试查找第一个未完成的课程
for (let i = 0; i < courseList.length; i++) {
const course=courseList[i];
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到第一个未完成课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
return null;
}
console.log(`📍 当前课程位置: 第 ${currentIndex + 1} 个 - "${courseList[currentIndex].title}" `);
// 查找下一个未完成的课程(从当前位置向后找)
console.log('🔍 向后查找未完成的课程...');
for (let i=currentIndex + 1; i < courseList.length; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到下一个课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
// 如果后面没有未完成的课程,尝试从开头查找
console.log('🔍 向后未找到,从开头查找未完成的课程...');
for (let i=0; i < currentIndex; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到前面的课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
console.log('所有课程状态:');
courseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
return null;
}
//--------------------------插入悬浮框------------------------------------//
function advis() {
// 🔴 第一步:只在顶层窗口运行,iframe 中直接退出
if (window.self !== window.top) {
console.log('小助手:当前处于 iframe 中,不创建面板');
return;
}
// 🔴 第二步:检查是否已有面板,防止重复创建(即使脚本多次调用)
const existingPanel = document.getElementById('Div1');
if (existingPanel) {
console.log('已检测到小助手面板,防止重复创建');
return; // 或者 existingPanel.remove(); 再创建(推荐 return 即可)
}
// 🟡 第三步:创建新面板
let div1 = document.createElement("div");
div1.innerHTML = `
`;
document.body.append(div1);
// 绑定事件
let share1 = document.getElementById('Share1');
let share2 = document.getElementById('Share2');
let clo = document.getElementById('clo');
if (share1) {
share1.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/500010", "_blank");
};
}
if (share2) {
share2.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/555651", "_blank");
};
}
if (clo) {
clo.onclick = function () {
var panel = document.getElementById('Div1');
if (panel) {
panel.style.display = 'none';
}
};
}
// === 初始化:左对齐课程列表 ===
const panel = document.getElementById('Div1');
if (!panel) return;
const container = document.querySelector('.page-container') ||
document.querySelector('.lis-content') ||
document.querySelector('.container-inside-header');
let initialLeft = 140; // 默认值
if (container) {
const rect = container.getBoundingClientRect();
initialLeft = rect.left + window.pageXOffset;
}
panel.style.left = initialLeft + 'px';
// === 拖拽功能 ===
let isDragging = false;
let offsetX, offsetY;
panel.addEventListener('mousedown', function (e) {
if (e.target === clo ||
e.target.tagName === 'A' ||
e.target.tagName === 'IMG' ||
e.target.tagName === 'HR') return;
isDragging = true;
offsetX = e.clientX - panel.getBoundingClientRect().left;
offsetY = e.clientY - panel.getBoundingClientRect().top;
e.preventDefault();
});
document.addEventListener('mousemove', function (e) {
if (!isDragging) return;
panel.style.left = (e.clientX - offsetX) + 'px';
panel.style.top = (e.clientY - offsetY) + 'px';
});
document.addEventListener('mouseup', () => {
isDragging = false;
});
// 创建状态面板(默认隐藏)
//createStatusPanel();
//document.getElementById('examStatusPanel').style.display = 'none';
}
//--------------------------连续考试的函数------------------------------------//
// 修改 addContinuousExamButton 函数
function addContinuousExamButton() {
// 检查是否已存在连续考试按钮
if (document.getElementById('continuousExamBtn')) {
return;
}
// 创建连续考试按钮
let btn = document.createElement("a");
btn.innerHTML = '连续考试';
btn.style = btstyleA
btn.id = 'continuousExamBtn';
btn.onclick = function () {
console.log('🚀 开始连续考试流程...');
startContinuousExam();
};
// 找到建议提示框
const tipDiv = document.querySelector('div.r div[style*="border: 1px dashed #ff9595"]');
if (tipDiv) {
// 创建按钮容器
let btnContainer = document.createElement('div');
btnContainer.style = "text-align: center; margin: 10px 0;";
btnContainer.appendChild(btn);
// 将按钮容器插入到建议提示框后面
tipDiv.parentNode.insertBefore(btnContainer, tipDiv.nextSibling);
} else {
// 如果找不到建议提示框,使用预留的容器
const btnContainer = document.getElementById('continuousExamBtnContainer');
if (btnContainer) {
btnContainer.appendChild(btn);
} else {
// 如果容器也不存在,添加到页面底部
document.body.appendChild(btn);
}
}
}
// 新增:创建状态面板的函数
function createStatusPanel() {
// 检查是否存在 exam_phase
const examPhase = localStorage.getItem('exam_phase');
if (!examPhase) {
// 如果不存在 exam_phase,移除可能存在的面板
const existingPanel = document.getElementById('examStatusPanel');
if (existingPanel) {
existingPanel.remove();
}
return;
}
// 检查是否已存在状态面板
if (document.getElementById('examStatusPanel')) {
// 如果面板已存在,只需更新状态信息
updatePanelContent();
return;
}
// 创建状态面板
const panel = document.createElement('div');
panel.id = 'examStatusPanel';
panel.style = `
position: fixed;
top: 20px;
right: 20px;
width: 300px;
background-color: rgba(255, 255, 255, 0.95);
border: 2px solid #4cb0f9;
border-radius: 8px;
padding: 15px;
z-index: 10000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
font-family: 'Microsoft YaHei', sans-serif;
`;
panel.innerHTML = `
连续考试状态
加载中...
`;
// 确保面板正确插入到页面中
document.body.appendChild(panel);
// 添加取消按钮事件
var cancelBtn = document.getElementById('cancelExamBtn');
if (cancelBtn) {
cancelBtn.onclick = function () {
if (confirm('确定要取消连续考试吗?')) {
cancelContinuousExam();
}
};
}
// 更新面板内容
updatePanelContent();
// 辅助函数:更新面板内容
function updatePanelContent() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examPhase = localStorage.getItem('exam_phase');
let statusMessage = '';
if (examPhase === 'face_verification') {
statusMessage = `👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else if (examPhase === 'examination') {
statusMessage = `📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else {
statusMessage = '连续考试进行中...';
}
const contentElement = document.getElementById('examStatusContent');
if (contentElement) {
contentElement.innerHTML = statusMessage;
}
}
}
// 修改:更新状态提示的函数
function updateExamStatus(message, isError = false) {
createStatusPanel(); // 确保面板存在
const panel = document.getElementById('examStatusPanel');
// 添加存在性检查
if (!panel) {
console.log('状态面板不存在,跳过更新');
return;
}
panel.style.display = 'block';
const statusContent = document.getElementById('examStatusContent');
if (statusContent) {
statusContent.innerHTML = message;
statusContent.style.color = isError ? '#f15854' : '#333';
}
}
// 取消连续考试
function cancelContinuousExam() {
console.log('❌ 结束连续考试');
// 清除相关状态
localStorage.removeItem('exam_courses');
localStorage.removeItem('current_exam_index');
localStorage.removeItem('exam_phase');
// 只有在面板存在时才更新状态
const panel = document.getElementById('examStatusPanel');
if (panel) {
updateExamStatus('连续考试已取消');
// 3秒后隐藏状态面板
setTimeout(() => {
//panel.style.display = 'none';
}, 3000);
} else {
console.log('状态面板不存在,直接清除状态');
}
}
// 连续考试主函数
function startContinuousExam() {
// 强制设置为单刷视频模式,避免冲突
localStorage.setItem("华医mode", "1");
console.log('🚀 开始连续考试流程,模式强制设置为单刷视频');
localStorage.setItem('exam_phase', 'setup'); // 设置阶段为初始化
// 创建状态面板
createStatusPanel();
// 获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
// 筛选待考试的课程
const examCourses = courseList.filter(course => course.status === '待考试');
if (examCourses.length === 0) {
console.log('❌ 没有找到待考试的课程');
updateExamStatus('❌ 没有找到待考试的课程', true);
localStorage.removeItem('exam_phase');
return;
}
// 保存待考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
localStorage.setItem('exam_phase', 'face_verification'); // 设置阶段为刷脸
console.log(`📋 找到 ${examCourses.length} 个待考试课程`);
updateExamStatus(`找到 ${examCourses.length} 个待考试课程
准备开始刷脸流程...`);
// 开始刷脸流程
startFaceVerificationProcess();
}
// 刷脸流程
function startFaceVerificationProcess() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有课程刷脸完成,开始连续考试');
updateExamStatus('✅ 所有课程刷脸完成
开始连续考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startFaceVerificationProcess, 1000);
return;
}
console.log(`👤 开始第 ${currentIndex + 1} 个课程刷脸: ${currentCourse.title}`);
updateExamStatus(`👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开课程链接进行刷脸
window.location.href = `course_ware.aspx?cwid=${currentCourse.cwid}`;
}
// 监听页面加载,判断是否在刷脸后返回
function checkFaceVerificationReturn() {
const examPhase = localStorage.getItem('exam_phase');
const isInFaceVerification = examPhase === 'face_verification';
if (isInFaceVerification) {
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
// 只有当索引有效时才继续
if (currentIndex < examCourses.length) {
console.log('🔍 检测到刷脸后返回,继续下一个课程');
localStorage.setItem('current_exam_index', currentIndex + 1);
updateExamStatus(`✅ 刷脸完成 ${currentIndex + 1}/${examCourses.length}
准备下一个课程...`);
// 添加延迟防止过快跳转
setTimeout(startFaceVerificationProcess, 3000);
} else {
console.log('✅ 刷脸流程已完成');
updateExamStatus('✅ 刷脸流程已完成
准备开始考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
}
}
}
// 开始所有考试
function startAllExams() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
if (examCourses.length === 0) {
console.log('❌ 没有待考试的课程');
updateExamStatus('❌ 没有待考试的课程', true);
return;
}
console.log('🎯 开始连续考试流程');
updateExamStatus(`🎯 开始连续考试流程
共 ${examCourses.length} 个考试待完成`);
// 保存考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
// 开始第一个考试
startNextExam();
}
// 开始下一个考试
function startNextExam() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有考试完成!');
updateExamStatus('✅ 所有考试完成!
连续考试流程结束');
cancelContinuousExam();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startNextExam, 1000);
return;
}
console.log(`📝 开始第 ${currentIndex + 1} 个考试: ${currentCourse.title}`);
updateExamStatus(`📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开考试页面
window.location.href = `/pages/exam.aspx?cwid=${currentCourse.cwid}`;
}
// 在考试结果页面检查是否需要继续下一个考试
function checkExamContinuation() {
const examPhase = localStorage.getItem('exam_phase');
const isInExamMode = examPhase === 'examination';
if (isInExamMode) {
console.log('🔍 检测到考试完成,准备下一个考试');
// 增加索引
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
localStorage.setItem('current_exam_index', currentIndex + 1);
// 更新状态提示
updateExamStatus(`✅ 考试完成 ${currentIndex + 1}/${examCourses.length}
准备下一个考试...`);
// 短暂延迟后继续下一个考试
setTimeout(() => {
startNextExam();
}, 3000);
}
}
//---------------------------------全局函数区end------------------------------//
})();gwQOWPuloSKykYzlA6CZxbTEFRiWVVbcQ9nxyvmpirmdmlD/UAA/8MQzsAMGXECpceKpvAcHnEPEINwkLqIrLlf5pEMBIMA7PEM0YMAHJZwU/gM9gM97RAMuaNhMuM1JXVc+jJNT+IUnFgMJsMM6BCPVJeIrTiOBHdkFtIM+3Nc5xN4j7c35jQUR5MP0pcSfPU5JoYPctWLHpIOqOQCwfZ0ZHlECUiM9al3FXIc4NZx2zeMwiYNwrU8znIdTJIA63JA/HI4gwsReXGBNlMPmHV49RuSBqVimzAneIJkuZh5tOUszGKQ/oIPKNIXLhEmnxALdIGIy+shaHNfrSaRLnhmbvdsXYhBGbMqQfSR+NIXe1AhwzEX8vSRQBiXfGUk5kM84/xJMP1xAM6QTWXDAJjYFPoTHDT0DBjSTUF4lVrogdBhAMDQDBjhAkRzl2kCHsSDLHJ2DOoYEAZCUzpDAMEgOP2alXO4d6tkFMtSDO5SUKH4fBikJLBDWhIkD7PUDLBRkJPEDmaTlXC4mNyIHtIDJO1BA+LlYSCBDNPBkWSAAFL6I5XgjcLADLBgYY46mK6Ie59UDlfQEdK0RRhjAI8KMOpxAQsLEOdCVPEkLBYgmae4mGtZFc90Qk8ldX2KSJt2QO+hD4zVFOizlezyDO+SmYvKmdIranp2TdZUFBkwm9RwHfXghbSDHPzanH4VdXhRmmywYO1SYdk4ne3LdUqhFMP8ECZu0j26GFJuNQAJQQD4YQHShpJtdgHBVSZsU14s4Zh36xDpgiX+2J4PmHdXhQzDUAwLwgwjoA8JwZpoMg/kpWsWl5VBcgFTCDAnUUzKGRFRIKD+gw0nGZYO2qBo+HgHggwGcwDbuGVH8BQFwQDoNXTiJ3nV0JP34Q+SkJEiUQzsgwwno3g66KJOKGs2Ux5GMUxfOBNtYDgLAzYAqJlNQgEeWAJYUaIDE1Ho2KZmW4B+xzXk85Ez0VTsY5nuQx5imRFvY2OCtg8Ul44/dB8JEZ5n26VlVm19QjI3KxJ7dQ3GKhwPEaf50ILI8g2Sm3VJIR+p9IYv6qaX6HOu9FZ///kU5oMONsc/+cWJQKCXH4ZRsKipgaIkkFhGfXqqrThtvnAAhEYE6lIA+5CRnsgchsUMsDANyAuGrBquLVttHgAAuIAMu0ENWGN6ptcUsGIA+JIA4RJOwVmt7GmF3imV6wF+Ytqq1fusi6kXlRGkCvqc+Viq4pqv/AQuM8NxsrGQcqqu8YiX6tB6XoKr5DBg0kNyazau/XuWeAWo8hlSMxeu/HizCJqzCLizDNqzDPizERqzETizFVqzFXizGZqzGbizHdqzHfizIhqzIjizJlqzJnizKpqzKrizLtqzLvizMxqzMzizN1qzN3izO5qzO7izP9qzP/izQBq3QDi3RIhat0R4t0iat0i4t0zat0z4t1Eat1E4t1Vat1V4t1qJsQAAAOw==`;
var clock = null;
var testtest = true; //另一个可能会封号的功能,仅调试使用。
advis();
createStatusPanel(); //状态监视面板根据需要进行显示
// 修复错误:检查元素是否存在后再设置内容
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "当前网址已适配ヾ(๑╹◡╹)ノ"
失效请赞赏联系  ε(┬┬﹏┬┬)3";
}
if (urlTip == "course_ware_polyv.aspx") { //保利威播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(1);
} else if (urlTip == "course_ware_cc.aspx") { //CC播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(2);
} else if (urlTip == "face.aspx") { //刷脸
console.log("当前任务: 刷脸界面");
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "course.aspx" || urlTip == "cme.aspx") { //课程列表页面
console.log("当前任务: 课程列表");
huayi.courseList();
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "exam.aspx") { //考试页面
console.log("当前任务: 华医考试");
huayi.doTest();
} else if (urlTip == "exam_result.aspx") { //考试结果页面
console.log("当前任务: 华医考试结果审核");
huayi.doResult();
} else {
console.log("其它情况");
try {
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "此页面非视频、考试或未适配";
}
document.querySelector("img[id='Pic']").style.display = "block";
} catch (error) { };
};
function getHuayi() {
return {
courseList: function () {
addAnwserCopybtn();
addImportAnswerBtn();
DelAllAnwser();
},
seeVideo: function (e) {
var tr = localStorage.getItem(keyPlayRate);
//console.log("存储读取" + tr);//读取倍速
//var playRateNow = tr ? tr : vSpeed;
var playRateNow = 1;
cleanKeyStorage();
asynckillsendQuestion();//屏蔽课堂问答的函数;
killsendQuestion2();//屏蔽课堂问答的函数2;
killsendQuestion3(); //循环检测问答对话框是否弹出。
//addrateinfo();//插入一些按钮
//addratebtn(1);
//addratebtn(1.5);
//addratebtn(2);
//addSkipbtn();//跳过按钮
addinfo();//脚本信息
changelayout();
//速度调节部分
window.onload = function () {
localStorage.setItem(keyThisTitle, JSON.stringify(window.document.title));//储存章节标题
// console.log("准备激活加速");
ratechg(playRateNow);
if (autoSkip == true) {//秒过功能,已经不抵了,别尝试,没用的
setTimeout(function () {
skipVideo();
}, (submitTime + Math.ceil(Math.random() * randomX)));
console.log("秒过了!");
};
clock = setInterval(examherftest, 3000);//阿み杰此处要改11才能考试,循环法用examherftest检测考试按钮是否能点击
;
}
// 保存课程列表(每次都会检查并更新)
console.log('🎬 视频页面加载完成,开始保存/更新课程列表');
saveCourseList();
if (testtest) { addContinuousExamButton(); }// 添加连续考试按钮
// 检查是否是刷脸后返回
checkFaceVerificationReturn();
switch (e) {
case 1:
if (typeof window.s2j_onPlayerInitOver === 'function') {
window.s2j_onPlayerInitOver();
}
{
// 修复静音错误:先检查player对象是否存在
if (typeof player !== 'undefined' && player && player.j2s_setVolume) {
try {
player.j2s_setVolume(0);
console.log("保利威播放器静音成功");
} catch (error) {
console.log("保利威播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof player !== 'undefined' && player && player.j2s_resumeVideo) {
player.j2s_resumeVideo();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
killsendQuestion3();
break;
case 2:
if (typeof window.on_CCH5player_ready === 'function') {
window.on_CCH5player_ready();
}
{
// 修复静音错误:先检查cc_js_Player对象是否存在
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.setVolume) {
try {
cc_js_Player.setVolume(0);
console.log("CC播放器静音成功");
} catch (error) {
console.log("CC播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.play) {
cc_js_Player.play();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
break;
default:
console.log("其他播放器?");
};
},
doTest: function () {
var questions = JSON.parse(localStorage.getItem(keyTest)) || {};
var qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
if (JSON.stringify(qRightAnswer) == "{}") {
qRightAnswer = LoadRightAnwser();
};
var qTestAnswer = {};
var index = 0;
while (true) {
var question = document.querySelectorAll("table[class='tablestyle']")[index];
if (question == null) break;
else {
//var q = question.querySelector(".q_name").innerText.substring(2).replace(/\s*/g, "");//问题的具体文本
// 使用新的题目获取方式
var rawQuestion = question.querySelector(".q_name").innerText.substring(2);
var q = cleanQuestionText(rawQuestion);
console.log(q);
//thisQuestions=thisQuestions+q+"@"
if (qRightAnswer.hasOwnProperty(q)) { //当查询到记录了正确答案时的操作
//console.log("问题:"+ q + ",有答案:"+ qRightAnswer[q]);
var rightSelection = findAnwser("tbody", index, qRightAnswer[q]) //返回答案选项label
if (rightSelection) {
rightSelection.click();
}
} else {
if (questions.hasOwnProperty(q)) {
questions[q] = getNextChoice(questions[q]);//通过Unicode数字+1切换到下一个选项,返回的是字母选项
//console.log("不知道答案:"+ q+",测试:"+questions[q]);
} else { //如果系统没有记录
questions[q] = "A";
};
var answer = getChoiceCode(questions[q]);//将字母选项转换为Unicode数字并减去A代表的65,等于选项顺序,0是第一个选项
var element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
if (!element) { //选项除错机制
console.log("找不到选项,选项更改为A index: " + index + " answer: " + answer);
questions[q] = "A";
answer = getChoiceCode("A");
element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
//localStorage.removeItem(keyTest)
};
try {
var answerText = element.innerText.substring(3);//"A、"占用3个字符
//console.log("测试语法:" + (answerText == element.innerText.trim().substring(2)));
//element.nextSibling.innerText.trim().substring(2); //获得当前答案文本
qTestAnswer[q] = answerText;
//console.log("qTestAnswer:"+error);
} catch (error) { console.log("答案文本获取失败A:" + error); };
if (element) {
element.click();
}
};
index = index + 1;
};
};
//存储相关记录
localStorage.setItem(keyTest, JSON.stringify(questions));
localStorage.setItem(keyTestAnswer, JSON.stringify(qTestAnswer));
setTimeout(function () {
var submitButton = document.querySelector("#btn_submit");
if (submitButton) {
submitButton.click();
}
}, (submitTime + Math.ceil(Math.random() * randomX))); //交卷延时
///专用函数区
function findAnwser(qakey, index, rightAnwserText) {
var answerslist = document.querySelectorAll(qakey)[index];
if (!answerslist) return null;
var arr = answerslist.getElementsByTagName("label");
console.log(`查找答案: ${rightAnwserText}`);
// 精确匹配
for (var i = 0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText===rightAnwserText) {
console.log(`✅ 精确匹配: ${optionText}`);
return arr[i];
}
}
// 模糊匹配
for (var i=0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText.includes(rightAnwserText) || rightAnwserText.includes(optionText)) {
console.log(`🔍 模糊匹配: ${optionText}`);
return arr[i];
}
}
console.log(`❌ 未找到匹配答案,使用第一个选项`);
return arr[0];
}
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] ? $(".tips_text")[0].innerText : null;
var dds=$(".state_cour_lis");
localStorage.removeItem(keyResult);
if (res=="考试通过" || res=="考试通过!" || res=="完成项目学习可以申请学分了" ) {
console.log("考试通过");
saveRightAnwser();
SaveAllAnwser();
cleanKeyStorage();
checkExamContinuation();
setTimeout(function () {
// ...(原有代码)
}, 1000);
} else {
console.log("考试未通过")
var tipsTextElement=document.querySelector("p[class='tips_text' ]");
if (tipsTextElement) {
tipsTextElement.innerText="本次未通过,正在尝试更换答案\r\n(此为正常现象,脚本几秒后刷新,请勿操作)"
}
var qWrong={};
for (var i=0; i < dds.length; ++i) {
if (dds[i].querySelector("img") && !dds[i].querySelector("img").src.includes("bar_img")) {//这里表示否定
var rawQuestion=dds[i].querySelector("p").title;
var cleanedQuestion=cleanQuestionText(rawQuestion);
qWrong[cleanedQuestion]=i
};
};
if (qWrong !={}) {
localStorage.setItem(keyResult, JSON.stringify(qWrong));
saveRightAnwser();
setTimeout(function () {
$("input[type=button][value='重新考试' ]").click();
}, (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 qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) ||{};
var qTitle=JSON.parse(localStorage.getItem(keyThisTitle)) || "没有记录到章节名称" ;
if (qTitle=="没有记录到章节名称" ) {
console.log("没找到章节名称");
return {};
};
var qOldAnswer=qAllAnswer[qTitle] || {};
return qOldAnswer
};
// 修改题目处理逻辑,去除干扰的问号
// 统一的题目清洗函数
function cleanQuestionText(questionText) {
if (!questionText) return '' ;
// 去除各种特殊字符和空白
let cleaned=questionText
.replace(/[??]/g, '' )
.replace(/||[\u200B-\u200D\uFEFF]/g, '' ) // 去除零宽空格
.replace(/\s+/g, ' ' ) // 将多个空格合并为一个
.trim();
// 去除题目编号
cleaned=cleaned.replace(/^\d+、/, '' ).trim();
// 智能处理括号:
// 1. 只删除完全为空或只有空格的括号
// 2. 保留包含实际内容的括号
cleaned=cleaned.replace(/[((]\s*[))]/g, '' ) // 处理空括号
.replace(/[((]\s*([^))\s]+)\s*[))]/g, '$1' ) // 保留括号内的内容
.trim();
return cleaned;
}
// 修改题目获取方式,确保一致性
function getQuestionText(questionElement) {
try {
let rawText=questionElement.querySelector(".q_name").innerText;
// 去除编号部分(如"1、")
let textWithoutNumber=rawText.replace(/^\d+、/, '' );
return cleanQuestionText(textWithoutNumber);
} catch (error) {
console.log("获取题目文本错误:", error);
return "" ;
}
}
// 修改答案记录部分
function saveRightAnwser() {
var qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
var qTestAnswer=JSON.parse(localStorage.getItem(keyTestAnswer)) || {};
var qWrongs=JSON.parse(localStorage.getItem(keyResult)) || {};
console.log("开始保存正确答案...");
console.log("错题记录:", qWrongs);
console.log("测试答案:", qTestAnswer);
// 构建清理后的题目映射
var cleanedWrongs={};
for (var wrongQ in qWrongs) {
var cleanedWrongQ=cleanQuestionText(wrongQ);
cleanedWrongs[cleanedWrongQ]=true;
console.log(`错题清洗: "${wrongQ}" -> "${cleanedWrongQ}"`);
}
for (var q in qTestAnswer) {
var cleanedQ = cleanQuestionText(q);
console.log(`处理题目: "${q}" -> "${cleanedQ}", 答案: ${qTestAnswer[q]}`);
if (!cleanedWrongs[cleanedQ]) {
console.log(`✅ 正确答案: "${cleanedQ}" -> ${qTestAnswer[q]}`);
qRightAnswer[cleanedQ] = qTestAnswer[q];
} else {
console.log(`❌ 错误题目: "${cleanedQ}" -> ${qTestAnswer[q]}`);
}
}
localStorage.removeItem(keyTestAnswer);
if (Object.keys(qRightAnswer).length > 0) {
localStorage.setItem(keyRightAnswer, JSON.stringify(qRightAnswer));
console.log("✅ 正确答案已保存:", qRightAnswer);
} else {
console.log("❌ 没有正确答案需要保存");
}
}
//答案记录函数区结束//
//------------------答案复制相关按钮--------------------------------------------
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")
//Aout=encodeURIComponent(Aout);
//window.prompt("请复制",Aout);
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;
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(textout);
}
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.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);
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
//答案复制相关按钮 end
function skipVideo() {//这是跳过视频的代码
var oVideo = document.getElementsByTagName('video')[0];
if (oVideo) {
oVideo.currentTime = oVideo.duration - 1
};
};
// 在 courseList 函数中添加导入答案按钮
function addImportAnswerBtn() {
let alink = document.createElement("a");
alink.innerHTML = '导入答案';
alink.style = btstyleB;
alink.onclick = function (event) {
var input = prompt("请粘贴要导入的答案数据(JSON格式)");
if (input) {
try {
// 解析输入的JSON数据
var importedAnswers = JSON.parse(input);
// 获取现有的答案记录
var existingAnswers = JSON.parse(localStorage.getItem(keyAllAnswer)) || {};
// 合并答案
var mergedAnswers = mergeAnswerData(existingAnswers, importedAnswers);
// 保存合并后的答案
localStorage.setItem(keyAllAnswer, JSON.stringify(mergedAnswers));
alert("✅ 答案导入成功!\n已合并 " + Object.keys(importedAnswers).length + " 个章节的答案");
} catch (error) {
alert("❌ 导入失败:数据格式不正确\n" + error);
}
}
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
// 合并答案数据的函数
function mergeAnswerData(existing, imported) {
// 深拷贝现有答案
var merged = JSON.parse(JSON.stringify(existing));
// 遍历导入的答案
for (var chapter in imported) {
if (imported.hasOwnProperty(chapter)) {
// 如果章节不存在,直接添加
if (!merged[chapter]) {
merged[chapter] = imported[chapter];
} else {
// 合并章节内的题目答案
for (var question in imported[chapter]) {
if (imported[chapter].hasOwnProperty(question)) {
merged[chapter][question] = imported[chapter][question];
}
}
}
}
}
return merged;
};
//------------------看视频页面主要函数-------------------------------------------
function clickexam() { //延时点击考试按钮。
console.log("已点击考试按钮");
setTimeout(function () {
var examButton = document.querySelector("#jrks");
if (examButton) {
examButton.click();
}
}, (Math.ceil(Math.random() * randomX)));
//}, (examTime + Math.ceil(Math.random() * randomX)));
};
//按钮插入函数相关
function addSkipbtn() {//插入按钮快进视频按钮
let alink = document.createElement("a");
alink.innerHTML = '快进视频';
alink.style = btstyleA;
alink.onclick = function (event) {
skipVideo();
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
};
function addratebtn(ra) {//倍率调整按钮
let alink = document.createElement("a");
alink.innerHTML = '' + ra + 'x';
alink.style = btstyleB;
alink.className = "speed";
alink.id = ra + "x";
alink.onclick = function (event) {
ratechg(ra);
try {
var arr = document.querySelectorAll("a[class='speed']");
arr.forEach(function (item, index, arr) {
arr[index].style = btstyleB;
});
} catch (error) {
};
alink.style = btstyleC;
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
}
function ratechg(ra) {//倍率调整
var videoObj = document.querySelector("video")
if (videoObj) {
try {
clearInterval(nspeed);
nspeed = setInterval(() => {
videoObj.playbackRate = ra;
}, 1 * 1000);
localStorage.setItem(keyPlayRate, ra);
//document.querySelector("a[id=" + "'" + ra + "x']").style = btstyleC;
//document.getElementById("playrate").innerHTML = "当前播放速率" + ra + "x";
//console.log("倍率调整为" + ra);
} catch (error) { console.log("倍率调整错误" + error); };
}
};
function addrateinfo() {//插入说明
let adiv1 = document.createElement("div");
adiv1.innerHTML = '当前播放速率';
adiv1.id = 'playrate';
adiv1.style = "font-size: 15px;text-align: center;margin-top: 10px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv1);
}
};
function addinfo() {//插入说明
//模式切换按钮
var moderesult = localStorage.getItem("华医mode");
if (moderesult == 2) {
moderesult = "当前模式:视频+考试";
} else {//包括了结果为1或者无存储的情况
moderesult = "当前模式:单刷视频";
};
var checkbox = document.createElement('div');
checkbox.innerHTML = '' + moderesult + '
[点击此处切换] ';
// 添加到页面的 body 元素中
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(checkbox);
}
//插入说明部分
let mode1 = document.querySelector("a[id='mode']");
if (mode1) {
mode1.onclick = function () {
if (mode1.innerText == "当前模式:单刷视频\n[点击此处切换]") {
mode1.innerText = "当前模式:视频+考试\n[点击此处切换]";
localStorage.setItem("华医mode", "2");
} else {
mode1.innerText = "当前模式:单刷视频\n[点击此处切换]";
localStorage.setItem("华医mode", "1");
};
};
}
let adiv2 = document.createElement("div");
adiv2.innerHTML = '       本人医学研一学生,经常要帮师兄师姐刷华医视频,属实太累。偶然在抖音发现Dr.S的脚本,结果刷完1个视频立刻考试,导致频繁人脸识别跟手动区别不大。原作者已不更新,于是我自学修改了播放逻辑,实现无人值守连续播放。现将原先自用的脚本分享给大家❤❤
     刷完视频再切换考试模式,即可连续考试。
';
adiv2.id = 'jsinfo';
adiv2.style = "position:relative;left:10px;top:5px;width:240px;font-size:13px;text-align: justify;border: 1px dashed #ff9595;padding:5px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv2);
}
if (typeof $ !== 'undefined') {
$('div:contains("观看视频完成后,才能进入考试")').eq(-1).text('建议360安全浏览器和脚本猫');
}
// 创建连续考试按钮的容器
let examBtnContainer = document.createElement('div');
examBtnContainer.id = 'continuousExamBtnContainer';
examBtnContainer.style = "text-align: center; margin: 10px 0;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(examBtnContainer);
}
};
function changelayout() {
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv) {
jjDiv.remove();
}
var photoImg = document.querySelector("img[id='photo']");
if (photoImg) {
photoImg.outerHTML = `
`;
photoImg.style.width = "120px";
photoImg.style.height = "120px";
}
var titleDivs = document.querySelectorAll("div[class='title']");
if (titleDivs[0] && titleDivs[0].children[0]) {
titleDivs[0].children[0].style = "color: #ff0000;font-weight: bold";
titleDivs[0].children[0].innerText = "支持作者";
}
var imgTextDivs = document.querySelector("div[class='imgtext']");
if (imgTextDivs && imgTextDivs.children[1]) {
imgTextDivs.children[1].style.width = "125px";
imgTextDivs.children[1].style = "color: #ff0000;padding-top:10px";
imgTextDivs.children[1].innerText = "作 者\n创作优化不易\n投点小费吧\n❤谢啦❤\n❤"
}
var topDiv = document.querySelector("div[class='top']");
if (topDiv) {
topDiv.outerHTML = '如服务器调整,脚本可能失效。反馈意见、免费增加课程请在Greasyfork私信或脚本反馈区联络。也欢迎投喂↓
';
}
};
function cleanKeyStorage() {//缓存清理
localStorage.removeItem(keyTest);
localStorage.removeItem(keyResult);
localStorage.removeItem(keyTestAnswer);
localStorage.removeItem(keyRightAnswer);
};
function examherftest() {//考试按钮激活状态检测
var examButton = document.getElementById("jrks");
var hreftest = examButton ? examButton.attributes["disabled"] : null;
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if ((state == "已完成" || state == "待考试" || !hreftest) && examButton) {//value不为#说明考试按钮已经激活
console.log("已经播放完了");
// 优先处理"视频+考试"模式下的"待考试"状态
var modeElement = document.querySelector("a[id='mode']");
if (modeElement && modeElement.innerText.indexOf("视频+考试") != -1 && state == "待考试") {
console.log("mode=2,准备进入考试");
// 重试机制:尝试5次进入考试
var retryCount = 0;
var maxRetries = 5;
function tryEnterExam() {
retryCount++;
console.log(`尝试进入考试 (第${retryCount}次)`);
try {
// 方法1:尝试点击考试按钮
if (document.getElementById("jrks") && !document.getElementById("jrks").disabled) {
document.getElementById("jrks").click();
console.log("成功点击考试按钮");
return true; // 成功进入考试
}
// 方法2:尝试备用方式
if (typeof cwrid !== 'undefined') {
window.open("/pages/exam_tip.aspx?cwrid=" + cwrid, "_self");
console.log("尝试备用方式进入考试");
return true;
}
// 方法3:尝试通过URL跳转
var currentUrl = window.location.href;
if (currentUrl.includes("course_ware")) {
var examUrl = currentUrl.replace("course_ware/course_ware_", "pages/exam.aspx?cwid=")
.split("?")[0] + "?cwid=" + getUrlParam("cwid");
window.location.href = examUrl;
console.log("尝试通过URL跳转进入考试");
return true;
}
} catch (error) {
console.log(`第${retryCount}次尝试失败:`, error);
}
return false; // 进入考试失败
}
// 立即尝试第一次
if (tryEnterExam()) {
return; // 成功进入考试,直接返回
}
// 设置重试间隔
var retryInterval = setInterval(function () {
if (retryCount >= maxRetries) {
clearInterval(retryInterval);
console.log(`尝试${maxRetries}次进入考试均失败,继续听课`);
// 继续执行后续的跳转到下一个视频的逻辑
proceedToNextVideo();
} else if (tryEnterExam()) {
clearInterval(retryInterval); // 成功进入考试,停止重试
}
}, 2000); // 每2秒重试一次
} else {
// 单刷视频模式或非待考试状态,直接继续听课
proceedToNextVideo();
};
} else {//#代表考试按钮还没激活
//继续播放,无需任何操作
}
}
// 跳转到下一个视频的函数
function proceedToNextVideo() {
console.log('🚀 准备跳转到下一个视频...');
const nextCwid = getNextCourseCwid();
if (nextCwid) {
console.log(`✅ 确定跳转到课程: ${nextCwid.substring(0, 8)}...`);
console.log(`🌐 跳转URL: course_ware.aspx?cwid=${nextCwid}`);
// 延迟跳转,让用户有时间查看日志
setTimeout(() => {
console.log('⏩ 正在跳转...');
window.location.href = `course_ware.aspx?cwid=${nextCwid}`;
}, 2000);
} else {
console.log('❌ 没有找到可用的课程,尝试刷新页面');
setTimeout(() => {
console.log('🔄 正在刷新页面...');
window.location.reload();
}, 2000);
}
}
// 辅助函数:获取URL参数
function getUrlParam(name) {
var urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
};
//课堂问答跳过,临时版
function sleep(timeout) {
return new Promise((resolve) => { setTimeout(resolve, timeout); });
console.log("课堂问答循环调用");
};
function asynckillsendQuestion() {
(async function () {
while (!window.player || !window.player.sendQuestion) {
await sleep(20);
};
//console.log("课堂问答跳过插入");
player.sendQuestion = function () {
//console.log("播放器尝试弹出课堂问答,已屏蔽。");
};
})();
};
function killsendQuestion2() {
if (typeof (isInteraction) == "undefined") {
//console.log('变量未定义');
} else {
console.log('isInteraction设置off');
isInteraction = "off";
};
};
function killsendQuestion3() { //点击跳过按钮版的跳过课堂答题
var clockms = setInterval(async function () {
try {
if (typeof $ !== 'undefined' && $('.pv-ask-head').length && $('.pv-ask-head').length > 0) {
console.log("检测到问题对话框,尝试跳过");
$(".pv-ask-skip").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.signBtn').length && $('.signBtn').length > 0) {
console.log("检测到签到对话框,尝试跳过");
$(".signBtn").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' &&
$("button[onclick='closeProcessbarTip()']").length &&
$("button[onclick='closeProcessbarTip()']").length > 0 &&
$("div[id='div_processbar_tip']").css("display") == "block") {
console.log("检测到温馨提示对话框(不能拖拽),尝试跳过");//
//*[@id="div_processbar_tip"]/div/div[2]/input
//document.querySelector("#div_processbar_tip > div > div.foot_sub > input")
//#div_processbar_tip > div > div.foot_sub > input
//
$("button[onclick='closeBangZhu()']").click();
$("button[onclick='closeProcessbarTip()']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $("button[class='btn_sign']").length && $("button[class='btn_sign']").length > 0) {
console.log("检测到温馨提示对话框(疲劳提醒),尝试跳过");
$("button[class='btn_sign']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.rig_btn').length && $('.rig_btn').length > 0) {
if ($('#div_processbar_tip').is(':visible')) {
console.log("检测到按钮(知道了),执行隐藏操作");
$('#div_processbar_tip').hide();
}
//$(".rig_btn").click();
};
} catch (err) {
console.log(err);
};
try {
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if (typeof $ !== 'undefined' &&
$('video').prop('paused') == true &&
state != "已完成" &&
state != "待考试") {
console.log("视频意外暂停,恢复播放");
$('video').get(0).play();
//$('video').prop('volumed') = 0;
$('video').prop('muted') = true;
} else if (state == "已完成") {
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.pause();
}
//clearInterval(clockms);
};
} catch (err) {
//console.log(err);
};
}, 10000);
};
function autoClickKnowButton() {
// 检测按钮是否加载完成
const observer = new MutationObserver(() => {
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
observer.disconnect(); // 停止观察
button.click(); // 点击按钮
}
});
// 开始观察文档的变化
observer.observe(document.body, {
childList: true,
subtree: true
});
// 如果按钮已经加载完成,直接点击
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
button.click();
}
}
// 在全局函数区添加以下函数
function saveCourseList() {
console.log('📋 开始保存/更新课程列表...');
// 尝试获取课程列表容器
const courseContainer = document.querySelector('.page-container');
if (!courseContainer) {
console.log('❌ 未找到课程列表容器');
return;
}
// 尝试获取课程项
const courseItems = document.querySelectorAll('.lis-inside-content');
if (courseItems.length === 0) {
console.log('❌ 未找到课程项');
return;
}
console.log(`📚 找到 ${courseItems.length} 个课程项,开始解析...`);
const currentCourseList = [];
let hasChanges = false;
courseItems.forEach((item, index) => {
const titleElement = item.querySelector('h2');
const statusButton = item.querySelector('button');
if (titleElement && statusButton) {
const title = titleElement.textContent.trim();
const status = statusButton.textContent.trim();
const statusColor = statusButton.style.background;
// 从onclick属性中提取cwid
const onclickAttr = titleElement.getAttribute('onclick');
let cwid = '';
if (onclickAttr) {
const match = onclickAttr.match(/cwid=([^']+)/);
if (match && match[1]) {
cwid = match[1];
}
}
if (cwid) {
currentCourseList.push({
title,
status,
statusColor,
cwid,
index
});
//console.log(` 课程 ${index + 1}: "${title}" - 状态: ${status}`);
}
}
});
if (currentCourseList.length === 0) {
console.log('❌ 未解析到任何课程信息');
return;
}
// 获取之前保存的课程列表
const previousCourseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
if (previousCourseList.length === 0) {
// 第一次保存
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`✅ 首次保存课程列表完成,共 ${currentCourseList.length} 个课程`);
return;
}
// 检查是否有变化
console.log('🔍 检查课程状态变化...');
for (let i = 0; i < currentCourseList.length; i++) {
const currentCourse=currentCourseList[i];
const previousCourse=previousCourseList[i];
if (!previousCourse) {
console.log(` 新增课程: "${currentCourse.title}" `);
hasChanges=true;
continue;
}
// 检查状态变化
if (currentCourse.status !==previousCourse.status) {
console.log(` 状态变化: "${currentCourse.title}" - ${previousCourse.status} → ${currentCourse.status}`);
hasChanges=true;
}
// 检查标题变化(可能课程有更新)
if (currentCourse.title !==previousCourse.title) {
console.log(` 标题变化: "${previousCourse.title}" → "${currentCourse.title}" `);
hasChanges=true;
}
// 检查cwid变化(理论上不应该变)
if (currentCourse.cwid !==previousCourse.cwid) {
console.log(` cwid变化: "${currentCourse.title}" `);
hasChanges=true;
}
}
// 检查课程数量变化
if (currentCourseList.length !==previousCourseList.length) {
console.log(` 课程数量变化: ${previousCourseList.length} → ${currentCourseList.length}`);
hasChanges=true;
}
if (hasChanges) {
// 更新课程列表
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`🔄 课程列表已更新,共 ${currentCourseList.length} 个课程`);
// 输出详细的课程状态
console.log('📊 当前所有课程状态:');
currentCourseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
} else {
console.log('✅ 课程列表无变化,无需更新');
// 即使无变化,也确保本地存储的是最新数据(防止数据损坏)
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
}
}
function getCurrentCourseCwid() {
// 从当前URL获取cwid
const urlParams = new URLSearchParams(window.location.search);
const cwid = urlParams.get('cwid');
console.log(`🔍 当前课程 cwid: ${cwid ? cwid.substring(0, 8) + '...' : '未找到'}`);
return cwid;
}
function getNextCourseCwid() {
console.log('🔄 开始查找下一个课程...');
// 尝试从localStorage获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
const currentCwid = getCurrentCourseCwid();
if (courseList.length === 0) {
console.log('❌ 未找到存储的课程列表');
return null;
}
console.log(`📊 课程列表中有 ${courseList.length} 个课程`);
// 找到当前课程的索引
const currentIndex = courseList.findIndex(course => course.cwid === currentCwid);
if (currentIndex === -1) {
console.log('❌ 未找到当前课程在列表中的位置');
console.log('当前课程可能不在列表中,将尝试第一个未完成的课程');
// 尝试查找第一个未完成的课程
for (let i = 0; i < courseList.length; i++) {
const course=courseList[i];
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到第一个未完成课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
return null;
}
console.log(`📍 当前课程位置: 第 ${currentIndex + 1} 个 - "${courseList[currentIndex].title}" `);
// 查找下一个未完成的课程(从当前位置向后找)
console.log('🔍 向后查找未完成的课程...');
for (let i=currentIndex + 1; i < courseList.length; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到下一个课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
// 如果后面没有未完成的课程,尝试从开头查找
console.log('🔍 向后未找到,从开头查找未完成的课程...');
for (let i=0; i < currentIndex; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到前面的课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
console.log('所有课程状态:');
courseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
return null;
}
//--------------------------插入悬浮框------------------------------------//
function advis() {
// 🔴 第一步:只在顶层窗口运行,iframe 中直接退出
if (window.self !== window.top) {
console.log('小助手:当前处于 iframe 中,不创建面板');
return;
}
// 🔴 第二步:检查是否已有面板,防止重复创建(即使脚本多次调用)
const existingPanel = document.getElementById('Div1');
if (existingPanel) {
console.log('已检测到小助手面板,防止重复创建');
return; // 或者 existingPanel.remove(); 再创建(推荐 return 即可)
}
// 🟡 第三步:创建新面板
let div1 = document.createElement("div");
div1.innerHTML = `
`;
document.body.append(div1);
// 绑定事件
let share1 = document.getElementById('Share1');
let share2 = document.getElementById('Share2');
let clo = document.getElementById('clo');
if (share1) {
share1.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/500010", "_blank");
};
}
if (share2) {
share2.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/555651", "_blank");
};
}
if (clo) {
clo.onclick = function () {
var panel = document.getElementById('Div1');
if (panel) {
panel.style.display = 'none';
}
};
}
// === 初始化:左对齐课程列表 ===
const panel = document.getElementById('Div1');
if (!panel) return;
const container = document.querySelector('.page-container') ||
document.querySelector('.lis-content') ||
document.querySelector('.container-inside-header');
let initialLeft = 140; // 默认值
if (container) {
const rect = container.getBoundingClientRect();
initialLeft = rect.left + window.pageXOffset;
}
panel.style.left = initialLeft + 'px';
// === 拖拽功能 ===
let isDragging = false;
let offsetX, offsetY;
panel.addEventListener('mousedown', function (e) {
if (e.target === clo ||
e.target.tagName === 'A' ||
e.target.tagName === 'IMG' ||
e.target.tagName === 'HR') return;
isDragging = true;
offsetX = e.clientX - panel.getBoundingClientRect().left;
offsetY = e.clientY - panel.getBoundingClientRect().top;
e.preventDefault();
});
document.addEventListener('mousemove', function (e) {
if (!isDragging) return;
panel.style.left = (e.clientX - offsetX) + 'px';
panel.style.top = (e.clientY - offsetY) + 'px';
});
document.addEventListener('mouseup', () => {
isDragging = false;
});
// 创建状态面板(默认隐藏)
//createStatusPanel();
//document.getElementById('examStatusPanel').style.display = 'none';
}
//--------------------------连续考试的函数------------------------------------//
// 修改 addContinuousExamButton 函数
function addContinuousExamButton() {
// 检查是否已存在连续考试按钮
if (document.getElementById('continuousExamBtn')) {
return;
}
// 创建连续考试按钮
let btn = document.createElement("a");
btn.innerHTML = '连续考试';
btn.style = btstyleA
btn.id = 'continuousExamBtn';
btn.onclick = function () {
console.log('🚀 开始连续考试流程...');
startContinuousExam();
};
// 找到建议提示框
const tipDiv = document.querySelector('div.r div[style*="border: 1px dashed #ff9595"]');
if (tipDiv) {
// 创建按钮容器
let btnContainer = document.createElement('div');
btnContainer.style = "text-align: center; margin: 10px 0;";
btnContainer.appendChild(btn);
// 将按钮容器插入到建议提示框后面
tipDiv.parentNode.insertBefore(btnContainer, tipDiv.nextSibling);
} else {
// 如果找不到建议提示框,使用预留的容器
const btnContainer = document.getElementById('continuousExamBtnContainer');
if (btnContainer) {
btnContainer.appendChild(btn);
} else {
// 如果容器也不存在,添加到页面底部
document.body.appendChild(btn);
}
}
}
// 新增:创建状态面板的函数
function createStatusPanel() {
// 检查是否存在 exam_phase
const examPhase = localStorage.getItem('exam_phase');
if (!examPhase) {
// 如果不存在 exam_phase,移除可能存在的面板
const existingPanel = document.getElementById('examStatusPanel');
if (existingPanel) {
existingPanel.remove();
}
return;
}
// 检查是否已存在状态面板
if (document.getElementById('examStatusPanel')) {
// 如果面板已存在,只需更新状态信息
updatePanelContent();
return;
}
// 创建状态面板
const panel = document.createElement('div');
panel.id = 'examStatusPanel';
panel.style = `
position: fixed;
top: 20px;
right: 20px;
width: 300px;
background-color: rgba(255, 255, 255, 0.95);
border: 2px solid #4cb0f9;
border-radius: 8px;
padding: 15px;
z-index: 10000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
font-family: 'Microsoft YaHei', sans-serif;
`;
panel.innerHTML = `
连续考试状态
加载中...
`;
// 确保面板正确插入到页面中
document.body.appendChild(panel);
// 添加取消按钮事件
var cancelBtn = document.getElementById('cancelExamBtn');
if (cancelBtn) {
cancelBtn.onclick = function () {
if (confirm('确定要取消连续考试吗?')) {
cancelContinuousExam();
}
};
}
// 更新面板内容
updatePanelContent();
// 辅助函数:更新面板内容
function updatePanelContent() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examPhase = localStorage.getItem('exam_phase');
let statusMessage = '';
if (examPhase === 'face_verification') {
statusMessage = `👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else if (examPhase === 'examination') {
statusMessage = `📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else {
statusMessage = '连续考试进行中...';
}
const contentElement = document.getElementById('examStatusContent');
if (contentElement) {
contentElement.innerHTML = statusMessage;
}
}
}
// 修改:更新状态提示的函数
function updateExamStatus(message, isError = false) {
createStatusPanel(); // 确保面板存在
const panel = document.getElementById('examStatusPanel');
// 添加存在性检查
if (!panel) {
console.log('状态面板不存在,跳过更新');
return;
}
panel.style.display = 'block';
const statusContent = document.getElementById('examStatusContent');
if (statusContent) {
statusContent.innerHTML = message;
statusContent.style.color = isError ? '#f15854' : '#333';
}
}
// 取消连续考试
function cancelContinuousExam() {
console.log('❌ 结束连续考试');
// 清除相关状态
localStorage.removeItem('exam_courses');
localStorage.removeItem('current_exam_index');
localStorage.removeItem('exam_phase');
// 只有在面板存在时才更新状态
const panel = document.getElementById('examStatusPanel');
if (panel) {
updateExamStatus('连续考试已取消');
// 3秒后隐藏状态面板
setTimeout(() => {
//panel.style.display = 'none';
}, 3000);
} else {
console.log('状态面板不存在,直接清除状态');
}
}
// 连续考试主函数
function startContinuousExam() {
// 强制设置为单刷视频模式,避免冲突
localStorage.setItem("华医mode", "1");
console.log('🚀 开始连续考试流程,模式强制设置为单刷视频');
localStorage.setItem('exam_phase', 'setup'); // 设置阶段为初始化
// 创建状态面板
createStatusPanel();
// 获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
// 筛选待考试的课程
const examCourses = courseList.filter(course => course.status === '待考试');
if (examCourses.length === 0) {
console.log('❌ 没有找到待考试的课程');
updateExamStatus('❌ 没有找到待考试的课程', true);
localStorage.removeItem('exam_phase');
return;
}
// 保存待考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
localStorage.setItem('exam_phase', 'face_verification'); // 设置阶段为刷脸
console.log(`📋 找到 ${examCourses.length} 个待考试课程`);
updateExamStatus(`找到 ${examCourses.length} 个待考试课程
准备开始刷脸流程...`);
// 开始刷脸流程
startFaceVerificationProcess();
}
// 刷脸流程
function startFaceVerificationProcess() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有课程刷脸完成,开始连续考试');
updateExamStatus('✅ 所有课程刷脸完成
开始连续考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startFaceVerificationProcess, 1000);
return;
}
console.log(`👤 开始第 ${currentIndex + 1} 个课程刷脸: ${currentCourse.title}`);
updateExamStatus(`👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开课程链接进行刷脸
window.location.href = `course_ware.aspx?cwid=${currentCourse.cwid}`;
}
// 监听页面加载,判断是否在刷脸后返回
function checkFaceVerificationReturn() {
const examPhase = localStorage.getItem('exam_phase');
const isInFaceVerification = examPhase === 'face_verification';
if (isInFaceVerification) {
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
// 只有当索引有效时才继续
if (currentIndex < examCourses.length) {
console.log('🔍 检测到刷脸后返回,继续下一个课程');
localStorage.setItem('current_exam_index', currentIndex + 1);
updateExamStatus(`✅ 刷脸完成 ${currentIndex + 1}/${examCourses.length}
准备下一个课程...`);
// 添加延迟防止过快跳转
setTimeout(startFaceVerificationProcess, 3000);
} else {
console.log('✅ 刷脸流程已完成');
updateExamStatus('✅ 刷脸流程已完成
准备开始考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
}
}
}
// 开始所有考试
function startAllExams() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
if (examCourses.length === 0) {
console.log('❌ 没有待考试的课程');
updateExamStatus('❌ 没有待考试的课程', true);
return;
}
console.log('🎯 开始连续考试流程');
updateExamStatus(`🎯 开始连续考试流程
共 ${examCourses.length} 个考试待完成`);
// 保存考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
// 开始第一个考试
startNextExam();
}
// 开始下一个考试
function startNextExam() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有考试完成!');
updateExamStatus('✅ 所有考试完成!
连续考试流程结束');
cancelContinuousExam();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startNextExam, 1000);
return;
}
console.log(`📝 开始第 ${currentIndex + 1} 个考试: ${currentCourse.title}`);
updateExamStatus(`📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开考试页面
window.location.href = `/pages/exam.aspx?cwid=${currentCourse.cwid}`;
}
// 在考试结果页面检查是否需要继续下一个考试
function checkExamContinuation() {
const examPhase = localStorage.getItem('exam_phase');
const isInExamMode = examPhase === 'examination';
if (isInExamMode) {
console.log('🔍 检测到考试完成,准备下一个考试');
// 增加索引
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
localStorage.setItem('current_exam_index', currentIndex + 1);
// 更新状态提示
updateExamStatus(`✅ 考试完成 ${currentIndex + 1}/${examCourses.length}
准备下一个考试...`);
// 短暂延迟后继续下一个考试
setTimeout(() => {
startNextExam();
}, 3000);
}
}
//---------------------------------全局函数区end------------------------------//
})();gwQOWPuloSKykYzlA6CZxbTEFRiWVVbcQ9nxyvmpirmdmlD/UAA/8MQzsAMGXECpceKpvAcHnEPEINwkLqIrLlf5pEMBIMA7PEM0YMAHJZwU/gM9gM97RAMuaNhMuM1JXVc+jJNT+IUnFgMJsMM6BCPVJeIrTiOBHdkFtIM+3Nc5xN4j7c35jQUR5MP0pcSfPU5JoYPctWLHpIOqOQCwfZ0ZHlECUiM9al3FXIc4NZx2zeMwiYNwrU8znIdTJIA63JA/HI4gwsReXGBNlMPmHV49RuSBqVimzAneIJkuZh5tOUszGKQ/oIPKNIXLhEmnxALdIGIy+shaHNfrSaRLnhmbvdsXYhBGbMqQfSR+NIXe1AhwzEX8vSRQBiXfGUk5kM84/xJMP1xAM6QTWXDAJjYFPoTHDT0DBjSTUF4lVrogdBhAMDQDBjhAkRzl2kCHsSDLHJ2DOoYEAZCUzpDAMEgOP2alXO4d6tkFMtSDO5SUKH4fBikJLBDWhIkD7PUDLBRkJPEDmaTlXC4mNyIHtIDJO1BA+LlYSCBDNPBkWSAAFL6I5XgjcLADLBgYY46mK6Ie59UDlfQEdK0RRhjAI8KMOpxAQsLEOdCVPEkLBYgmae4mGtZFc90Qk8ldX2KSJt2QO+hD4zVFOizlezyDO+SmYvKmdIranp2TdZUFBkwm9RwHfXghbSDHPzanH4VdXhRmmywYO1SYdk4ne3LdUqhFMP8ECZu0j26GFJuNQAJQQD4YQHShpJtdgHBVSZsU14s4Zh36xDpgiX+2J4PmHdXhQzDUAwLwgwjoA8JwZpoMg/kpWsWl5VBcgFTCDAnUUzKGRFRIKD+gw0nGZYO2qBo+HgHggwGcwDbuGVH8BQFwQDoNXTiJ3nV0JP34Q+SkJEiUQzsgwwno3g66KJOKGs2Ux5GMUxfOBNtYDgLAzYAqJlNQgEeWAJYUaIDE1Ho2KZmW4B+xzXk85Ez0VTsY5nuQx5imRFvY2OCtg8Ul44/dB8JEZ5n26VlVm19QjI3KxJ7dQ3GKhwPEaf50ILI8g2Sm3VJIR+p9IYv6qaX6HOu9FZ///kU5oMONsc/+cWJQKCXH4ZRsKipgaIkkFhGfXqqrThtvnAAhEYE6lIA+5CRnsgchsUMsDANyAuGrBquLVttHgAAuIAMu0ENWGN6ptcUsGIA+JIA4RJOwVmt7GmF3imV6wF+Ytqq1fusi6kXlRGkCvqc+Viq4pqv/AQuM8NxsrGQcqqu8YiX6tB6XoKr5DBg0kNyazau/XuWeAWo8hlSMxeu/HizCJqzCLizDNqzDPizERqzETizFVqzFXizGZqzGbizHdqzHfizIhqzIjizJlqzJnizKpqzKrizLtqzLvizMxqzMzizN1qzN3izO5qzO7izP9qzP/izQBq3QDi3RIhat0R4t0iat0i4t0zat0z4t1Eat1E4t1Vat1V4t1qJsQAAAOw==`;
var clock = null;
var testtest = true; //另一个可能会封号的功能,仅调试使用。
advis();
createStatusPanel(); //状态监视面板根据需要进行显示
// 修复错误:检查元素是否存在后再设置内容
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "当前网址已适配ヾ(๑╹◡╹)ノ"
失效请赞赏联系  ε(┬┬﹏┬┬)3";
}
if (urlTip == "course_ware_polyv.aspx") { //保利威播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(1);
} else if (urlTip == "course_ware_cc.aspx") { //CC播放器视频页面
console.log("当前任务: 华医看视频");
var div1Element = document.querySelector("div[id='Div1']");
if (div1Element) {
div1Element.style.top = "40px";
}
huayi.seeVideo(2);
} else if (urlTip == "face.aspx") { //刷脸
console.log("当前任务: 刷脸界面");
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "course.aspx" || urlTip == "cme.aspx") { //课程列表页面
console.log("当前任务: 课程列表");
huayi.courseList();
(function () { setTimeout(() => { location.reload(); }, 5 * 60 * 1000); })(); // 添加5分钟自动刷新功能
} else if (urlTip == "exam.aspx") { //考试页面
console.log("当前任务: 华医考试");
huayi.doTest();
} else if (urlTip == "exam_result.aspx") { //考试结果页面
console.log("当前任务: 华医考试结果审核");
huayi.doResult();
} else {
console.log("其它情况");
try {
var tixingElement = document.querySelector("span[id='tixing']");
if (tixingElement) {
tixingElement.innerHTML = "此页面非视频、考试或未适配";
}
document.querySelector("img[id='Pic']").style.display = "block";
} catch (error) { };
};
function getHuayi() {
return {
courseList: function () {
addAnwserCopybtn();
addImportAnswerBtn();
DelAllAnwser();
},
seeVideo: function (e) {
var tr = localStorage.getItem(keyPlayRate);
//console.log("存储读取" + tr);//读取倍速
//var playRateNow = tr ? tr : vSpeed;
var playRateNow = 1;
cleanKeyStorage();
asynckillsendQuestion();//屏蔽课堂问答的函数;
killsendQuestion2();//屏蔽课堂问答的函数2;
killsendQuestion3(); //循环检测问答对话框是否弹出。
//addrateinfo();//插入一些按钮
//addratebtn(1);
//addratebtn(1.5);
//addratebtn(2);
//addSkipbtn();//跳过按钮
addinfo();//脚本信息
changelayout();
//速度调节部分
window.onload = function () {
localStorage.setItem(keyThisTitle, JSON.stringify(window.document.title));//储存章节标题
// console.log("准备激活加速");
ratechg(playRateNow);
if (autoSkip == true) {//秒过功能,已经不抵了,别尝试,没用的
setTimeout(function () {
skipVideo();
}, (submitTime + Math.ceil(Math.random() * randomX)));
console.log("秒过了!");
};
clock = setInterval(examherftest, 3000);//阿み杰此处要改11才能考试,循环法用examherftest检测考试按钮是否能点击
;
}
// 保存课程列表(每次都会检查并更新)
console.log('🎬 视频页面加载完成,开始保存/更新课程列表');
saveCourseList();
if (testtest) { addContinuousExamButton(); }// 添加连续考试按钮
// 检查是否是刷脸后返回
checkFaceVerificationReturn();
switch (e) {
case 1:
if (typeof window.s2j_onPlayerInitOver === 'function') {
window.s2j_onPlayerInitOver();
}
{
// 修复静音错误:先检查player对象是否存在
if (typeof player !== 'undefined' && player && player.j2s_setVolume) {
try {
player.j2s_setVolume(0);
console.log("保利威播放器静音成功");
} catch (error) {
console.log("保利威播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof player !== 'undefined' && player && player.j2s_resumeVideo) {
player.j2s_resumeVideo();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
killsendQuestion3();
break;
case 2:
if (typeof window.on_CCH5player_ready === 'function') {
window.on_CCH5player_ready();
}
{
// 修复静音错误:先检查cc_js_Player对象是否存在
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.setVolume) {
try {
cc_js_Player.setVolume(0);
console.log("CC播放器静音成功");
} catch (error) {
console.log("CC播放器静音失败:", error);
}
}
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.defaultMuted = true;
}
setTimeout(function () {
try {
//document.querySelector("video").volume = 0;//实际测试,主要靠这一条静音
if (typeof cc_js_Player !== 'undefined' && cc_js_Player && cc_js_Player.play) {
cc_js_Player.play();
}
//document.querySelector("video").muted = true;
examherftest();
//document.querySelector("button[onclick='closeBangZhu()']").click();//关闭温馨提醒
} catch (error) {
console.log("上一段代码有误");
};
}, 8000); //延时点击播放,之前是5秒
};
break;
default:
console.log("其他播放器?");
};
},
doTest: function () {
var questions = JSON.parse(localStorage.getItem(keyTest)) || {};
var qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
if (JSON.stringify(qRightAnswer) == "{}") {
qRightAnswer = LoadRightAnwser();
};
var qTestAnswer = {};
var index = 0;
while (true) {
var question = document.querySelectorAll("table[class='tablestyle']")[index];
if (question == null) break;
else {
//var q = question.querySelector(".q_name").innerText.substring(2).replace(/\s*/g, "");//问题的具体文本
// 使用新的题目获取方式
var rawQuestion = question.querySelector(".q_name").innerText.substring(2);
var q = cleanQuestionText(rawQuestion);
console.log(q);
//thisQuestions=thisQuestions+q+"@"
if (qRightAnswer.hasOwnProperty(q)) { //当查询到记录了正确答案时的操作
//console.log("问题:"+ q + ",有答案:"+ qRightAnswer[q]);
var rightSelection = findAnwser("tbody", index, qRightAnswer[q]) //返回答案选项label
if (rightSelection) {
rightSelection.click();
}
} else {
if (questions.hasOwnProperty(q)) {
questions[q] = getNextChoice(questions[q]);//通过Unicode数字+1切换到下一个选项,返回的是字母选项
//console.log("不知道答案:"+ q+",测试:"+questions[q]);
} else { //如果系统没有记录
questions[q] = "A";
};
var answer = getChoiceCode(questions[q]);//将字母选项转换为Unicode数字并减去A代表的65,等于选项顺序,0是第一个选项
var element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
if (!element) { //选项除错机制
console.log("找不到选项,选项更改为A index: " + index + " answer: " + answer);
questions[q] = "A";
answer = getChoiceCode("A");
element = document.querySelectorAll("tbody")[index].getElementsByTagName("label")[answer];//获取到的是4-5个选项的数组answer等于选项顺序,0是第一个选项
//document.querySelector("#gvQuestion_rbl_" + index + "_" + answer + "_" + index);
//localStorage.removeItem(keyTest)
};
try {
var answerText = element.innerText.substring(3);//"A、"占用3个字符
//console.log("测试语法:" + (answerText == element.innerText.trim().substring(2)));
//element.nextSibling.innerText.trim().substring(2); //获得当前答案文本
qTestAnswer[q] = answerText;
//console.log("qTestAnswer:"+error);
} catch (error) { console.log("答案文本获取失败A:" + error); };
if (element) {
element.click();
}
};
index = index + 1;
};
};
//存储相关记录
localStorage.setItem(keyTest, JSON.stringify(questions));
localStorage.setItem(keyTestAnswer, JSON.stringify(qTestAnswer));
setTimeout(function () {
var submitButton = document.querySelector("#btn_submit");
if (submitButton) {
submitButton.click();
}
}, (submitTime + Math.ceil(Math.random() * randomX))); //交卷延时
///专用函数区
function findAnwser(qakey, index, rightAnwserText) {
var answerslist = document.querySelectorAll(qakey)[index];
if (!answerslist) return null;
var arr = answerslist.getElementsByTagName("label");
console.log(`查找答案: ${rightAnwserText}`);
// 精确匹配
for (var i = 0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText===rightAnwserText) {
console.log(`✅ 精确匹配: ${optionText}`);
return arr[i];
}
}
// 模糊匹配
for (var i=0; i < arr.length; i++) {
var optionText=arr[i].innerText.substring(3).trim();
if (optionText.includes(rightAnwserText) || rightAnwserText.includes(optionText)) {
console.log(`🔍 模糊匹配: ${optionText}`);
return arr[i];
}
}
console.log(`❌ 未找到匹配答案,使用第一个选项`);
return arr[0];
}
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] ? $(".tips_text")[0].innerText : null;
var dds=$(".state_cour_lis");
localStorage.removeItem(keyResult);
if (res=="考试通过" || res=="考试通过!" || res=="完成项目学习可以申请学分了" ) {
console.log("考试通过");
saveRightAnwser();
SaveAllAnwser();
cleanKeyStorage();
checkExamContinuation();
setTimeout(function () {
// ...(原有代码)
}, 1000);
} else {
console.log("考试未通过")
var tipsTextElement=document.querySelector("p[class='tips_text' ]");
if (tipsTextElement) {
tipsTextElement.innerText="本次未通过,正在尝试更换答案\r\n(此为正常现象,脚本几秒后刷新,请勿操作)"
}
var qWrong={};
for (var i=0; i < dds.length; ++i) {
if (dds[i].querySelector("img") && !dds[i].querySelector("img").src.includes("bar_img")) {//这里表示否定
var rawQuestion=dds[i].querySelector("p").title;
var cleanedQuestion=cleanQuestionText(rawQuestion);
qWrong[cleanedQuestion]=i
};
};
if (qWrong !={}) {
localStorage.setItem(keyResult, JSON.stringify(qWrong));
saveRightAnwser();
setTimeout(function () {
$("input[type=button][value='重新考试' ]").click();
}, (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 qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) ||{};
var qTitle=JSON.parse(localStorage.getItem(keyThisTitle)) || "没有记录到章节名称" ;
if (qTitle=="没有记录到章节名称" ) {
console.log("没找到章节名称");
return {};
};
var qOldAnswer=qAllAnswer[qTitle] || {};
return qOldAnswer
};
// 修改题目处理逻辑,去除干扰的问号
// 统一的题目清洗函数
function cleanQuestionText(questionText) {
if (!questionText) return '' ;
// 去除各种特殊字符和空白
let cleaned=questionText
.replace(/[??]/g, '' )
.replace(/||[\u200B-\u200D\uFEFF]/g, '' ) // 去除零宽空格
.replace(/\s+/g, ' ' ) // 将多个空格合并为一个
.trim();
// 去除题目编号
cleaned=cleaned.replace(/^\d+、/, '' ).trim();
// 智能处理括号:
// 1. 只删除完全为空或只有空格的括号
// 2. 保留包含实际内容的括号
cleaned=cleaned.replace(/[((]\s*[))]/g, '' ) // 处理空括号
.replace(/[((]\s*([^))\s]+)\s*[))]/g, '$1' ) // 保留括号内的内容
.trim();
return cleaned;
}
// 修改题目获取方式,确保一致性
function getQuestionText(questionElement) {
try {
let rawText=questionElement.querySelector(".q_name").innerText;
// 去除编号部分(如"1、")
let textWithoutNumber=rawText.replace(/^\d+、/, '' );
return cleanQuestionText(textWithoutNumber);
} catch (error) {
console.log("获取题目文本错误:", error);
return "" ;
}
}
// 修改答案记录部分
function saveRightAnwser() {
var qRightAnswer=JSON.parse(localStorage.getItem(keyRightAnswer)) || {};
var qTestAnswer=JSON.parse(localStorage.getItem(keyTestAnswer)) || {};
var qWrongs=JSON.parse(localStorage.getItem(keyResult)) || {};
console.log("开始保存正确答案...");
console.log("错题记录:", qWrongs);
console.log("测试答案:", qTestAnswer);
// 构建清理后的题目映射
var cleanedWrongs={};
for (var wrongQ in qWrongs) {
var cleanedWrongQ=cleanQuestionText(wrongQ);
cleanedWrongs[cleanedWrongQ]=true;
console.log(`错题清洗: "${wrongQ}" -> "${cleanedWrongQ}"`);
}
for (var q in qTestAnswer) {
var cleanedQ = cleanQuestionText(q);
console.log(`处理题目: "${q}" -> "${cleanedQ}", 答案: ${qTestAnswer[q]}`);
if (!cleanedWrongs[cleanedQ]) {
console.log(`✅ 正确答案: "${cleanedQ}" -> ${qTestAnswer[q]}`);
qRightAnswer[cleanedQ] = qTestAnswer[q];
} else {
console.log(`❌ 错误题目: "${cleanedQ}" -> ${qTestAnswer[q]}`);
}
}
localStorage.removeItem(keyTestAnswer);
if (Object.keys(qRightAnswer).length > 0) {
localStorage.setItem(keyRightAnswer, JSON.stringify(qRightAnswer));
console.log("✅ 正确答案已保存:", qRightAnswer);
} else {
console.log("❌ 没有正确答案需要保存");
}
}
//答案记录函数区结束//
//------------------答案复制相关按钮--------------------------------------------
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")
//Aout=encodeURIComponent(Aout);
//window.prompt("请复制",Aout);
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;
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(textout);
}
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.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);
};
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
//答案复制相关按钮 end
function skipVideo() {//这是跳过视频的代码
var oVideo = document.getElementsByTagName('video')[0];
if (oVideo) {
oVideo.currentTime = oVideo.duration - 1
};
};
// 在 courseList 函数中添加导入答案按钮
function addImportAnswerBtn() {
let alink = document.createElement("a");
alink.innerHTML = '导入答案';
alink.style = btstyleB;
alink.onclick = function (event) {
var input = prompt("请粘贴要导入的答案数据(JSON格式)");
if (input) {
try {
// 解析输入的JSON数据
var importedAnswers = JSON.parse(input);
// 获取现有的答案记录
var existingAnswers = JSON.parse(localStorage.getItem(keyAllAnswer)) || {};
// 合并答案
var mergedAnswers = mergeAnswerData(existingAnswers, importedAnswers);
// 保存合并后的答案
localStorage.setItem(keyAllAnswer, JSON.stringify(mergedAnswers));
alert("✅ 答案导入成功!\n已合并 " + Object.keys(importedAnswers).length + " 个章节的答案");
} catch (error) {
alert("❌ 导入失败:数据格式不正确\n" + error);
}
}
};
var mainDiv = document.getElementById("main_div");
if (mainDiv) {
mainDiv.parentNode.append(alink);
}
};
// 合并答案数据的函数
function mergeAnswerData(existing, imported) {
// 深拷贝现有答案
var merged = JSON.parse(JSON.stringify(existing));
// 遍历导入的答案
for (var chapter in imported) {
if (imported.hasOwnProperty(chapter)) {
// 如果章节不存在,直接添加
if (!merged[chapter]) {
merged[chapter] = imported[chapter];
} else {
// 合并章节内的题目答案
for (var question in imported[chapter]) {
if (imported[chapter].hasOwnProperty(question)) {
merged[chapter][question] = imported[chapter][question];
}
}
}
}
}
return merged;
};
//------------------看视频页面主要函数-------------------------------------------
function clickexam() { //延时点击考试按钮。
console.log("已点击考试按钮");
setTimeout(function () {
var examButton = document.querySelector("#jrks");
if (examButton) {
examButton.click();
}
}, (Math.ceil(Math.random() * randomX)));
//}, (examTime + Math.ceil(Math.random() * randomX)));
};
//按钮插入函数相关
function addSkipbtn() {//插入按钮快进视频按钮
let alink = document.createElement("a");
alink.innerHTML = '快进视频';
alink.style = btstyleA;
alink.onclick = function (event) {
skipVideo();
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
};
function addratebtn(ra) {//倍率调整按钮
let alink = document.createElement("a");
alink.innerHTML = '' + ra + 'x';
alink.style = btstyleB;
alink.className = "speed";
alink.id = ra + "x";
alink.onclick = function (event) {
ratechg(ra);
try {
var arr = document.querySelectorAll("a[class='speed']");
arr.forEach(function (item, index, arr) {
arr[index].style = btstyleB;
});
} catch (error) {
};
alink.style = btstyleC;
};
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(alink);
}
}
function ratechg(ra) {//倍率调整
var videoObj = document.querySelector("video")
if (videoObj) {
try {
clearInterval(nspeed);
nspeed = setInterval(() => {
videoObj.playbackRate = ra;
}, 1 * 1000);
localStorage.setItem(keyPlayRate, ra);
//document.querySelector("a[id=" + "'" + ra + "x']").style = btstyleC;
//document.getElementById("playrate").innerHTML = "当前播放速率" + ra + "x";
//console.log("倍率调整为" + ra);
} catch (error) { console.log("倍率调整错误" + error); };
}
};
function addrateinfo() {//插入说明
let adiv1 = document.createElement("div");
adiv1.innerHTML = '当前播放速率';
adiv1.id = 'playrate';
adiv1.style = "font-size: 15px;text-align: center;margin-top: 10px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv1);
}
};
function addinfo() {//插入说明
//模式切换按钮
var moderesult = localStorage.getItem("华医mode");
if (moderesult == 2) {
moderesult = "当前模式:视频+考试";
} else {//包括了结果为1或者无存储的情况
moderesult = "当前模式:单刷视频";
};
var checkbox = document.createElement('div');
checkbox.innerHTML = '' + moderesult + '
[点击此处切换] ';
// 添加到页面的 body 元素中
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(checkbox);
}
//插入说明部分
let mode1 = document.querySelector("a[id='mode']");
if (mode1) {
mode1.onclick = function () {
if (mode1.innerText == "当前模式:单刷视频\n[点击此处切换]") {
mode1.innerText = "当前模式:视频+考试\n[点击此处切换]";
localStorage.setItem("华医mode", "2");
} else {
mode1.innerText = "当前模式:单刷视频\n[点击此处切换]";
localStorage.setItem("华医mode", "1");
};
};
}
let adiv2 = document.createElement("div");
adiv2.innerHTML = '       本人医学研一学生,经常要帮师兄师姐刷华医视频,属实太累。偶然在抖音发现Dr.S的脚本,结果刷完1个视频立刻考试,导致频繁人脸识别跟手动区别不大。原作者已不更新,于是我自学修改了播放逻辑,实现无人值守连续播放。现将原先自用的脚本分享给大家❤❤
     刷完视频再切换考试模式,即可连续考试。
';
adiv2.id = 'jsinfo';
adiv2.style = "position:relative;left:10px;top:5px;width:240px;font-size:13px;text-align: justify;border: 1px dashed #ff9595;padding:5px;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(adiv2);
}
if (typeof $ !== 'undefined') {
$('div:contains("观看视频完成后,才能进入考试")').eq(-1).text('建议360安全浏览器和脚本猫');
}
// 创建连续考试按钮的容器
let examBtnContainer = document.createElement('div');
examBtnContainer.id = 'continuousExamBtnContainer';
examBtnContainer.style = "text-align: center; margin: 10px 0;";
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv && jjDiv.parentNode) {
jjDiv.parentNode.append(examBtnContainer);
}
};
function changelayout() {
var jjDiv = document.querySelector("div[id='jj']");
if (jjDiv) {
jjDiv.remove();
}
var photoImg = document.querySelector("img[id='photo']");
if (photoImg) {
photoImg.outerHTML = `
`;
photoImg.style.width = "120px";
photoImg.style.height = "120px";
}
var titleDivs = document.querySelectorAll("div[class='title']");
if (titleDivs[0] && titleDivs[0].children[0]) {
titleDivs[0].children[0].style = "color: #ff0000;font-weight: bold";
titleDivs[0].children[0].innerText = "支持作者";
}
var imgTextDivs = document.querySelector("div[class='imgtext']");
if (imgTextDivs && imgTextDivs.children[1]) {
imgTextDivs.children[1].style.width = "125px";
imgTextDivs.children[1].style = "color: #ff0000;padding-top:10px";
imgTextDivs.children[1].innerText = "作 者\n创作优化不易\n投点小费吧\n❤谢啦❤\n❤"
}
var topDiv = document.querySelector("div[class='top']");
if (topDiv) {
topDiv.outerHTML = '如服务器调整,脚本可能失效。反馈意见、免费增加课程请在Greasyfork私信或脚本反馈区联络。也欢迎投喂↓
';
}
};
function cleanKeyStorage() {//缓存清理
localStorage.removeItem(keyTest);
localStorage.removeItem(keyResult);
localStorage.removeItem(keyTestAnswer);
localStorage.removeItem(keyRightAnswer);
};
function examherftest() {//考试按钮激活状态检测
var examButton = document.getElementById("jrks");
var hreftest = examButton ? examButton.attributes["disabled"] : null;
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if ((state == "已完成" || state == "待考试" || !hreftest) && examButton) {//value不为#说明考试按钮已经激活
console.log("已经播放完了");
// 优先处理"视频+考试"模式下的"待考试"状态
var modeElement = document.querySelector("a[id='mode']");
if (modeElement && modeElement.innerText.indexOf("视频+考试") != -1 && state == "待考试") {
console.log("mode=2,准备进入考试");
// 重试机制:尝试5次进入考试
var retryCount = 0;
var maxRetries = 5;
function tryEnterExam() {
retryCount++;
console.log(`尝试进入考试 (第${retryCount}次)`);
try {
// 方法1:尝试点击考试按钮
if (document.getElementById("jrks") && !document.getElementById("jrks").disabled) {
document.getElementById("jrks").click();
console.log("成功点击考试按钮");
return true; // 成功进入考试
}
// 方法2:尝试备用方式
if (typeof cwrid !== 'undefined') {
window.open("/pages/exam_tip.aspx?cwrid=" + cwrid, "_self");
console.log("尝试备用方式进入考试");
return true;
}
// 方法3:尝试通过URL跳转
var currentUrl = window.location.href;
if (currentUrl.includes("course_ware")) {
var examUrl = currentUrl.replace("course_ware/course_ware_", "pages/exam.aspx?cwid=")
.split("?")[0] + "?cwid=" + getUrlParam("cwid");
window.location.href = examUrl;
console.log("尝试通过URL跳转进入考试");
return true;
}
} catch (error) {
console.log(`第${retryCount}次尝试失败:`, error);
}
return false; // 进入考试失败
}
// 立即尝试第一次
if (tryEnterExam()) {
return; // 成功进入考试,直接返回
}
// 设置重试间隔
var retryInterval = setInterval(function () {
if (retryCount >= maxRetries) {
clearInterval(retryInterval);
console.log(`尝试${maxRetries}次进入考试均失败,继续听课`);
// 继续执行后续的跳转到下一个视频的逻辑
proceedToNextVideo();
} else if (tryEnterExam()) {
clearInterval(retryInterval); // 成功进入考试,停止重试
}
}, 2000); // 每2秒重试一次
} else {
// 单刷视频模式或非待考试状态,直接继续听课
proceedToNextVideo();
};
} else {//#代表考试按钮还没激活
//继续播放,无需任何操作
}
}
// 跳转到下一个视频的函数
function proceedToNextVideo() {
console.log('🚀 准备跳转到下一个视频...');
const nextCwid = getNextCourseCwid();
if (nextCwid) {
console.log(`✅ 确定跳转到课程: ${nextCwid.substring(0, 8)}...`);
console.log(`🌐 跳转URL: course_ware.aspx?cwid=${nextCwid}`);
// 延迟跳转,让用户有时间查看日志
setTimeout(() => {
console.log('⏩ 正在跳转...');
window.location.href = `course_ware.aspx?cwid=${nextCwid}`;
}, 2000);
} else {
console.log('❌ 没有找到可用的课程,尝试刷新页面');
setTimeout(() => {
console.log('🔄 正在刷新页面...');
window.location.reload();
}, 2000);
}
}
// 辅助函数:获取URL参数
function getUrlParam(name) {
var urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
};
//课堂问答跳过,临时版
function sleep(timeout) {
return new Promise((resolve) => { setTimeout(resolve, timeout); });
console.log("课堂问答循环调用");
};
function asynckillsendQuestion() {
(async function () {
while (!window.player || !window.player.sendQuestion) {
await sleep(20);
};
//console.log("课堂问答跳过插入");
player.sendQuestion = function () {
//console.log("播放器尝试弹出课堂问答,已屏蔽。");
};
})();
};
function killsendQuestion2() {
if (typeof (isInteraction) == "undefined") {
//console.log('变量未定义');
} else {
console.log('isInteraction设置off');
isInteraction = "off";
};
};
function killsendQuestion3() { //点击跳过按钮版的跳过课堂答题
var clockms = setInterval(async function () {
try {
if (typeof $ !== 'undefined' && $('.pv-ask-head').length && $('.pv-ask-head').length > 0) {
console.log("检测到问题对话框,尝试跳过");
$(".pv-ask-skip").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.signBtn').length && $('.signBtn').length > 0) {
console.log("检测到签到对话框,尝试跳过");
$(".signBtn").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' &&
$("button[onclick='closeProcessbarTip()']").length &&
$("button[onclick='closeProcessbarTip()']").length > 0 &&
$("div[id='div_processbar_tip']").css("display") == "block") {
console.log("检测到温馨提示对话框(不能拖拽),尝试跳过");//
//*[@id="div_processbar_tip"]/div/div[2]/input
//document.querySelector("#div_processbar_tip > div > div.foot_sub > input")
//#div_processbar_tip > div > div.foot_sub > input
//
$("button[onclick='closeBangZhu()']").click();
$("button[onclick='closeProcessbarTip()']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $("button[class='btn_sign']").length && $("button[class='btn_sign']").length > 0) {
console.log("检测到温馨提示对话框(疲劳提醒),尝试跳过");
$("button[class='btn_sign']").click();
};
} catch (err) {
console.log(err);
};
try {
if (typeof $ !== 'undefined' && $('.rig_btn').length && $('.rig_btn').length > 0) {
if ($('#div_processbar_tip').is(':visible')) {
console.log("检测到按钮(知道了),执行隐藏操作");
$('#div_processbar_tip').hide();
}
//$(".rig_btn").click();
};
} catch (err) {
console.log(err);
};
try {
var stateElement = document.querySelectorAll("i[id='top_play']")[0];
var state = stateElement ? stateElement.parentNode.nextElementSibling.nextElementSibling.nextElementSibling.innerText : null;
if (typeof $ !== 'undefined' &&
$('video').prop('paused') == true &&
state != "已完成" &&
state != "待考试") {
console.log("视频意外暂停,恢复播放");
$('video').get(0).play();
//$('video').prop('volumed') = 0;
$('video').prop('muted') = true;
} else if (state == "已完成") {
var videoElement = document.querySelector("video");
if (videoElement) {
videoElement.pause();
}
//clearInterval(clockms);
};
} catch (err) {
//console.log(err);
};
}, 10000);
};
function autoClickKnowButton() {
// 检测按钮是否加载完成
const observer = new MutationObserver(() => {
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
observer.disconnect(); // 停止观察
button.click(); // 点击按钮
}
});
// 开始观察文档的变化
observer.observe(document.body, {
childList: true,
subtree: true
});
// 如果按钮已经加载完成,直接点击
const button = document.querySelector("input.rig_btn[value='知道了']");
if (button) {
button.click();
}
}
// 在全局函数区添加以下函数
function saveCourseList() {
console.log('📋 开始保存/更新课程列表...');
// 尝试获取课程列表容器
const courseContainer = document.querySelector('.page-container');
if (!courseContainer) {
console.log('❌ 未找到课程列表容器');
return;
}
// 尝试获取课程项
const courseItems = document.querySelectorAll('.lis-inside-content');
if (courseItems.length === 0) {
console.log('❌ 未找到课程项');
return;
}
console.log(`📚 找到 ${courseItems.length} 个课程项,开始解析...`);
const currentCourseList = [];
let hasChanges = false;
courseItems.forEach((item, index) => {
const titleElement = item.querySelector('h2');
const statusButton = item.querySelector('button');
if (titleElement && statusButton) {
const title = titleElement.textContent.trim();
const status = statusButton.textContent.trim();
const statusColor = statusButton.style.background;
// 从onclick属性中提取cwid
const onclickAttr = titleElement.getAttribute('onclick');
let cwid = '';
if (onclickAttr) {
const match = onclickAttr.match(/cwid=([^']+)/);
if (match && match[1]) {
cwid = match[1];
}
}
if (cwid) {
currentCourseList.push({
title,
status,
statusColor,
cwid,
index
});
//console.log(` 课程 ${index + 1}: "${title}" - 状态: ${status}`);
}
}
});
if (currentCourseList.length === 0) {
console.log('❌ 未解析到任何课程信息');
return;
}
// 获取之前保存的课程列表
const previousCourseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
if (previousCourseList.length === 0) {
// 第一次保存
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`✅ 首次保存课程列表完成,共 ${currentCourseList.length} 个课程`);
return;
}
// 检查是否有变化
console.log('🔍 检查课程状态变化...');
for (let i = 0; i < currentCourseList.length; i++) {
const currentCourse=currentCourseList[i];
const previousCourse=previousCourseList[i];
if (!previousCourse) {
console.log(` 新增课程: "${currentCourse.title}" `);
hasChanges=true;
continue;
}
// 检查状态变化
if (currentCourse.status !==previousCourse.status) {
console.log(` 状态变化: "${currentCourse.title}" - ${previousCourse.status} → ${currentCourse.status}`);
hasChanges=true;
}
// 检查标题变化(可能课程有更新)
if (currentCourse.title !==previousCourse.title) {
console.log(` 标题变化: "${previousCourse.title}" → "${currentCourse.title}" `);
hasChanges=true;
}
// 检查cwid变化(理论上不应该变)
if (currentCourse.cwid !==previousCourse.cwid) {
console.log(` cwid变化: "${currentCourse.title}" `);
hasChanges=true;
}
}
// 检查课程数量变化
if (currentCourseList.length !==previousCourseList.length) {
console.log(` 课程数量变化: ${previousCourseList.length} → ${currentCourseList.length}`);
hasChanges=true;
}
if (hasChanges) {
// 更新课程列表
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
console.log(`🔄 课程列表已更新,共 ${currentCourseList.length} 个课程`);
// 输出详细的课程状态
console.log('📊 当前所有课程状态:');
currentCourseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
} else {
console.log('✅ 课程列表无变化,无需更新');
// 即使无变化,也确保本地存储的是最新数据(防止数据损坏)
localStorage.setItem('huayi_course_list', JSON.stringify(currentCourseList));
}
}
function getCurrentCourseCwid() {
// 从当前URL获取cwid
const urlParams = new URLSearchParams(window.location.search);
const cwid = urlParams.get('cwid');
console.log(`🔍 当前课程 cwid: ${cwid ? cwid.substring(0, 8) + '...' : '未找到'}`);
return cwid;
}
function getNextCourseCwid() {
console.log('🔄 开始查找下一个课程...');
// 尝试从localStorage获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
const currentCwid = getCurrentCourseCwid();
if (courseList.length === 0) {
console.log('❌ 未找到存储的课程列表');
return null;
}
console.log(`📊 课程列表中有 ${courseList.length} 个课程`);
// 找到当前课程的索引
const currentIndex = courseList.findIndex(course => course.cwid === currentCwid);
if (currentIndex === -1) {
console.log('❌ 未找到当前课程在列表中的位置');
console.log('当前课程可能不在列表中,将尝试第一个未完成的课程');
// 尝试查找第一个未完成的课程
for (let i = 0; i < courseList.length; i++) {
const course=courseList[i];
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到第一个未完成课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
return null;
}
console.log(`📍 当前课程位置: 第 ${currentIndex + 1} 个 - "${courseList[currentIndex].title}" `);
// 查找下一个未完成的课程(从当前位置向后找)
console.log('🔍 向后查找未完成的课程...');
for (let i=currentIndex + 1; i < courseList.length; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到下一个课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
// 如果后面没有未完成的课程,尝试从开头查找
console.log('🔍 向后未找到,从开头查找未完成的课程...');
for (let i=0; i < currentIndex; i++) {
const course=courseList[i];
console.log(` 检查第 ${i + 1} 个课程: "${course.title}" - 状态: ${course.status}`);
if (course.status==='未学习' || course.status==='学习中' || course.status==='待考试' ) {
console.log(`🎯 找到前面的课程: "${course.title}" (${course.status})`);
console.log(` 位置: 第 ${i + 1} 个课程`);
console.log(` cwid: ${course.cwid.substring(0, 8)}...`);
return course.cwid;
}
}
console.log('❌ 没有找到任何未完成的课程');
console.log('所有课程状态:');
courseList.forEach((course, index)=> {
console.log(` ${index + 1}. "${course.title}" - ${course.status}`);
});
return null;
}
//--------------------------插入悬浮框------------------------------------//
function advis() {
// 🔴 第一步:只在顶层窗口运行,iframe 中直接退出
if (window.self !== window.top) {
console.log('小助手:当前处于 iframe 中,不创建面板');
return;
}
// 🔴 第二步:检查是否已有面板,防止重复创建(即使脚本多次调用)
const existingPanel = document.getElementById('Div1');
if (existingPanel) {
console.log('已检测到小助手面板,防止重复创建');
return; // 或者 existingPanel.remove(); 再创建(推荐 return 即可)
}
// 🟡 第三步:创建新面板
let div1 = document.createElement("div");
div1.innerHTML = `
`;
document.body.append(div1);
// 绑定事件
let share1 = document.getElementById('Share1');
let share2 = document.getElementById('Share2');
let clo = document.getElementById('clo');
if (share1) {
share1.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/500010", "_blank");
};
}
if (share2) {
share2.onclick = function () {
window.open("https://greasyfork.org/zh-CN/scripts/555651", "_blank");
};
}
if (clo) {
clo.onclick = function () {
var panel = document.getElementById('Div1');
if (panel) {
panel.style.display = 'none';
}
};
}
// === 初始化:左对齐课程列表 ===
const panel = document.getElementById('Div1');
if (!panel) return;
const container = document.querySelector('.page-container') ||
document.querySelector('.lis-content') ||
document.querySelector('.container-inside-header');
let initialLeft = 140; // 默认值
if (container) {
const rect = container.getBoundingClientRect();
initialLeft = rect.left + window.pageXOffset;
}
panel.style.left = initialLeft + 'px';
// === 拖拽功能 ===
let isDragging = false;
let offsetX, offsetY;
panel.addEventListener('mousedown', function (e) {
if (e.target === clo ||
e.target.tagName === 'A' ||
e.target.tagName === 'IMG' ||
e.target.tagName === 'HR') return;
isDragging = true;
offsetX = e.clientX - panel.getBoundingClientRect().left;
offsetY = e.clientY - panel.getBoundingClientRect().top;
e.preventDefault();
});
document.addEventListener('mousemove', function (e) {
if (!isDragging) return;
panel.style.left = (e.clientX - offsetX) + 'px';
panel.style.top = (e.clientY - offsetY) + 'px';
});
document.addEventListener('mouseup', () => {
isDragging = false;
});
// 创建状态面板(默认隐藏)
//createStatusPanel();
//document.getElementById('examStatusPanel').style.display = 'none';
}
//--------------------------连续考试的函数------------------------------------//
// 修改 addContinuousExamButton 函数
function addContinuousExamButton() {
// 检查是否已存在连续考试按钮
if (document.getElementById('continuousExamBtn')) {
return;
}
// 创建连续考试按钮
let btn = document.createElement("a");
btn.innerHTML = '连续考试';
btn.style = btstyleA
btn.id = 'continuousExamBtn';
btn.onclick = function () {
console.log('🚀 开始连续考试流程...');
startContinuousExam();
};
// 找到建议提示框
const tipDiv = document.querySelector('div.r div[style*="border: 1px dashed #ff9595"]');
if (tipDiv) {
// 创建按钮容器
let btnContainer = document.createElement('div');
btnContainer.style = "text-align: center; margin: 10px 0;";
btnContainer.appendChild(btn);
// 将按钮容器插入到建议提示框后面
tipDiv.parentNode.insertBefore(btnContainer, tipDiv.nextSibling);
} else {
// 如果找不到建议提示框,使用预留的容器
const btnContainer = document.getElementById('continuousExamBtnContainer');
if (btnContainer) {
btnContainer.appendChild(btn);
} else {
// 如果容器也不存在,添加到页面底部
document.body.appendChild(btn);
}
}
}
// 新增:创建状态面板的函数
function createStatusPanel() {
// 检查是否存在 exam_phase
const examPhase = localStorage.getItem('exam_phase');
if (!examPhase) {
// 如果不存在 exam_phase,移除可能存在的面板
const existingPanel = document.getElementById('examStatusPanel');
if (existingPanel) {
existingPanel.remove();
}
return;
}
// 检查是否已存在状态面板
if (document.getElementById('examStatusPanel')) {
// 如果面板已存在,只需更新状态信息
updatePanelContent();
return;
}
// 创建状态面板
const panel = document.createElement('div');
panel.id = 'examStatusPanel';
panel.style = `
position: fixed;
top: 20px;
right: 20px;
width: 300px;
background-color: rgba(255, 255, 255, 0.95);
border: 2px solid #4cb0f9;
border-radius: 8px;
padding: 15px;
z-index: 10000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
font-family: 'Microsoft YaHei', sans-serif;
`;
panel.innerHTML = `
连续考试状态
加载中...
`;
// 确保面板正确插入到页面中
document.body.appendChild(panel);
// 添加取消按钮事件
var cancelBtn = document.getElementById('cancelExamBtn');
if (cancelBtn) {
cancelBtn.onclick = function () {
if (confirm('确定要取消连续考试吗?')) {
cancelContinuousExam();
}
};
}
// 更新面板内容
updatePanelContent();
// 辅助函数:更新面板内容
function updatePanelContent() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examPhase = localStorage.getItem('exam_phase');
let statusMessage = '';
if (examPhase === 'face_verification') {
statusMessage = `👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else if (examPhase === 'examination') {
statusMessage = `📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${examCourses[currentIndex]?.title || '未知课程'}`;
} else {
statusMessage = '连续考试进行中...';
}
const contentElement = document.getElementById('examStatusContent');
if (contentElement) {
contentElement.innerHTML = statusMessage;
}
}
}
// 修改:更新状态提示的函数
function updateExamStatus(message, isError = false) {
createStatusPanel(); // 确保面板存在
const panel = document.getElementById('examStatusPanel');
// 添加存在性检查
if (!panel) {
console.log('状态面板不存在,跳过更新');
return;
}
panel.style.display = 'block';
const statusContent = document.getElementById('examStatusContent');
if (statusContent) {
statusContent.innerHTML = message;
statusContent.style.color = isError ? '#f15854' : '#333';
}
}
// 取消连续考试
function cancelContinuousExam() {
console.log('❌ 结束连续考试');
// 清除相关状态
localStorage.removeItem('exam_courses');
localStorage.removeItem('current_exam_index');
localStorage.removeItem('exam_phase');
// 只有在面板存在时才更新状态
const panel = document.getElementById('examStatusPanel');
if (panel) {
updateExamStatus('连续考试已取消');
// 3秒后隐藏状态面板
setTimeout(() => {
//panel.style.display = 'none';
}, 3000);
} else {
console.log('状态面板不存在,直接清除状态');
}
}
// 连续考试主函数
function startContinuousExam() {
// 强制设置为单刷视频模式,避免冲突
localStorage.setItem("华医mode", "1");
console.log('🚀 开始连续考试流程,模式强制设置为单刷视频');
localStorage.setItem('exam_phase', 'setup'); // 设置阶段为初始化
// 创建状态面板
createStatusPanel();
// 获取课程列表
const courseList = JSON.parse(localStorage.getItem('huayi_course_list')) || [];
// 筛选待考试的课程
const examCourses = courseList.filter(course => course.status === '待考试');
if (examCourses.length === 0) {
console.log('❌ 没有找到待考试的课程');
updateExamStatus('❌ 没有找到待考试的课程', true);
localStorage.removeItem('exam_phase');
return;
}
// 保存待考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
localStorage.setItem('exam_phase', 'face_verification'); // 设置阶段为刷脸
console.log(`📋 找到 ${examCourses.length} 个待考试课程`);
updateExamStatus(`找到 ${examCourses.length} 个待考试课程
准备开始刷脸流程...`);
// 开始刷脸流程
startFaceVerificationProcess();
}
// 刷脸流程
function startFaceVerificationProcess() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有课程刷脸完成,开始连续考试');
updateExamStatus('✅ 所有课程刷脸完成
开始连续考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startFaceVerificationProcess, 1000);
return;
}
console.log(`👤 开始第 ${currentIndex + 1} 个课程刷脸: ${currentCourse.title}`);
updateExamStatus(`👤 刷脸进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开课程链接进行刷脸
window.location.href = `course_ware.aspx?cwid=${currentCourse.cwid}`;
}
// 监听页面加载,判断是否在刷脸后返回
function checkFaceVerificationReturn() {
const examPhase = localStorage.getItem('exam_phase');
const isInFaceVerification = examPhase === 'face_verification';
if (isInFaceVerification) {
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
// 只有当索引有效时才继续
if (currentIndex < examCourses.length) {
console.log('🔍 检测到刷脸后返回,继续下一个课程');
localStorage.setItem('current_exam_index', currentIndex + 1);
updateExamStatus(`✅ 刷脸完成 ${currentIndex + 1}/${examCourses.length}
准备下一个课程...`);
// 添加延迟防止过快跳转
setTimeout(startFaceVerificationProcess, 3000);
} else {
console.log('✅ 刷脸流程已完成');
updateExamStatus('✅ 刷脸流程已完成
准备开始考试...');
localStorage.setItem('exam_phase', 'examination');
localStorage.setItem('current_exam_index', 0);
startAllExams();
}
}
}
// 开始所有考试
function startAllExams() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
if (examCourses.length === 0) {
console.log('❌ 没有待考试的课程');
updateExamStatus('❌ 没有待考试的课程', true);
return;
}
console.log('🎯 开始连续考试流程');
updateExamStatus(`🎯 开始连续考试流程
共 ${examCourses.length} 个考试待完成`);
// 保存考试课程列表和当前索引
localStorage.setItem('exam_courses', JSON.stringify(examCourses));
localStorage.setItem('current_exam_index', 0);
// 开始第一个考试
startNextExam();
}
// 开始下一个考试
function startNextExam() {
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
// 添加边界检查
if (currentIndex >= examCourses.length || examCourses.length === 0) {
console.log('✅ 所有考试完成!');
updateExamStatus('✅ 所有考试完成!
连续考试流程结束');
cancelContinuousExam();
return;
}
const currentCourse = examCourses[currentIndex];
if (!currentCourse || !currentCourse.cwid) {
console.log('❌ 无效的课程数据,跳过');
localStorage.setItem('current_exam_index', currentIndex + 1);
setTimeout(startNextExam, 1000);
return;
}
console.log(`📝 开始第 ${currentIndex + 1} 个考试: ${currentCourse.title}`);
updateExamStatus(`📝 考试进度: ${currentIndex + 1}/${examCourses.length}
正在处理: ${currentCourse.title}`);
// 打开考试页面
window.location.href = `/pages/exam.aspx?cwid=${currentCourse.cwid}`;
}
// 在考试结果页面检查是否需要继续下一个考试
function checkExamContinuation() {
const examPhase = localStorage.getItem('exam_phase');
const isInExamMode = examPhase === 'examination';
if (isInExamMode) {
console.log('🔍 检测到考试完成,准备下一个考试');
// 增加索引
const currentIndex = parseInt(localStorage.getItem('current_exam_index')) || 0;
const examCourses = JSON.parse(localStorage.getItem('exam_courses')) || [];
localStorage.setItem('current_exam_index', currentIndex + 1);
// 更新状态提示
updateExamStatus(`✅ 考试完成 ${currentIndex + 1}/${examCourses.length}
准备下一个考试...`);
// 短暂延迟后继续下一个考试
setTimeout(() => {
startNextExam();
}, 3000);
}
}
//---------------------------------全局函数区end------------------------------//
})();