ahgbjy自动学习

ahgbjy自动学习脚本V1.0.1优化版:支持自动选课、自动学习、防休眠、智能课程切换等功能

// ==UserScript==
// @name         ahgbjy自动学习
// @namespace    http://tampermonkey.net/
// @version      1.0.1
// @description  ahgbjy自动学习脚本V1.0.1优化版:支持自动选课、自动学习、防休眠、智能课程切换等功能
// @author       Moker32
// @license      GPL-3.0-or-later
// @match        https://www.ahgbjy.gov.cn/*
// @icon         https://www.ahgbjy.gov.cn/commons/img/index/favicon.ico
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        unsafeWindow
// @noframes
// @run-at       document-start
// ==/UserScript==

/**
 * ┌─────────────────────────────────────────────────────────────────────────┐
 * │                        ahgbjy自动学习 V1.0.1                            │
 * │                        Released: 2025-06-13                            │
 * │                        Updated: 2025-06-27                             │
 * └─────────────────────────────────────────────────────────────────────────┘
 * 
 * ✨ 核心特性
 * ├─ 🎯 智能选课:优先选择"学习中"状态课程,支持自动翻页
 * ├─ 📚 自动学习:完整章节学习流程,精确时间计算
 * ├─ 😴 防休眠:Wake Lock API + 多重备用机制
 * ├─ 🔄 课程切换:智能切换下一门课程,支持必修/选修
 * ├─ 🎨 简洁UI:实时状态显示,精确倒计时
 * └─ 🛡️  高稳定:统一错误处理,自动重试机制
 * 
 * 🏗️ 架构设计
 * ├─ VideoAutoplayBlocker  → 视频播放控制
 * ├─ WakeLockManager       → 防休眠系统
 * ├─ BackgroundMonitor     → 后台保活监控
 * ├─ Utils                 → 统一工具函数
 * ├─ UI                    → 用户界面管理
 * ├─ CourseHandler         → 课程处理引擎
 * └─ Router                → 页面路由控制
 * 
 * 💡 V1.0.1 优化亮点
 * • 手动操作适应性:支持混合使用模式
 * • 登录页面保护:智能暂停避免干扰
 * • 时间计算优化:100%完整时长 + 1分钟安全余量
 * • 存储优化:直接使用数组存储,提升性能
 * • 备用机制优化:智能检测页面变化,避免重复操作
 * • 定时器简化:移除复杂定时器替换,依赖Wake Lock保活
 */

