Greasy Fork

Greasy Fork is available in English.

华医网助手(自动跳转优化版)v2.2.1

自动播放华医网视频,跳过弹窗,状态面板,智能跳课

当前为 2025-06-01 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         华医网助手(自动跳转优化版)v2.2.1
// @namespace    http://tampermonkey.net/
// @version      2.2.1
// @description  自动播放华医网视频,跳过弹窗,状态面板,智能跳课
// @author       Yik Liu
// @match        *://*.91huayi.com/course_ware/course_ware_polyv.aspx?*
// @match        *://*.91huayi.com/course_ware/course_list.aspx?*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    let examErrorCount = 0;
    let lastActivityTime = Date.now();

    function createStatusPanel() {
        const panel = document.createElement("div");
        panel.id = "huayi-status";
        panel.style.cssText = `
            position: fixed; right: 10px; bottom: 10px; z-index: 9999;
            background: rgba(0,0,0,0.75); color: #fff; padding: 10px;
            border-radius: 10px; font-size: 14px; max-width: 250px;
        `;
        panel.innerHTML = `
            <div><b>华医网助手状态</b></div>
            <div id="h-status">状态: 启动中</div>
            <div id="h-action">操作: -</div>
            <div id="h-exam">考试按钮: -</div>
            <div id="h-error">异常检测: 0 次</div>
            <div id="h-title">当前视频: -</div>
            <button id="h-next" style="margin-top:5px;">强制下一课</button>
        `;
        document.body.appendChild(panel);

        document.getElementById("h-next").onclick = () => {
            autoJumpToLearningVideo();
        };
    }

    function updateStatusPanel(status, action, exam, errors, title) {
        document.getElementById("h-status").innerText = `状态: ${status}`;
        document.getElementById("h-action").innerText = `操作: ${action}`;
        document.getElementById("h-exam").innerText = `考试按钮: ${exam}`;
        document.getElementById("h-error").innerText = `异常检测: ${errors} 次`;
        document.getElementById("h-title").innerText = `当前视频: ${title}`;
    }

    function autoSkipPopup() {
        setInterval(() => {
            try {
                document.querySelector(".pv-ask-skip")?.click();
                document.querySelector(".signBtn")?.click();
                document.querySelector("button[onclick='closeProcessbarTip()']")?.click();
                document.querySelector("button.btn_sign")?.click();
                if (document.querySelector("#floatTips")?.style.display !== "none") {
                    window.closeFloatTips?.();
                }
            } catch (err) {
                console.warn("弹窗跳过失败:", err);
            }
        }, 2000);
    }

    function autoPlayVideo() {
        const video = document.querySelector("video");
        if (!video) return;

        video.volume = 0;
        video.muted = true;

        setInterval(() => {
            if (video.paused) {
                video.play().catch(() => {});
            }
        }, 1000);

        video.addEventListener("ended", () => {
            updateStatusPanel("监控中", "播放结束", "检测中", examErrorCount, document.title);
            setTimeout(() => {
                autoJumpToLearningVideo();
            }, 10000); // 10秒延迟
        });

        video.addEventListener("play", () => {
            lastActivityTime = Date.now();
            updateStatusPanel("监控中", "播放中", "检测中", examErrorCount, document.title);
        });
    }

    function monitorInactivity() {
        setInterval(() => {
            const now = Date.now();
            const video = document.querySelector("video");
            const time = video?.currentTime || 0;

            if (now - lastActivityTime > 3 * 60 * 1000 || time === 0) {
                examErrorCount++;
                updateStatusPanel("无响应", "无操作/暂停", "检测中", examErrorCount, document.title);
                if (video?.paused) video.play();
            }

            lastActivityTime = now;
        }, 3 * 60 * 1000);
    }

    function monitorExamButton() {
        setInterval(() => {
            const btn = document.getElementById("jrks");
            const disabled = btn?.getAttribute("disabled");
            const examAvailable = disabled ? "不可用" : "可用";
            updateStatusPanel("监控中", "检测考试按钮", examAvailable, examErrorCount, document.title);
            if (!disabled) {
                try {
                    autoJumpToLearningVideo();
                } catch {
                    examErrorCount++;
                }
            }
        }, 5000);
    }

    function autoJumpToLearningVideo() {
        const items = document.querySelectorAll('li.lis-inside-content');
        let target = null;
        let status = '';
        let index = -1;

        for (let i = 0; i < items.length; i++) {
            const text = items[i].innerText;
            if (text.includes('学习中')) {
                target = items[i];
                status = '学习中';
                index = i;
                break;
            }
        }

        if (!target) {
            for (let i = 0; i < items.length; i++) {
                const text = items[i].innerText;
                if (text.includes('未学习')) {
                    target = items[i];
                    status = '未学习';
                    index = i;
                    break;
                }
            }
        }

        if (!target) {
            updateStatusPanel("待命", "所有课程完成", "-", examErrorCount, document.title);
            return;
        }

        const h2 = target.querySelector('h2.must-text');
        if (h2) {
            h2.click();
            updateStatusPanel("跳转中", `点击第 ${index + 1} 个【${status}】`, "-", examErrorCount, document.title);
        }
    }

    function addDonationPanel() {
        const panel = document.createElement("div");
        panel.style.cssText = `
            position: fixed;
            bottom: 20px;
            left: 20px;
            background: rgba(255, 255, 255, 0.95);
            padding: 10px 15px;
            border-radius: 12px;
            box-shadow: 0 0 10px rgba(0,0,0,0.2);
            z-index: 99999;
            font-family: sans-serif;
            color: #000;
            font-size: 14px;
            max-width: 200px;
            text-align: center;
        `;

        panel.innerHTML = `
            <div style="font-size: 16px; font-weight: bold; color: red; margin-bottom: 5px;">
                如果没有时间可加v:xxsrjbhyw
            </div>
            <img src="https://i.ibb.co/CKgvr8WW/20250601161310.jpg" alt="打赏二维码" style="width: 150px; border-radius: 8px;">
            <div style="margin-top: 6px; font-style: italic;">创作不易,感谢买咖啡的钱 ☕</div>
        `;

        document.body.appendChild(panel);
    }

    function init() {
        const url = window.location.href;

        if (url.includes("course_ware/course_ware_polyv.aspx")) {
            setTimeout(() => {
                if (!document.querySelector("video")) return;

                createStatusPanel();
                autoSkipPopup();
                autoPlayVideo();
                monitorInactivity();
                monitorExamButton();
                updateStatusPanel("运行中", "初始化完成", "检测中", examErrorCount, document.title);
                addDonationPanel(); // 添加打赏信息
            }, 2000);
        }

        if (url.includes("course_ware/course_list.aspx")) {
            setTimeout(() => {
                autoJumpToLearningVideo();
            }, 3000);
        }
    }

    init();
})();