// ==UserScript== // @name 广东干部培训助手 (重oku构优化版) // @namespace http://tampermonkey.net/ // @version 1.0 // @description 本脚本基于 LEEMO2023 的 3.2 版本重构,修复了原版在 ASP.NET 页面中常见的“回发或回调参数无效”错误,并优化了视频播放的监控逻辑。脚本将自动学习、切换课程,无任何多余功能。 // @author Community Contributor // @license MIT // @match *://gbpx.gd.gov.cn/* // @match *://*.gdgbpx.com/* // @match *://wcs1.shawcoder.xyz/* // @match *://*gzqinghui.com.cn/* // @grant window.close // @run-at document-end // ==/UserScript== (function() { 'use strict'; /** --- 用户配置 --- */ const CONFIG = { // 'full': 完整播放视频 | 'time': 按指定分钟数播放 watchMode: 'full', // 当 watchMode 为 'time' 时生效,设定每个视频的观看分钟数 watchMinutes: 5 }; /** --- 配置结束 --- */ const currentUrl = window.location.href; /** * @summary 主逻辑入口,监听 window.load 事件 * @description 确保在页面所有资源(包括ASP.NET的视图状态)加载完毕后执行脚本,以防止事件验证错误。 */ window.addEventListener('load', function() { console.log("[助手] 脚本已启动,等待页面加载完成..."); // 延迟执行,确保ASP.NET页面完全初始化 setTimeout(() => { if (currentUrl.includes("LearningCourse.aspx")) { handleCourseListPage(); } else if (currentUrl.includes("StudyCenter.aspx")) { handleStudyCenterPage(); } else if (currentUrl.includes("CourseDetail.aspx")) { handleCourseDetailPage(); } else if (currentUrl.includes("play_pc") || currentUrl.includes("CourseWare")) { handleVideoPage(); } else if (currentUrl.includes("playdo_pc.html")) { handleCompletionPage(); } else { console.log("[助手] 当前页面无需处理,脚本将保持静默。"); } }, 1500); setupMessageListener(); }); /** * @summary 模块一: 处理课程列表页面 (LearningCourse.aspx) * @description 遍历课程列表,查找第一个学习进度未达标的课程并进入。 */ function handleCourseListPage() { console.log("[模块一] 开始处理课程列表..."); const links = document.querySelectorAll("a.courseware-list-reed, a[id^='gvList_ctl']"); for (let link of links) { const text = link.innerText || link.title || ""; // 从链接文本中解析课程进度 const match = text.match(/已学习\s*([\d.]+)[%%]/); const progress = match ? parseFloat(match[1]) : 0; if (progress < 95) { console.log(`[模块一] 定位到未完成课程: ${text.trim()},准备进入...`); safeClick(link); return; // 找到即退出循环 } } console.log("[模块一] 列表内所有课程学习进度均已达标 (>= 95%)。"); } /** * @summary 模块二: 处理学习中心页面 (StudyCenter.aspx) * @description 检测当前课程的总体进度,若未完成则点击继续学习,否则返回课程列表。 */ function handleStudyCenterPage() { console.log("[模块二] 开始处理学习中心,检测当前课程进度..."); let progress = 0; // 通过页面文本检索课程进度 const match = document.body.innerText.match(/(?:当前进度|学习进度).*?([\d.]+)%/); if (match) { progress = parseFloat(match[1]); } console.log(`[模块二] 检测到当前课程进度为: ${progress}%`); if (progress >= 95) { console.log("[模块二] 课程进度已达标,即将返回课程列表..."); window.location.assign("https://gbpx.gd.gov.cn/gdceportal/Study/LearningCourse.aspx"); } else { console.log("[模块二] 课程进度未达标,尝试点击'继续学习'..."); const playBtn = document.querySelector("a.courseware-list-reed, a[id^='gvList_ctl']"); if (playBtn) safeClick(playBtn); } } /** * @summary 模块三: 处理课程详情页面 (CourseDetail.aspx) * @description 查找并点击“进入学习”或类似按钮,以启动课件播放窗口。 */ function handleCourseDetailPage() { console.log("[模块三] 开始处理课程详情页..."); // 查找包含关键文本的入口按钮 const btns = Array.from(document.querySelectorAll('a, button, input')); const playBtn = btns.find(b => { const text = (b.innerText || b.value || b.title || '').trim(); return text.includes('进入学习') || text.includes('继续学习') || text.includes('开始学习'); }); if (playBtn) { console.log("[模块三] 已找到学习入口按钮,准备点击..."); // 点击后页面将执行回发(PostBack),交由safeClick处理。 safeClick(playBtn); } else { console.log("[模块三] 错误: 未能在页面上找到'进入学习'或类似按钮。"); } } /** * @summary 模块四: 处理视频播放页面 * @description 智能监控视频播放,根据用户配置(完整播放或按时播放)来决定何时关闭窗口。 */ function handleVideoPage() { console.log("[模块四] 进入视频播放页面..."); // 轮询查找