(function() {
    'use strict';

    // ════════════════════════════════════════════════════════════════════════
    //                            🎥 视频控制模块
    // ════════════════════════════════════════════════════════════════════════
    const VideoAutoplayBlocker = {
        init: () => {
            Utils.safeExecute(() => {
                console.log('视频自动播放阻止器启动');
                VideoAutoplayBlocker.blockAutoplay();
                VideoAutoplayBlocker.blockVideoPopups();
            }, '视频阻止器初始化失败');
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    阻止视频自动播放                              │
        // └─────────────────────────────────────────────────────────────────┘
        blockAutoplay: () => {
            Utils.safeExecute(() => {
                // 设置现有视频
                document.addEventListener('DOMContentLoaded', () => {
                    const videos = document.querySelectorAll('video');
                    videos.forEach(video => {
                        video.autoplay = false;
                        video.muted = true;
                    });
                });
                
                // 监控新增视频
                const observer = new MutationObserver(mutations => {
                    mutations.forEach(mutation => {
                        mutation.addedNodes.forEach(node => {
                            if (node.nodeType === 1) {
                                if (node.tagName === 'VIDEO') {
                                    node.autoplay = false;
                                    node.muted = true;
                                }
                                if (node.querySelectorAll) {
                                    node.querySelectorAll('video').forEach(video => {
                                        video.autoplay = false;
                                        video.muted = true;
                                    });
                                }
                            }
                        });
                    });
                });
                
                if (document.body) {
                    observer.observe(document.body, { childList: true, subtree: true });
                }
                
                console.log('视频自动播放已阻止');
            }, '阻止视频自动播放失败');
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    阻止视频弹窗                                  │
        // └─────────────────────────────────────────────────────────────────┘
        blockVideoPopups: () => {
            Utils.safeExecute(() => {
                const popupSelectors = [
                    '.video-popup', '.video-ad', '.video-overlay',
                    '.player-popup', '.media-popup', '.video-dialog'
                ];
                
                const hidePopups = () => {
                    popupSelectors.forEach(selector => {
                        const elements = document.querySelectorAll(selector);
                        elements.forEach(element => {
                            if (element) {
                                element.style.display = 'none !important';
                            }
                        });
                    });
                };
                
                hidePopups();
                setInterval(hidePopups, 5000);
                console.log('视频弹窗阻止器已启动');
            }, '视频弹窗阻止设置失败');
        }
    };

    // ════════════════════════════════════════════════════════════════════════
    //                            🛠️  防休眠系统
    // ════════════════════════════════════════════════════════════════════════
    const WakeLockManager = {
        wakeLock: null,
        fallbackInterval: null,
        
        init: () => {
            Utils.safeExecute(() => {
                WakeLockManager.requestWakeLock();
                WakeLockManager.setupFallbackKeepAwake();
                WakeLockManager.handleVisibilityChange();
                console.log('防休眠系统已启动');
            }, '防休眠初始化失败');
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    Wake Lock API                                │
        // └─────────────────────────────────────────────────────────────────┘
        requestWakeLock: async () => {
            try {
                if ('wakeLock' in navigator) {
                    WakeLockManager.wakeLock = await navigator.wakeLock.request('screen');
                    console.log('Wake Lock已激活,系统保持唤醒状态');
                    
                    WakeLockManager.wakeLock.addEventListener('release', () => {
                        console.log('Wake Lock已释放');
                    });
                } else {
                    console.log('浏览器不支持Wake Lock API,使用备用方案');
                }
            } catch (error) {
                console.log('Wake Lock请求失败,使用备用方案');
            }
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    备用防休眠机制                                │
        // └─────────────────────────────────────────────────────────────────┘
        setupFallbackKeepAwake: () => {
            Utils.safeExecute(() => {
                // 定期活动保持系统唤醒
                WakeLockManager.fallbackInterval = setInterval(() => {
                    // 轻微的DOM活动
                    document.title = document.title;
                    
                    // 偶尔发送心跳请求
                    if (Math.random() < 0.1) {
                        fetch(window.location.href, { method: 'HEAD' }).catch(() => {});
                    }
                }, 30000);
                
                console.log('备用防休眠机制已启动');
            }, '备用防休眠设置失败');
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    页面可见性处理                                │
        // └─────────────────────────────────────────────────────────────────┘
        handleVisibilityChange: () => {
            document.addEventListener('visibilitychange', async () => {
                if (!document.hidden && !WakeLockManager.wakeLock) {
                    await WakeLockManager.requestWakeLock();
                }
            });
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    系统清理                                      │
        // └─────────────────────────────────────────────────────────────────┘
        cleanup: () => {
            Utils.safeExecute(() => {
                if (WakeLockManager.wakeLock) {
                    WakeLockManager.wakeLock.release();
                    WakeLockManager.wakeLock = null;
                }
                
                if (WakeLockManager.fallbackInterval) {
                    clearInterval(WakeLockManager.fallbackInterval);
                    WakeLockManager.fallbackInterval = null;
                }
                
                console.log('防休眠系统已清理');
            }, '防休眠清理失败');
        }
    };

    // ════════════════════════════════════════════════════════════════════════
    //                            📱 后台监控系统
    // ════════════════════════════════════════════════════════════════════════
    const BackgroundMonitor = {
        isVisible: !document.hidden,
        backgroundTime: 0,
        pendingActions: new Map(),
        keepAliveWorker: null,
        
        init: () => {
            Utils.safeExecute(() => {
                // 页面可见性监控
                document.addEventListener('visibilitychange', BackgroundMonitor.handleVisibilityChange);
                
                // 简化的定时器替换
                BackgroundMonitor.replaceTimers();
                
                // Web Worker保活
                BackgroundMonitor.createKeepAliveWorker();
                
                // 添加页面状态强制检查
                BackgroundMonitor.forceCheckPageState();
                
                console.log('双重后台监控系统已启动');
            }, '后台监控初始化失败');
        },
        
        handleVisibilityChange: () => {
            Utils.safeExecute(() => {
                BackgroundMonitor.isVisible = !document.hidden;
                const status = BackgroundMonitor.isVisible ? '前台' : '后台';
                console.log(`页面状态切换: ${status}`);
                UI.updateBackgroundStatus(!BackgroundMonitor.isVisible);
                
                if (!BackgroundMonitor.isVisible) {
                    BackgroundMonitor.backgroundTime = Date.now();
                    console.log('页面进入后台');
                } else {
                    console.log('页面恢复前台,检查待执行动作');
                    BackgroundMonitor.processPendingActions();
                }
            }, '可见性变化处理失败');
        },
        
        // 简化的Web Worker保活(单一版本)
        createKeepAliveWorker: () => {
            Utils.safeExecute(() => {
                const workerScript = `
                    let interval = null;
                    let isActive = true;
                    
                    const startKeepAlive = () => {
                        interval = setInterval(() => {
                            if (isActive) {
                                postMessage({type: 'tick', timestamp: Date.now()});
                            }
                        }, 1000);
                    };
                    
                    startKeepAlive();
                    
                    self.onmessage = function(e) {
                        if (e.data === 'stop') {
                            isActive = false;
                            if (interval) clearInterval(interval);
                        }
                    };
                `;
                
                const blob = new Blob([workerScript], { type: 'application/javascript' });
                const worker = new Worker(URL.createObjectURL(blob));
                
                worker.onmessage = (e) => {
                    if (e.data.type === 'tick') {
                        BackgroundMonitor.checkPendingActions();
                    }
                };
                
                BackgroundMonitor.keepAliveWorker = worker;
                console.log('Web Worker保活已启动');
            }, 'Web Worker创建失败');
        },
        
        // 简化的定时器替换(优化版本)
        replaceTimers: () => {
            Utils.safeExecute(() => {
                // 由于已有 Wake Lock API 和 Web Worker 保活机制,简化定时器替换逻辑
                console.log('定时器管理已简化,依赖Wake Lock和Web Worker保活');
            }, '定时器替换失败');
        },
        
        // 简化的后台动作调度
        scheduleBackgroundAction: (actionId, callback, delay = 0) => {
            const action = {
                id: actionId,
                callback: callback,
                scheduledTime: Date.now() + delay,
                executed: false
            };
            
            BackgroundMonitor.pendingActions.set(actionId, action);
            console.log(`注册后台动作: ${actionId}, 延迟: ${delay}ms`);
            
            // 延迟执行
            setTimeout(() => {
                if (!action.executed) {
                    Utils.safeExecute(callback, `动作执行失败: ${actionId}`);
                    action.executed = true;
                    BackgroundMonitor.pendingActions.delete(actionId);
                }
            }, delay);
            
            return actionId;
        },
        
        // 检查待执行动作
        checkPendingActions: () => {
            Utils.safeExecute(() => {
                const now = Date.now();
                for (const [actionId, action] of BackgroundMonitor.pendingActions) {
                    if (!action.executed && now >= action.scheduledTime) {
                        console.log(`执行待处理动作: ${actionId}`);
                        Utils.safeExecute(action.callback, `执行动作失败: ${actionId}`);
                        action.executed = true;
                        BackgroundMonitor.pendingActions.delete(actionId);
                    }
                }
            }, '检查待执行动作失败');
        },
        
        // 处理页面恢复时的待执行动作
        processPendingActions: () => {
            Utils.safeExecute(() => {
                for (const [actionId, action] of BackgroundMonitor.pendingActions) {
                    if (!action.executed) {
                        console.log(`页面恢复,立即执行动作: ${actionId}`);
                        Utils.safeExecute(action.callback, `恢复执行动作失败: ${actionId}`);
                        action.executed = true;
                        BackgroundMonitor.pendingActions.delete(actionId);
                    }
                }
            }, '处理恢复动作失败');
        },
        
        // 页面状态强制检查机制
        forceCheckPageState: () => {
            Utils.safeExecute(() => {
                // 定期检查页面状态,即使在后台也能响应
                setInterval(() => {
                    const currentUrl = window.location.href;
                    const lastUrl = sessionStorage.getItem('lastUrl') || '';
                    
                    // 如果是登录页面,跳过所有检查
                    if (currentUrl.includes('/pc/login.do')) {
                        return;
                    }
                    
                    // 如果URL发生变化,说明页面已经跳转
                    if (currentUrl !== lastUrl) {
                        console.log(`检测到页面变化: ${lastUrl} -> ${currentUrl}`);
                        sessionStorage.setItem('lastUrl', currentUrl);
                        
                        // 延迟执行以确保页面完全加载
                        setTimeout(() => {
                            Router.handleCurrentPage();
                        }, 2000);
                    }
                    
                    // 检查是否需要强制刷新状态
                    const lastActiveTime = sessionStorage.getItem('lastActiveTime');
                    if (lastActiveTime) {
                        const elapsed = Date.now() - parseInt(lastActiveTime);
                        
                        // 如果超过5分钟没有活动,且在课程详情页,强制检查
                        if (elapsed > 300000 && currentUrl.includes('coursedetail.do')) {
                            console.log('长时间无活动,强制检查课程详情页状态');
                            sessionStorage.setItem('lastActiveTime', Date.now().toString());
                            Router.handleCourseDetailPage();
                        }
                    }
                }, 30000); // 每30秒检查一次
                
                console.log('页面状态强制检查已启动');
            }, '页面状态检查设置失败');
        },
        
        cleanup: () => {
            Utils.safeExecute(() => {
                // 清理简化后的资源
                BackgroundMonitor.pendingActions.clear();
                
                if (BackgroundMonitor.keepAliveWorker) {
                    BackgroundMonitor.keepAliveWorker.postMessage('stop');
                    BackgroundMonitor.keepAliveWorker = null;
                }
                
                console.log('后台监控已清理');
            }, '后台监控清理失败');
        }
    };

    // ════════════════════════════════════════════════════════════════════════
    //                            🔧 统一工具模块
    // ════════════════════════════════════════════════════════════════════════
    const Utils = {
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    统一错误处理                                  │
        // └─────────────────────────────────────────────────────────────────┘
        safeExecute: (func, errorMsg = '操作失败') => {
            try {
                return func();
            } catch (error) {
                console.error(`${errorMsg}: ${error.message}`);
                return null;
            }
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    智能重试机制                                  │
        // └─────────────────────────────────────────────────────────────────┘
        retry: (func, maxRetries = 3, delay = 1000, errorMsg = '重试失败') => {
            let attempts = 0;
            
            const attempt = () => {
                try {
                    const result = func();
                    if (result !== false && result !== null && result !== undefined) {
                        return result;
                    }
                } catch (error) {
                    console.error(`尝试 ${attempts + 1} 失败: ${error.message}`);
                }
                
                attempts++;
                if (attempts < maxRetries) {
                    setTimeout(attempt, delay);
                } else {
                    console.error(`${errorMsg}: 已达最大重试次数`);
                }
            };
            
            attempt();
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    DOM 选择器                                   │
        // └─────────────────────────────────────────────────────────────────┘
        $: (selector, context = document) => {
            return Utils.safeExecute(() => context.querySelector(selector), `查询失败: ${selector}`);
        },
        
        $$: (selector, context = document) => {
            return Utils.safeExecute(() => Array.from(context.querySelectorAll(selector)), `查询失败: ${selector}`) || [];
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    元素等待器                                    │
        // └─────────────────────────────────────────────────────────────────┘
        waitForElement: (selector, timeout = 10000) => {
            return new Promise((resolve) => {
                Utils.safeExecute(() => {
                    const elements = Utils.$$(selector);
                    if (elements.length > 0) {
                        resolve(elements);
                        return;
                    }
                    
                    const startTime = performance.now();
                    const checkElements = (currentTime) => {
                        const elements = Utils.$$(selector);
                        if (elements.length > 0 || currentTime - startTime > timeout) {
                            resolve(elements);
                        } else {
                            requestAnimationFrame(checkElements);
                        }
                    };
                    
                    requestAnimationFrame(checkElements);
                }, '等待元素失败');
            });
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    页面导航器                                    │
        // └─────────────────────────────────────────────────────────────────┘
        navigateTo: (url, reason = '页面跳转') => {
            Utils.safeExecute(() => {
                console.log(`${reason}: ${url}`);
                sessionStorage.setItem('returning', 'true');
                window.location.href = url;
                
                // 单一备用机制
                setTimeout(() => {
                    if (window.location.href !== url) {
                        console.log('备用导航触发');
                        window.location.assign(url);
                    }
                }, 2000);
            }, `导航失败: ${url}`);
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    时间处理工具                                  │
        // └─────────────────────────────────────────────────────────────────┘
        extractMinutes: text => {
            if (!text) return 30;
            const match = text.match(/(\d+)/);
            return match ? parseInt(match[1]) : 30;
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    安全防护设置                                  │
        // └─────────────────────────────────────────────────────────────────┘
        setupProtection: () => {
            Utils.safeExecute(() => {
                // 基础弹窗阻止
                unsafeWindow.alert = () => console.log('警告窗口被屏蔽');
                unsafeWindow.confirm = () => true;
                unsafeWindow.prompt = () => '';
                
                // 防止WebDriver检测
                if (window.navigator) {
                    Object.defineProperty(navigator, 'webdriver', { get: () => false });
                }
                
                console.log('基础防护设置已启用');
            }, '防护设置失败');
        },

        // ═══════════════════════════════════════════════════════════════════
        //                           💾 存储管理
        // ═══════════════════════════════════════════════════════════════════
        storage: {
            get: (key, defaultValue = '') => {
                return Utils.safeExecute(() => GM_getValue(key, defaultValue), `存储读取错误: ${key}`, defaultValue);
            },
            
            set: (key, value) => {
                Utils.safeExecute(() => GM_setValue(key, value), `存储写入错误: ${key}`);
            },
            
            getVisited: () => {
                return Utils.safeExecute(() => {
                    return GM_getValue('visitedCourses', []);
                }, '获取访问记录错误', []);
            },
            
            addVisited: courseId => {
                Utils.safeExecute(() => {
                    const visited = Utils.storage.getVisited();
                    if (!visited.includes(courseId)) {
                        visited.push(courseId);
                        GM_setValue('visitedCourses', visited);
                    }
                }, `添加访问记录错误: ${courseId}`);
            },
            
            clearVisited: () => {
                Utils.safeExecute(() => GM_setValue('visitedCourses', []), '清除访问记录错误');
            }
        },

        // ═══════════════════════════════════════════════════════════════════
        //                           🔗 URL处理
        // ═══════════════════════════════════════════════════════════════════
        url: {
            extractCourseId: url => {
                const match = url.match(/courseid=([0-9A-F-]{36})/i) || url.match(/courseid=(\d+)/);
                return match ? match[1] : null;
            },
            
            extractChapterId: url => {
                const match = url.match(/chapterid=([0-9A-F-]{36})/i) || url.match(/chapterid=(\d+)/);
                return match ? match[1] : null;
            },
            
            getParam: name => {
                const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`);
                const results = regex.exec(window.location.href);
                return results && results[2] ? decodeURIComponent(results[2].replace(/\+/g, ' ')) : null;
            }
        }
    };

    // ════════════════════════════════════════════════════════════════════════
    //                            🎨 用户界面模块
    // ════════════════════════════════════════════════════════════════════════
    const UI = {
        panel: null,
        stats: {
            startTime: Date.now(),
            coursesCompleted: 0,
            backgroundTime: 0
        },
        
        init: () => {
            Utils.safeExecute(() => {
                UI.createPanel();
                UI.updateStatus('脚本已启动', 'info');
                console.log('用户界面已初始化');
            }, '用户界面初始化失败');
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    创建控制面板                                  │
        // └─────────────────────────────────────────────────────────────────┘
        createPanel: () => {
            Utils.safeExecute(() => {
                const panel = document.createElement('div');
                panel.id = 'study-assistant-panel';
                panel.innerHTML = `
                    <div style="position: fixed; top: 10px; right: 10px; width: 300px; background: #fff; border: 1px solid #ddd; border-radius: 5px; padding: 15px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); z-index: 10000; font-family: Arial, sans-serif; font-size: 12px;">
                        <div style="font-weight: bold; margin-bottom: 10px; color: #333;">安徽干部教育助手 V1.0.1</div>
                        <div id="status-display" style="padding: 8px; background: #f5f5f5; border-radius: 3px; margin-bottom: 10px; min-height: 20px;"></div>
                        <div id="background-status" style="padding: 5px; background: #e8f5e8; border-radius: 3px; font-size: 11px; text-align: center;">前台运行中</div>
                    </div>
                `;
                
                document.body.appendChild(panel);
                UI.panel = panel;
            }, 'UI面板创建失败');
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    状态更新器                                    │
        // └─────────────────────────────────────────────────────────────────┘
        updateStatus: (message, type = 'info') => {
            Utils.safeExecute(() => {
                const statusEl = document.getElementById('status-display');
                if (statusEl) {
                    const colors = {
                        info: '#2196F3',
                        success: '#4CAF50',
                        warning: '#FF9800',
                        error: '#F44336'
                    };
                    statusEl.style.color = colors[type] || colors.info;
                    statusEl.textContent = message;
                }
            }, '状态更新失败');
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    后台状态指示器                                │
        // └─────────────────────────────────────────────────────────────────┘
        updateBackgroundStatus: (isBackground) => {
            Utils.safeExecute(() => {
                const bgEl = document.getElementById('background-status');
                if (bgEl) {
                    if (isBackground) {
                        bgEl.textContent = '后台运行中';
                        bgEl.style.background = '#fff3cd';
                        UI.stats.backgroundTime = Date.now();
                    } else {
                        bgEl.textContent = '前台运行中';
                        bgEl.style.background = '#e8f5e8';
                    }
                }
            }, '后台状态更新失败');
        }
    };

    // ════════════════════════════════════════════════════════════════════════
    //                            📚 课程处理引擎
    // ════════════════════════════════════════════════════════════════════════
    const CourseHandler = {
        currentCourse: null,
        isProcessing: false,
        
        init: () => {
            Utils.safeExecute(() => {
                console.log('课程处理器已初始化');
            }, '课程处理器初始化失败');
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    智能课程打开器                                │
        // └─────────────────────────────────────────────────────────────────┘
        openCourse: (courseElement) => {
            if (!courseElement || CourseHandler.isProcessing) return;
            
            Utils.safeExecute(() => {
                CourseHandler.isProcessing = true;
                const courseTitle = courseElement.textContent?.trim() || '未知课程';
                console.log(`准备打开课程: ${courseTitle}`);
                UI.updateStatus(`正在打开课程: ${courseTitle}`, 'info');
                
                // 智能打开机制:直接导航 + 智能备用
                const link = courseElement.querySelector('a') || courseElement.closest('a');
                if (link && link.href) {
                    console.log(`直接导航到课程: ${link.href}`);
                    Utils.navigateTo(link.href, '打开课程');
                } else {
                    console.log('使用点击方式打开课程');
                    courseElement.click();
                    
                    // 智能备用:检查页面是否发生变化,如果没有则再次点击
                    const currentUrl = window.location.href;
                    setTimeout(() => {
                        if (window.location.href === currentUrl && courseElement) {
                            console.log('页面未跳转,执行备用点击');
                            courseElement.click();
                        }
                    }, 2000);
                }
                
                CourseHandler.isProcessing = false;
            }, '打开课程失败');
        },
        

        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    学习时间管理器                                │
        // └─────────────────────────────────────────────────────────────────┘
        startStudyTime: (requiredMinutes, completeButton) => {
            Utils.safeExecute(() => {
                console.log(`开始学习计时: ${requiredMinutes}分钟`);
                UI.updateStatus(`学习中: ${requiredMinutes}分钟`, 'info');
                
                const waitTime = requiredMinutes * 60 * 1000;
                const studyStartTime = Date.now();
                
                // 显示倒计时(每秒更新)
                const updateDisplay = () => {
                    const elapsed = Date.now() - studyStartTime;
                    const remaining = Math.max(0, waitTime - elapsed);
                    const minutes = Math.floor(remaining / 60000);
                    const seconds = Math.floor((remaining % 60000) / 1000);
                    
                    if (remaining > 0) {
                        UI.updateStatus(`学习中,剩余: ${minutes}:${seconds.toString().padStart(2, '0')}`, 'info');
                    } else {
                        UI.updateStatus('学习完成,准备切换...', 'success');
                        clearInterval(displayInterval);
                    }
                };
                
                // 立即显示一次
                updateDisplay();
                
                // 每秒更新一次倒计时
                const displayInterval = setInterval(updateDisplay, 1000);
                
                // 时间到后完成
                setTimeout(() => {
                    clearInterval(displayInterval);
                    UI.updateStatus('学习完成,准备切换...', 'success');
                    
                    if (completeButton && typeof completeButton.click === 'function') {
                        console.log('点击完成按钮');
                        const currentUrl = window.location.href;
                        completeButton.click();
                        
                        // 学习完成后,等待页面跳转或寻找下一章节
                        setTimeout(() => {
                            CourseHandler.handleStudyComplete();
                        }, 3000);
                        
                        // 智能备用:检查页面是否发生变化,如果没有则再次点击
                        setTimeout(() => {
                            if (window.location.href === currentUrl && 
                                completeButton && 
                                typeof completeButton.click === 'function') {
                                console.log('页面未跳转,执行备用完成点击');
                                completeButton.click();
                            }
                        }, 2000);
                    }
                }, waitTime);
            }, '学习时间处理失败');
        },
        
        // ┌─────────────────────────────────────────────────────────────────┐
        // │                    学习完成处理器                                │
        // └─────────────────────────────────────────────────────────────────┘
        handleStudyComplete: () => {
            Utils.safeExecute(() => {
                console.log('章节学习完成,寻找下一步');
                
                // 等待可能的页面跳转
                setTimeout(() => {
                    // 检查是否回到了课程详情页
                    if (window.location.pathname.includes('coursedetail.do')) {
                        console.log('返回课程详情页,寻找下一章节');
                        Router.handleCourseDetailPage();
                    }
                    // 检查是否还在学习页面
                    else if (window.location.pathname.includes('playvideo.do') || window.location.pathname.includes('playscorm.do')) {
                        console.log('仍在学习页面,寻找下一章节按钮');
                        // 寻找下一章节按钮
                        const nextChapterButton = Utils.$('a[href*="playvideo"], a[href*="playscorm"], .next-chapter, .next-lesson');
                        if (nextChapterButton && nextChapterButton.href && nextChapterButton.href !== window.location.href) {
                            console.log('找到下一章节,准备跳转');
                            UI.updateStatus('发现下一章节,准备继续学习', 'info');
                            setTimeout(() => nextChapterButton.click(), 2000);
                        } else {
                            // 没有下一章节,尝试返回课程列表
                            console.log('没有更多章节,准备返回课程列表');
                            Utils.navigateTo('/courseList.do', '返回课程列表');
                        }
                    }
                    // 检查是否回到了课程列表页
                    else if (window.location.pathname.includes('courselist.do')) {
                        console.log('返回课程列表页,寻找下一门课程');
                        Router.handleCourseListPage();
                    }
                    // 其他情况,尝试返回课程列表
                    else {
                        console.log('未知页面,尝试返回课程列表');
                        Utils.navigateTo('https://www.ahgbjy.gov.cn/pc/course/courselist.do?categoryid=&year=&coutype=0&mostNInput=0&mostHInput=0&mostTJInput=&keyword=', '返回课程列表');
                    }
                }, 2000);
            }, '学习完成处理失败');
        },

        // ─────────────────────────────────────────────────────────────────────
        //                          🎯 课程选择算法
        // ─────────────────────────────────────────────────────────────────────
        selectCourse: (courseElements, visitedCourses) => {
            // 🥇 优先级1:选择"学习中"的课程
            for (const el of courseElements) {
                const status = el.lastChild?.innerHTML?.trim() || '';
                if (status === "学习中") {
                    console.log('✨ 找到学习中的课程');
                    return el;
                }
            }
            
            // 🥈 优先级2:选择未完成且未访问的课程
            for (const el of courseElements) {
                const status = el.lastChild?.innerHTML?.trim() || '';
                if (status !== "已完成") {
                    const courseId = CourseHandler.extractCourseId(el);
                    if (!visitedCourses.includes(courseId)) {
                        Utils.storage.addVisited(courseId);
                        console.log(`🎯 选择未完成课程: ${courseId}`);
                        return el;
                    }
                }
            }
            
            return null;
        },

        // ─────────────────────────────────────────────────────────────────────
        //                          📄 分页处理
        // ─────────────────────────────────────────────────────────────────────
        handlePagination: async () => {
            try {
                const pagination = Utils.$('.pagination');
                if (!pagination) {
                    console.error('未找到分页元素');
                    return false;
                }
                
                const pageLinks = pagination.querySelectorAll('a[href]');
                console.log(`找到 ${pageLinks.length} 个分页链接`);
                
                // 查找">"按钮
                for (const link of pageLinks) {
                    const linkText = link.textContent.trim();
                    if (linkText === '>') {
                        const href = link.getAttribute('href');
                        if (href) {
                            const fullUrl = href.startsWith('/') ? `https://www.ahgbjy.gov.cn${href}` : href;
                            console.log(`找到下一页按钮,跳转到: ${fullUrl}`);
                            UI.updateStatus('跳转到下一页');
                            window.location.href = fullUrl;
                            return true;
                        }
                    }
                }
                
                console.error('未找到下一页按钮');
                return false;
            } catch (error) {
                console.error(`分页处理错误: ${error.message}`);
                return false;
            }
        },

        // ─────────────────────────────────────────────────────────────────────
        //                          🔄 课程类型切换
        // ─────────────────────────────────────────────────────────────────────
        switchCourseType: () => {
            try {
                const currentType = Utils.url.getParam('coutype') || '0';
                console.log(`当前课程类型: ${currentType === '0' ? '必修' : '选修'}`);
                
                // 检查是否两种类型都已完成
                const requiredCompleted = Utils.storage.get('requiredCoursesCompleted', 'false');
                const electiveCompleted = Utils.storage.get('electiveCoursesCompleted', 'false');
                
                if (requiredCompleted === 'true' && electiveCompleted === 'true') {
                    console.log('🎉 所有课程均已完成!');
                    UI.updateStatus('🎉 所有课程已完成!', 'success');
                    alert('🎉 恭喜!所有必修和选修课程均已完成!');
                    return;
                }
                
                // 根据当前类型切换到另一种类型
                if (currentType === '0') {
                    // 当前是必修课程,标记必修课程完成,切换到选修课程
                    console.log('🎉 必修课程已完成,切换到选修课程');
                    Utils.storage.set('requiredCoursesCompleted', 'true');
                    UI.updateStatus('必修课程完成!切换到选修课程', 'success');
                    
                    const electiveUrl = 'https://www.ahgbjy.gov.cn/pc/course/courselist.do?categoryid=&year=&coutype=1&mostNInput=0&mostHInput=0&mostTJInput=&keyword=';
                    setTimeout(() => {
                        window.location.replace(electiveUrl);
                    }, 2000);
                } else {
                    // 当前是选修课程,标记选修课程完成,切换到必修课程
                    console.log('🎉 选修课程已完成,切换到必修课程');
                    Utils.storage.set('electiveCoursesCompleted', 'true');
                    UI.updateStatus('选修课程完成!切换到必修课程', 'success');
                    
                    const requiredUrl = 'https://www.ahgbjy.gov.cn/pc/course/courselist.do?categoryid=&year=&coutype=0&mostNInput=0&mostHInput=0&mostTJInput=&keyword=';
                    setTimeout(() => {
                        window.location.replace(requiredUrl);
                    }, 2000);
                }
            } catch (error) {
                console.error(`课程类型切换错误: ${error.message}`);
            }
        },

        // 提取课程ID
        extractCourseId: (courseElement) => {
            try {
                const href = courseElement.getAttribute('href') || 
                             courseElement.querySelector('a')?.getAttribute('href') || '';
                return Utils.url.extractCourseId(href) || 'unknown';
            } catch (error) {
                console.error(`提取课程ID错误: ${error.message}`);
                return 'unknown';
            }
        },

        // ─────────────────────────────────────────────────────────────────────
        //                          🔍 章节处理算法
        // ─────────────────────────────────────────────────────────────────────
        findAndClickIncompleteChapter: () => {
            Utils.safeExecute(() => {
                console.log('查找未完成章节');
                const playButtons = Utils.$$('.playBtn[data-chapterid]');
                
                for (let i = 0; i < playButtons.length; i++) {
                    const button = playButtons[i];
                    const row = button.closest('tr');
                    if (!row) continue;
                    
                    const progressCells = row.querySelectorAll('td.col-md-2');
                    if (progressCells.length >= 2) {
                        const progressText = progressCells[1].textContent;
                        const match = progressText.match(/(\d+)%/);
                        const progress = match ? parseInt(match[1]) : 0;
                        
                        if (progress < 100) {
                            console.log(`找到未完成章节(进度:${progress}%),准备点击`);
                            UI.updateStatus(`进入章节${i + 1}(进度:${progress}%)`, 'info');
                            
                            const currentUrl = window.location.href;
                            button.click();
                            
                            // 智能备用:检查页面是否发生变化,如果没有则再次点击
                            setTimeout(() => {
                                if (window.location.href === currentUrl) {
                                    const currentButton = Utils.$$('.playBtn[data-chapterid]')[i];
                                    if (currentButton) {
                                        console.log('页面未跳转,执行备用章节点击');
                                        currentButton.click();
                                    }
                                }
                            }, 2000);
                            
                            return;
                        }
                    }
                }
                
                console.log('所有章节已完成,返回课程列表');
                UI.updateStatus('课程已完成,返回列表', 'success');
                setTimeout(() => CourseHandler.returnToCourseList(), 1000);
            }, '查找未完成章节失败');
        },

        // ─────────────────────────────────────────────────────────────────────
        //                          📊 章节信息提取
        // ─────────────────────────────────────────────────────────────────────
        extractChapterInfo: (courseId) => {
            Utils.safeExecute(() => {
                const playButtons = Utils.$$('.playBtn[data-chapterid]');
                console.log(`找到 ${playButtons.length} 个章节`);
                
                playButtons.forEach((button, index) => {
                    Utils.safeExecute(() => {
                        const chapterId = button.getAttribute('data-chapterid');
                        if (!chapterId) return;
                        
                        const row = button.closest('tr');
                        if (!row) return;
                        
                        const colMd2Cells = row.querySelectorAll('td.col-md-2');
                        let totalMinutes = 30;
                        let learnedPercent = 0;
                        
                        // 提取时长
                        if (colMd2Cells.length >= 1) {
                            const timeText = colMd2Cells[0].textContent;
                            if (timeText.includes('分钟')) {
                                totalMinutes = Utils.extractMinutes(timeText);
                                console.log(`章节${index + 1}时长: ${totalMinutes}分钟`);
                            }
                        }
                        
                        // 提取进度
                        if (colMd2Cells.length >= 2) {
                            const progressText = colMd2Cells[1].textContent;
                            const match = progressText.match(/(\d+)%/);
                            if (match) {
                                learnedPercent = parseInt(match[1]);
                                console.log(`章节${index + 1}进度: ${learnedPercent}%`);
                            }
                        }
                        
                        // 计算剩余时间
                        const remainingPercent = Math.max(0, 100 - learnedPercent);
                        const remainingMinutes = Math.ceil((totalMinutes * remainingPercent) / 100);
                        
                        // 保存时长信息
                        const key = `duration_${courseId}_${chapterId}`;
                        Utils.storage.set(key, remainingMinutes.toString());
                    }, `章节${index + 1}信息提取错误`);
                });
            }, '章节信息处理错误');
        },

        // 检查课程完成状态
        checkCourseCompletion: () => {
            return Utils.safeExecute(() => {
                const colMd2Elements = document.getElementsByClassName('col-md-2');
                if (colMd2Elements.length > 0) {
                    const lastElement = colMd2Elements[colMd2Elements.length - 1];
                    const spans = lastElement.getElementsByTagName('span');
                    return spans.length > 0 && spans[0].innerHTML === '100';
                }
                return false;
            }, '课程完成状态检查错误', false);
        },

        // 返回课程列表
        returnToCourseList: () => {
            Utils.safeExecute(() => {
                const coursetype = sessionStorage.getItem('lastCoutype') || '0';
                const backUrl = `https://www.ahgbjy.gov.cn/pc/course/courselist.do?categoryid=&year=&coutype=${coursetype}&mostNInput=0&mostHInput=0&mostTJInput=&keyword=`;
                
                sessionStorage.setItem('returning', 'true');
                Utils.navigateTo(backUrl, '返回课程列表');
            }, '返回课程列表失败');
        }
    };

    // ════════════════════════════════════════════════════════════════════════
    //                            🛣️  路由管理系统
    // ════════════════════════════════════════════════════════════════════════
    const Router = {
        routes: {
            '/': () => Router.handleHomePage(),
            '/courseList.do': () => Router.handleCourseListPage(),
            '/coursedetail.do': () => Router.handleCourseDetailPage(),
            '/playvideo.do': () => Router.handleVideoPage(),
            '/playscorm.do': () => Router.handleScormPage()
        },
        
        init: () => {
            Utils.safeExecute(() => {
                Router.handleCurrentPage();
                console.log('路由管理器已初始化');
            }, '路由管理器初始化失败');
        },
        
        handleCurrentPage: () => {
            Utils.safeExecute(() => {
                const path = window.location.pathname;
                const search = window.location.search;
                const url = window.location.href;
                
                console.log(`当前页面: ${path}${search}`);
                
                // 检查是否为登录页面,如果是则不执行任何操作
                if (url.includes('/pc/login.do')) {
                    console.log('检测到登录页面,脚本暂停工作');
                    UI.updateStatus('登录页面 - 脚本已暂停', 'info');
                    return;
                }
                
                // 保存课程类型参数
                if (url.includes('courselist.do') && /[?&]coutype=\d/.test(url)) {
                    const match = url.match(/coutype=(\d+)/);
                    if (match) {
                        sessionStorage.setItem('lastCoutype', match[1]);
                    }
                }
                
                // 检查返回状态
                if (sessionStorage.getItem('returning') === 'true' && url.includes('courselist.do')) {
                    console.log('检测到从课程页面返回');
                    sessionStorage.removeItem('returning');
                    setTimeout(() => Router.handleCourseListPage(), 2000);
                    return;
                }
                
                if (url.includes('courselist.do')) {
                    console.log('当前页面: 课程列表');
                    setTimeout(() => Router.handleCourseListPage(), 1000);
                } else if (url.includes('coursedetail.do')) {
                    console.log('当前页面: 课程详情');
                    setTimeout(() => Router.handleCourseDetailPage(), 1000);
                } else if (url.includes('playvideo.do') || url.includes('playscorm.do')) {
                    console.log('当前页面: 学习页面');
                    setTimeout(() => Router.handleVideoPage(), 1000);
                } else {
                    console.log('当前页面: 首页或其他');
                    Router.handleHomePage();
                }
            }, '页面处理失败');
        },
        
        // ─────────────────────────────────────────────────────────────────────
        //                          🏠 主页处理
        // ─────────────────────────────────────────────────────────────────────
        handleHomePage: () => {
            Utils.safeExecute(() => {
                UI.updateStatus('首页已加载,请手动进入课程列表', 'info');
                console.log('首页已加载,脚本不会自动跳转到课程列表');
            }, '首页处理失败');
        },
        
        // ─────────────────────────────────────────────────────────────────────
        //                          📚 课程列表页处理
        // ─────────────────────────────────────────────────────────────────────
        handleCourseListPage: async () => {
            Utils.safeExecute(async () => {
                console.log('开始处理课程列表页面');
                
                const currentType = Utils.url.getParam('coutype') || '0';
                const typeName = currentType === '0' ? '必修' : '选修'; 
                
                UI.updateStatus(`正在分析${typeName}课程列表...`, 'info');
                
                // 等待页面加载
                await Utils.waitForElement('.coursespan', 5000);
                
                const courseElements = Utils.$$('.coursespan');
                if (courseElements.length === 0) {
                    console.error('未找到课程元素');
                    UI.updateStatus('未找到课程元素', 'error');
                    return;
                }
                
                console.log(`找到 ${courseElements.length} 个${typeName}课程`);
                UI.updateStatus(`正在分析 ${courseElements.length} 个${typeName}课程`, 'info');
                
                // 统计课程状态
                const stats = { completed: 0, learning: 0, uncompleted: 0 };
                const visitedCourses = Utils.storage.getVisited();
                
                courseElements.forEach(el => {
                    const status = el.lastChild?.innerHTML?.trim() || '';
                    if (status === "已完成") stats.completed++;
                    else if (status === "学习中") stats.learning++;
                    else stats.uncompleted++;
                });
                
                console.log(`${typeName}课程状态 - 已完成: ${stats.completed}, 学习中: ${stats.learning}, 未完成: ${stats.uncompleted}`);
                
                // 如果当前页所有课程已完成,尝试翻页
                if (stats.completed === courseElements.length) {
                    console.log(`当前页所有${typeName}课程已完成`);
                    UI.updateStatus(`当前页${typeName}课程已完成,准备翻页`, 'success');
                    Utils.storage.clearVisited();
                    
                    setTimeout(async () => {
                        if (await CourseHandler.handlePagination()) {
                            return;
                        }
                        console.log(`所有${typeName}课程页面已完成,切换课程类型`);
                        CourseHandler.switchCourseType();
                    }, 2000);
                    
                    return;
                }
                
                // 选择课程学习
                const selectedCourse = CourseHandler.selectCourse(courseElements, visitedCourses);
                if (selectedCourse) {
                    CourseHandler.openCourse(selectedCourse);
                } else {
                    console.log('所有课程都已访问,重置记录');
                    Utils.storage.clearVisited();
                    setTimeout(() => Router.handleCourseListPage(), 2000);
                }
            }, '课程列表页处理失败');
        },
        
        // ─────────────────────────────────────────────────────────────────────
        //                          📖 课程详情页处理
        // ─────────────────────────────────────────────────────────────────────
        handleCourseDetailPage: async () => {
            Utils.safeExecute(async () => {
                console.log('处理课程详情页');
                UI.updateStatus('分析课程详情...', 'info');
                
                // 添加页面焦点监听器
                const handlePageFocus = () => {
                    console.log('课程详情页获得焦点,重新检查状态');
                    setTimeout(() => {
                        Router.handleCourseDetailPage();
                    }, 1000);
                };
                
                // 只添加一次焦点监听器
                if (!window.focusListenerAdded) {
                    window.addEventListener('focus', handlePageFocus);
                    window.focusListenerAdded = true;
                }
                
                const courseId = Utils.url.extractCourseId(window.location.href);
                if (!courseId) {
                    console.error('无法获取课程ID');
                    return;
                }
                
                console.log(`课程ID: ${courseId}`);
                
                // 等待页面加载
                await Utils.waitForElement('.playBtn[data-chapterid]', 3000);
                
                // 提取章节信息
                CourseHandler.extractChapterInfo(courseId);
                
                // 检查课程完成状态
                if (CourseHandler.checkCourseCompletion()) {
                    console.log('课程已完成,返回列表');
                    UI.updateStatus('课程已完成,返回列表', 'success');
                    UI.stats.coursesCompleted++;
                    setTimeout(() => CourseHandler.returnToCourseList(), 1000);
                    return;
                }

                // 检查是否从学习页面返回或手动关闭
                const fromLearning = sessionStorage.getItem('fromLearningPage');
                const lastActiveTime = sessionStorage.getItem('lastActiveTime');
                const currentTime = Date.now();
                
                // 如果超过一定时间没有活动,强制刷新状态
                if (lastActiveTime && (currentTime - parseInt(lastActiveTime)) > 60000) {
                    console.log('检测到长时间无活动,强制刷新状态');
                    sessionStorage.removeItem('lastActiveTime');
                    sessionStorage.removeItem('fromLearningPage');
                }
                
                if (fromLearning === 'true') {
                    console.log('从学习页面返回,继续下一章节');
                    sessionStorage.removeItem('fromLearningPage');
                    sessionStorage.setItem('lastActiveTime', currentTime.toString());
                    setTimeout(() => CourseHandler.findAndClickIncompleteChapter(), 1000);
                    return;
                }
                
                // 首次进入,查找并开始学习
                const startButton = Utils.$('.btn.btn-default.startlearn');
                if (startButton) {
                    console.log(`找到开始学习按钮: ${startButton.textContent.trim()}`);
                    UI.updateStatus('准备开始学习...', 'info');
                    sessionStorage.setItem('lastActiveTime', currentTime.toString());
                    startButton.click();
                } else {
                    sessionStorage.setItem('lastActiveTime', currentTime.toString());
                    CourseHandler.findAndClickIncompleteChapter();
                }
                
            }, '课程详情页处理失败');
        },
        
        // ─────────────────────────────────────────────────────────────────────
        //                          🎬 学习页面处理
        // ─────────────────────────────────────────────────────────────────────
        handleVideoPage: async () => {
            Utils.safeExecute(async () => {
                console.log('处理学习页面');
                UI.updateStatus('正在学习课程...', 'info');
                
                const courseId = Utils.url.extractCourseId(window.location.href);
                const chapterId = Utils.url.extractChapterId(window.location.href);
                
                console.log(`学习页面 - 课程ID: ${courseId}, 章节ID: ${chapterId}`);
                
                // 等待完成按钮出现
                await Utils.waitForElement('.btn.btn-default:nth-child(2)', 5000);
                
                const completeButton = Utils.$('.btn.btn-default:nth-child(2)');
                if (!completeButton) {
                    console.error('未找到完成按钮');
                    return;
                }
                
                console.log(`找到完成按钮: ${completeButton.textContent.trim()}`);
                
                // 获取学习时长
                let duration = 30; // 默认30分钟
                if (courseId && chapterId) {
                    const storedDuration = Utils.storage.get(`duration_${courseId}_${chapterId}`);
                    if (storedDuration) {
                        duration = Math.max(parseInt(storedDuration), 1);
                    }
                }
                
                // 计算等待时间(100%剩余时长 + 1分钟安全余量,最少30秒)
                const waitTime = Math.max((duration + 1) * 60 * 1000, 30000);
                const waitMinutes = Math.round(waitTime / 60000);
                
                console.log(`等待 ${waitMinutes} 分钟后完成学习`);
                
                // 标记学习状态
                sessionStorage.setItem('fromLearningPage', 'true');
                
                // 使用带倒计时的学习时间处理
                CourseHandler.startStudyTime(waitMinutes, completeButton);
                
            }, '学习页处理失败');
        },
        
        handleScormPage: () => {
            // SCORM页面使用相同的处理逻辑
            Router.handleVideoPage();
        }
    };

    // ════════════════════════════════════════════════════════════════════════
    //                            🚀 主应用程序
    // ════════════════════════════════════════════════════════════════════════
    const App = {
        init: () => {
            Utils.safeExecute(() => {
                console.log('安徽干部在线教育自动学习 V1.0.1 启动(优化版:自动选课 + 智能学习 + 防休眠)');

                // 初始化各模块
                VideoAutoplayBlocker.init();
                BackgroundMonitor.init();
                Utils.setupProtection();

                // 等待页面加载完成
                if (document.readyState === 'loading') {
                    document.addEventListener('DOMContentLoaded', App.start);
                } else {
                    App.start();
                }
            }, '应用初始化失败');
        },

        start: () => {
            Utils.safeExecute(() => {
                if (!document.body) {
                    setTimeout(App.start, 100);
                    return;
                }

                console.log('页面加载完成,启动主程序');
                
                // 初始化防休眠系统
                WakeLockManager.init();
                
                // 记录初始URL和活动时间
                sessionStorage.setItem('lastUrl', window.location.href);
                sessionStorage.setItem('lastActiveTime', Date.now().toString());
                
                // 初始化UI和路由
                UI.init();
                CourseHandler.init();
                Router.init();
                
                console.log('所有模块启动完成');
            }, '应用启动失败');
        }
    };

    // ════════════════════════════════════════════════════════════════════════
    //                          🧹 系统清理与启动
    // ════════════════════════════════════════════════════════════════════════
    
    // 页面卸载时清理资源
    window.addEventListener('beforeunload', () => {
        Utils.safeExecute(() => {
            WakeLockManager.cleanup();
            BackgroundMonitor.cleanup();
            console.log('✅ 应用已安全清理');
        }, '应用清理失败');
    });

    // 🚀 启动应用程序
    App.init();

})();

/**
 * ┌─────────────────────────────────────────────────────────────────────────┐
 * │                           ✨ 脚本运行完毕 ✨                           │
 * │                                                                         │
 * │  感谢使用安徽干部在线教育自动学习脚本!                                 │
 * │  如有问题请联系开发者:Moker32                                          │
 * │                                                                         │
 * │  🎯 功能特性:自动选课 + 智能学习 + 防休眠                              │
 * │  💫 技术栈:ES6+ + WebAPI + Tampermonkey                              │
 * │  🌟 版本:V1.0.1 优化版                                                │
 * └─────────────────────────────────────────────────────────────────────────┘
 */