Greasy Fork

河北教师继续教育2024

自动过验证码、无人值守、学完主要课程自动开展20学时学习(测试中)。

目前为 2025-01-21 提交的版本。查看 最新版本

// ==UserScript==
// @name         河北教师继续教育2024
// @namespace    http://tampermonkey.net/
// @version      4.0.3
// @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
// @require      https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js
// ==/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();
                console.log('已点击元素:', selector);
                return true;
            }
            console.log('未找到元素:', selector);
            return false;
        },
        // 检查页面内容
        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;
                }
            }
        }
    };

    // 第一个脚本:验证信息提交、自动点击按钮等
    (function () {
        const checkAndSubmit = () => {
            if ($("div:contains('验证信息')").length > 1) {
                console.log("检测到学习验证");
                $("#code").attr("value", $("#codespan").text());
                $("a:contains('提交')")[0].click();
            }
        };

        const checkAndClickOk = () => {
            const okButton = $('a:contains("Ok,我知道了!")')[0];
            if (okButton) {
                utils.safeClick(okButton);
                $(".ccH5TogglePlay").click();
                console.log("rePlay success!!!");
            }
        };

        const checkCoursePage = () => {
            const href = location.href;
            if (href.includes("/course/showCourse/")) {
                const enterCourseButton = $(".button-hui")[0];
                if (enterCourseButton && enterCourseButton.innerText === "进入课程学习") {
                    utils.safeClick(enterCourseButton);
                }
            } else if (href.includes("/course/learn/")) {
                if (window.TimeNum >= 1200) {
                    alert("可以提交了");
                }
            }
        };

        const checkAndClickExpand = () => {
            const expandButton = $('span.step:contains("展开")')[0];
            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() {
        let clickCount = 0; // 计数器,限制点击次数
        const maxClicks = 10; // 最大点击次数

        const checkAndClickReplayBtn = () => {
            if (clickCount >= maxClicks) {
                console.log('已达到最大点击次数,停止点击replaybtn按钮');
                return;
            }

            const replayBtn = document.getElementById('replaybtn');
            if (replayBtn) {
                if (utils.safeClick(replayBtn)) {
                    console.log('已点击replaybtn按钮');
                    clickCount++; // 增加点击计数
                }
                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 () {
        const checkAndClickLearningPlan = () => {
            // 检测页面中是否存在“最长可累计时间”
            if (utils.checkPageContent('最长可累计时间:')) {
                console.log('检测到“最长可累计时间”,继续检测是否达到累计上限');

                // 检测是否存在“已达到累计上限”
                if (utils.checkPageContent('已达到累计上限')) {
                    console.log('检测到“已达到累计上限”,查找“学习计划”元素');

                    // 查找包含特定 class 和 data-type 的 <li> 元素
                    const learningPlanItem = document.querySelector('li.cur a[data-type="学习计划"]');
                    if (learningPlanItem) {
                        console.log('找到“学习计划”元素,准备点击');

                        // 确保在原窗口打开
                        if (learningPlanItem.target === '_blank') {
                            learningPlanItem.target = '_self'; // 修改为原窗口打开
                        }

                        // 点击“学习计划”超链接
                        if (utils.safeClick(learningPlanItem)) {
                            console.log('已点击“学习计划”超链接');
                        } else {
                            console.log('点击“学习计划”超链接失败');
                        }
                    } else {
                        console.log('未找到“学习计划”元素');
                    }
                } else {
                    console.log('未检测到“已达到累计上限”');
                }
            } else {
                console.log('未检测到“最长可累计时间”,不执行操作');
            }
        };

        // 每隔15秒检查一次
        setInterval(checkAndClickLearningPlan, 15000);
    })();

    // 第八个脚本:自动点击“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() {
            // 检查页面中是否存在“未学习”或“学习中”
            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();
    })();
})();