// ==UserScript== // @name 河北教师继续教育2024 // @namespace http://tampermonkey.net/ // @version 3.4 // @description 自动过验证码、无人值守、学完主要课程自动开展20学时学习(测试中)。 // @author 金子 // @match *://*.stu.teacher.com.cn/* // @icon https://www.google.com/s2/favicons?sz=64&domain=bing.com // @grant none // @license MIT // @require https://code.jquery.com/jquery-3.6.0.min.js // @downloadURL none // ==/UserScript== /* global $ */ // 告诉 ESLint,$ 是全局变量 (function () { 'use strict'; // 通用工具函数 const utils = { // 延迟执行函数 delay: (ms) => new Promise(resolve => setTimeout(resolve, ms)), // 随机延迟 randomDelay: (min, max) => Math.floor(Math.random() * (max - min)) + min, // 检查元素是否存在 elementExists: (selector) => document.querySelector(selector) !== null, // 点击元素 clickElement: (selector) => { const element = document.querySelector(selector); if (element) element.click(); }, // 检查页面内容 checkPageContent: (content) => document.body.innerText.includes(content), // 记录上一次点击的时间 lastClickTime: 0, // 确保在指定时间内只执行一次点击 safeClick: (element, minInterval = 5000) => { const now = Date.now(); if (now - utils.lastClickTime >= minInterval) { utils.lastClickTime = now; if (element && typeof element.click === 'function') { element.click(); console.log('已安全点击元素:', element); return true; } } else { console.log('点击过于频繁,跳过本次点击'); } return false; }, // 检测重复页面并关闭 checkDuplicatePages: () => { const currentUrl = window.location.href; const allWindows = window.top.window; // 获取顶层窗口 const openedUrls = []; // 遍历所有窗口,检查是否有重复的URL for (let i = 0; i < allWindows.length; i++) { const win = allWindows[i]; if (win.location.href === currentUrl && win !== window) { console.log('检测到重复页面,关闭当前页面'); window.close(); // 关闭当前页面 return; } } }, // 记录上一次刷新时间 lastRefreshTime: 0, // 安全刷新 safeRefresh: (minInterval = 10000) => { const now = Date.now(); if (now - utils.lastRefreshTime >= minInterval) { utils.lastRefreshTime = now; window.location.reload(); console.log('已安全刷新页面'); return true; } else { console.log('刷新过于频繁,跳过本次刷新'); return false; } } }; // 第一个脚本:验证信息提交、自动点击按钮等 (function () { const checkAndSubmit = () => { if ($("div:contains('验证信息')").length > 1) { console.log("检测到学习验证"); $("#code").attr("value", $("#codespan").text()); $("a:contains('提交')")[0].click(); } }; const checkAndClickOk = () => { const okButton = document.querySelector('a:contains("Ok,我知道了!")'); if (okButton) { utils.safeClick(okButton); document.querySelector(".ccH5TogglePlay").click(); console.log("rePlay success!!!"); } }; const checkCoursePage = () => { const href = location.href; if (href.includes("/course/showCourse/")) { const enterCourseButton = document.querySelector(".button-hui"); if (enterCourseButton && enterCourseButton.innerText === "进入课程学习") { utils.safeClick(enterCourseButton); } } else if (href.includes("/course/learn/")) { if (window.TimeNum >= 1200) { alert("可以提交了"); } } }; const checkAndClickExpand = () => { const expandButton = document.querySelector('span.step:contains("展开")'); if (expandButton) { utils.safeClick(expandButton); console.log('已点击“展开”按钮'); // 展开操作完成后,延迟 20 秒执行第八个脚本 setTimeout(() => { console.log('展开操作完成,20秒后执行第八个脚本'); runEighthScript(); }, 20000); // 20秒后执行 } }; setInterval(() => { checkAndSubmit(); checkAndClickOk(); checkCoursePage(); checkAndClickExpand(); }, 15000); // 调整为15秒 })(); // 第二个脚本:点击“学习中”按钮 async function runSecondScript() { const targetElements = document.querySelectorAll('li i.icon_2'); for (const targetElement of targetElements) { if (targetElement.textContent === '学习中') { const targetButton = targetElement.closest('li').querySelector('a[onclick*="countLearn"]'); if (targetButton) { const delay = utils.randomDelay(15000, 20000); // 调整为15-20秒 await utils.delay(delay); if (targetButton.tagName === 'A' && targetButton.target === '_blank') { targetButton.target = '_self'; // 修改为原窗口打开 } if (utils.safeClick(targetButton)) { console.log('已点击“学习中”按钮'); const courseLink = targetElement.closest('li').querySelector('a.list-title'); if (courseLink && courseLink.href) { window.location.href = courseLink.href; // 在原窗口打开 } utils.checkDuplicatePages(); // 检测重复页面 return true; // 找到“学习中”状态并点击后返回 true } } } } return false; // 未找到“学习中”状态返回 false } // 第三个脚本:点击“未学习”按钮 async function runThirdScript() { const targetElements = document.querySelectorAll('li i.icon_0'); for (const targetElement of targetElements) { if (targetElement.textContent === '未学习') { const targetButton = targetElement.closest('li').querySelector('a[onclick*="countLearn"]'); if (targetButton) { const delay = utils.randomDelay(15000, 20000); // 调整为15-20秒 await utils.delay(delay); // 确保在原窗口打开 if (targetButton.tagName === 'A' && targetButton.target === '_blank') { targetButton.target = '_self'; // 修改为原窗口打开 } if (utils.safeClick(targetButton)) { console.log('已点击“未学习”按钮'); utils.checkDuplicatePages(); // 检测重复页面 return; // 找到第一个后立即返回,停止后续查找 } } } } } // 第四个脚本:自动点击视频项 function runFourthScript() { const autoClickVideoItem = () => { const videoItems = document.querySelectorAll('li[data-type="视频"], li[data-type="1"]'); videoItems.forEach(item => { if (item.onclick || item.getAttribute('onclick')) { if (utils.safeClick(item)) { console.log('已点击视频项:', item); utils.checkDuplicatePages(); // 检测重复页面 } } }); }; setTimeout(() => { autoClickVideoItem(); setInterval(autoClickVideoItem, 1200000); // 大于15秒,不做调整 }, 20000); // 调整为20秒 } // 第五个脚本:自动点击replaybtn按钮 function runFifthScript() { const checkAndClickReplayBtn = () => { const replayBtn = document.getElementById('replaybtn'); if (replayBtn) { if (utils.safeClick(replayBtn)) { console.log('已点击replaybtn按钮'); } const nextDelay = utils.randomDelay(15000, 20000); // 调整为15-20秒 setTimeout(checkAndClickReplayBtn, nextDelay); } else { const nextDelay = utils.randomDelay(15000, 20000); // 调整为15-20秒 setTimeout(checkAndClickReplayBtn, nextDelay); } }; checkAndClickReplayBtn(); } // 第六个脚本:自动刷新学习时间 (function () { const refreshButton = document.querySelector('div.fr button.btn.studyCourseTimeRefresh'); if (refreshButton) { const clickButton = () => { if (!utils.checkPageContent('最长可累计时间:')) { if (utils.safeClick(refreshButton)) { console.log('已触发“刷新学习时间”按钮点击。'); } } }; clickButton(); setInterval(clickButton, 600000); // 大于15秒,不做调整 } })(); // 第七个脚本:检测学习状态并刷新页面 (function () { let hasClicked = false; let refreshCount = 0; const maxRefreshCount = 1; const checkLearningStatus = () => { const unlearned = document.querySelector('.icon_0'); const learning = document.querySelector('.icon_2'); return !!(unlearned || learning); }; const clickThirdPhaseButton = () => { const thirdPhaseButton = document.querySelector('li[data-value="4032"]'); if (thirdPhaseButton && !hasClicked) { if (utils.safeClick(thirdPhaseButton)) { hasClicked = true; } } }; const checkAndClickStudyPlan = () => { if (utils.checkPageContent('最长可累计时间:')) { if (utils.checkPageContent('已达到累计上限')) { const studyPlanLink = document.querySelector('a[href*="/studyPlan/intoStudentStudy"]'); if (studyPlanLink) { if (utils.safeClick(studyPlanLink)) { console.log('已点击学习计划链接'); return true; // 点击成功后返回 true } } } } return false; // 未找到或未点击返回 false }; const main = () => { // 如果页面包含“最长可累计时间”,则不执行刷新操作 if (utils.checkPageContent('最长可累计时间:')) { console.log('当前页面包含“最长可累计时间”,跳过刷新操作'); checkAndClickStudyPlan(); // 检查并点击学习计划 return; } // 如果页面包含“未学习”或“学习中”,则不执行刷新操作 if (checkLearningStatus()) { console.log('当前页面包含“未学习”或“学习中”,跳过刷新操作'); return; } // 如果没有点击过第三阶段按钮且刷新次数未达到上限,则执行刷新 if (!hasClicked && refreshCount < maxRefreshCount) { refreshCount++; setTimeout(() => window.location.reload(), 10000); // 10秒后刷新 console.log('执行页面刷新操作'); } // 点击第三阶段按钮 clickThirdPhaseButton(); }; setInterval(main, 12000); // 12秒执行一次 })(); // 第八个脚本:自动点击“20学时培训”并进入学习(原窗口打开) function runEighthScript() { // 查找页面中是否存在“未学习”或“学习中”字段 function checkLearningStatus() { const pageText = document.body.innerText; const keywords = ["未学习", "学习中"]; return keywords.some(keyword => pageText.includes(keyword)); } // 查找并点击“20学时培训” function click20HourTraining() { const trainingItems = document.querySelectorAll('.selectItemSecond li'); for (const item of trainingItems) { if (item.innerText.includes("20学时培训")) { item.click(); // 点击“20学时培训” console.log("已点击:20学时培训"); break; } } } // 查找并点击符合条件的课程 function clickCourse() { // 查找“学习中”的课程 const learningCourse = document.querySelector('li i.icon_2'); if (learningCourse) { const courseLink = learningCourse.closest('li').querySelector('a[onclick="countLearn(this)"]'); if (courseLink) { courseLink.removeAttribute('target'); // 移除 target="_blank",确保在原窗口打开 courseLink.click(); // 点击“进入学习” console.log("已点击:学习中课程"); return; // 找到一个后立即返回,避免重复操作 } } // 如果没有“学习中”的课程,查找“未学习”的课程 const unlearnedCourse = document.querySelector('li i.icon_0'); if (unlearnedCourse) { const courseLink = unlearnedCourse.closest('li').querySelector('a[onclick="countLearn(this)"]'); if (courseLink) { courseLink.removeAttribute('target'); // 移除 target="_blank",确保在原窗口打开 courseLink.click(); // 点击“进入学习” console.log("已点击:未学习课程"); return; // 找到一个后立即返回,避免重复操作 } } console.log("未找到符合条件的课程"); } // 主逻辑 function main() { // 如果上面的脚本刚刚执行过刷新操作,则跳过本次操作 const now = Date.now(); if (now - utils.lastRefreshTime < 10000) { console.log("上面的脚本刚刚执行过刷新操作,跳过本次操作"); return; } // 检查页面中是否存在“未学习”或“学习中” if (!checkLearningStatus()) { console.log("未找到“未学习”或“学习中”字段,执行点击操作..."); click20HourTraining(); // 等待5秒后查找并点击课程 setTimeout(() => { console.log("等待5秒后查找并点击课程..."); clickCourse(); }, 5000); // 5秒后执行 } else { console.log("页面中存在“未学习”或“学习中”字段,不执行点击操作。"); } } // 执行主逻辑 main(); } // 控制脚本执行顺序 (async () => { const isLearningDetected = await runSecondScript(); if (!isLearningDetected) { await runThirdScript(); } runFourthScript(); runFifthScript(); })(); })();