// ==UserScript== // @name 生态环境云课堂自动学习助手 // @namespace http://onlinelearning.21tb.com/ // @version 3.2 // @description 全国生态环境执法培训云课堂全自动学习:精准关闭弹窗、自动循环学完所有必修,静音后台运行 // @author study_bot // @match *://onlinelearning.21tb.com/* // @grant none // @run-at document-idle // @noframes // @tag 教育,学习,自动化,网课,云课堂 // ==/UserScript== (function() { 'use strict'; const CONFIG = { checkInterval: 4000, actionCooldown: 12000 }; const state = { lastActionTime: 0, visitedCourses: new Set(JSON.parse(localStorage.getItem('visitedCourses') || '[]')) }; function log(msg) { console.log(`[自动学习v3.2] ${new Date().toLocaleTimeString()} | ${msg}`); } // 精准关闭所有弹窗(匹配真实页面的Close按钮) function closePopups() { try { // 匹配真实页面的关闭按钮 document.querySelectorAll('button[aria-label="Close"], .el-dialog__close, .modal-close, .el-icon-close').forEach(btn => { try { btn.click(); } catch(e) {} }); // 点遮罩层关闭弹窗 const modal = document.querySelector('.el-dialog__wrapper'); if (modal && getComputedStyle(modal).display !== 'none') modal.click(); } catch(e) {} } function playVideo() { try { document.querySelectorAll('video').forEach(v => { v.muted = true; v.volume = 0; v.playbackRate = 1; if (v.paused) v.play().catch(()=>{}); }); } catch(e) {} } function goCourseList() { const now = Date.now(); if (now - state.lastActionTime < CONFIG.actionCooldown) return; try { if (location.pathname.includes('/student/index')) { const btn = [...document.querySelectorAll('a, div, span')].find(el => el.innerText?.trim() === '我的课程' && el.offsetParent); if (btn) { log('首页进入我的课程'); btn.click(); state.lastActionTime = now; } } } catch(e) {} } function pickNextCourse() { const now = Date.now(); if (now - state.lastActionTime < CONFIG.actionCooldown) return; try { if (!location.href.includes('course_manage_user_pc')) return; const cards = [...document.querySelectorAll('[class*=course-card], [class*=item-card], .list-item')]; for (let c of cards) { const t = c.innerText || ''; if (t.includes('必修') && !t.includes('已完成') && !t.includes('100%') && !state.visitedCourses.has(t.slice(0,20))) { log('点未学必修: ' + t.split('\n')[0]); c.click(); state.visitedCourses.add(t.slice(0,20)); localStorage.setItem('visitedCourses', JSON.stringify([...state.visitedCourses])); state.lastActionTime = now; return; } } } catch(e) {} } function nextSection() { const now = Date.now(); if (now - state.lastActionTime < CONFIG.actionCooldown) return; try { if (!location.href.includes('courseLearning/play')) return; const nextBtn = [...document.querySelectorAll('button')].find(el => el.innerText?.trim() === '下一节' && el.offsetParent && !el.disabled); if (nextBtn) { log('点下一节'); nextBtn.click(); state.lastActionTime = now; return; } const unDone = [...document.querySelectorAll('span, div')].filter(el => el.innerText?.trim() === '未完成' && el.offsetParent); for (let el of unDone) { let p = el.parentElement; for (let i=0;i<6;i++) { if (!p) break; if (p.tagName === 'LI' || p.tagName === 'A') { p.click(); state.lastActionTime = now; return; } p = p.parentElement; } } if (document.body.innerText.includes('本课程学习完成')) { log('课程学完回列表'); history.back(); state.lastActionTime = now; } } catch(e) {} } async function answerQuiz() { try { const qs = document.querySelectorAll('[class*=question-item]'); if (!qs.length) return; log(`检测到${qs.length}道题,开始作答`); for (let q of qs) { const opts = q.querySelectorAll('label, .el-radio, .el-checkbox-item'); const unsel = [...opts].filter(o => !o.classList.contains('is-checked')); if (unsel.length) { unsel[Math.floor(Math.random()*unsel.length)].click(); await new Promise(r=>setTimeout(r,200)); } } await new Promise(r=>setTimeout(r,1000)); const allDone = [...qs].every(q => q.querySelectorAll('.is-checked').length > 0); if (allDone) { const submit = [...document.querySelectorAll('button')].find(b => b.innerText?.includes('提交')); if (submit) { submit.click(); log('全部答完提交'); } } } catch(e) {} } async function loop() { closePopups(); playVideo(); goCourseList(); pickNextCourse(); nextSection(); if (document.body.innerText.includes('单选题')) await answerQuiz(); setTimeout(loop, CONFIG.checkInterval); } log('v3.2启动:精准关弹窗,自动循环学完必修'); setTimeout(loop, 2000); })();