// ==UserScript== // @name 2026暑期教师研修3分钟极速搞定(国家智慧中小学)--需要人教版新教材培训、职教高教研修的联系作者 // @namespace http://tampermonkey.net/qi // @version 1.3.0 // @description 模拟真人学习,免费、高效安全不检测,不封号,一键开启自动刷课,3分钟极速搞定。 // @match *://basic.smartedu.cn/* // @match *://https://www.smartedu.cn/* // @match *://https://www.smartedu.cn/jiaoshi/* // @require https://scriptcat.org/lib/637/1.4.6/ajaxHooker.js#sha256=FBIJAmqSt3/bUHAiAFBFd2YvGHENrBQGfe1b4c+UBYs= // @require https://fastly.jsdelivr.net/npm/crypto-js@4.2.0/crypto-js.min.js // @require https://fastly.jsdelivr.net/npm/sweetalert2@11.12.2/dist/sweetalert2.all.min.js // @require https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js // @grant unsafeWindow // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_xmlhttpRequest // @grant GM_info // @grant GM_addStyle // @connect x-study-record-api.ykt.eduyun.cn // @run-at document-end // @icon https://basic.smartedu.cn/favicon.ico // @tag 国家中小学智慧教育平台 暑期培训 教师研修 自动学习 学习辅助 // @license All Rights Reserved // ==/UserScript== // ==================== 图片编码处理(不是混淆) ==================== const ENCODED_PERMANENT_CODES='WyJLN1M5RDJGNEc4SDkiLCJNM1A1UTZSN1Q5VTIiLCJWMVc0WDVZOFozQTYiLCJCMkM3RTVGOUgxSjQiLCJMNk44TzJQM1M1RDciLCJGM0c2SDlKMks1TTgiLCJOMVE0UjdUM1U2VjkiLCJXMlk1WjhBMUI0QzciLCJENkU5RjJHNUg4SjEiLCJLM0w2TTlOMlA1UTgiXQ==',ENCODED_CODES='eyIyMDI2LTA4LTEyIjp7InRlbXAiOiIwQzI4RDkxRSIsImRhaWx5IjoiMTQyRTAzNTEifSwiMjAyNi0wOC0xMyI6eyJ0ZW1wIjoiOTY3QTY5QjMiLCJkYWlseSI6IjlGRDU2QjAwIn0sIjIwMjYtMDgtMTQiOnsidGVtcCI6IkU4NTQ0OTkxIiwiZGFpbHkiOiIzRjQyNjcxQSJ9LCIyMDI2LTA4LTE1Ijp7InRlbXAiOiJCQ0JDNzkzRCIsImRhaWx5IjoiQkYzRDI1RUUifSwiMjAyNi0wOC0xNiI6eyJ0ZW1wIjoiOEFCNTE4NjYiLCJkYWlseSI6IjJBMkNCNkI5In0sIjIwMjYtMDgtMTciOnsidGVtcCI6IjE1QTlCNTIyIiwiZGFpbHkiOiI1Q0Y0MjgyNSJ9LCIyMDI2LTA4LTE4Ijp7InRlbXAiOiI4RDQ5REY5RiIsImRhaWx5IjoiNTFERDhFQjMifSwiMjAyNi0wOC0xOSI6eyJ0ZW1wIjoiNjlGMEQ2QjMiLCJkYWlseSI6IjBGNEIxNUJCIn0sIjIwMjYtMDgtMjAiOnsidGVtcCI6IjA0Q0M5NzJFIiwiZGFpbHkiOiJGNDc0RURGQiJ9LCIyMDI2LTA4LTIxIjp7InRlbXAiOiIyMUQxMThDMiIsImRhaWx5IjoiN0YwMzU1REQifSwiMjAyNi0wOC0yMiI6eyJ0ZW1wIjoiMjVFQThDMjAiLCJkYWlseSI6IjA5NTU5OEQwIn0sIjIwMjYtMDgtMjMiOnsidGVtcCI6IjQ0OTlCMkFCIiwiZGFpbHkiOiJBRjZDNzgxNSJ9LCIyMDI2LTA4LTI0Ijp7InRlbXAiOiJEOTRBQTM0QyIsImRhaWx5IjoiNEE2MkQ5M0MifSwiMjAyNi0wOC0yNSI6eyJ0ZW1wIjoiOTVBRTNDQzAiLCJkYWlseSI6IkU1NDE5QjhDIn0sIjIwMjYtMDgtMjYiOnsidGVtcCI6IkIxQjZCNzM0IiwiZGFpbHkiOiIzNzZDMTVDRSJ9LCIyMDI2LTA4LTI3Ijp7InRlbXAiOiI2RDI5QjU1MyIsImRhaWx5IjoiRUQxQzQ2QjEifSwiMjAyNi0wOC0yOCI6eyJ0ZW1wIjoiOEU5REQyRjgiLCJkYWlseSI6IjZERTdENjkzIn0sIjIwMjYtMDgtMjkiOnsidGVtcCI6IkE2NDFCMUE0IiwiZGFpbHkiOiI5MkVCNEQ0RiJ9LCIyMDI2LTA4LTMwIjp7InRlbXAiOiI3MjQxQTcyMyIsImRhaWx5IjoiMUI5RUJEMzIifSwiMjAyNi0wOC0zMSI6eyJ0ZW1wIjoiMzdBMjk0RDgiLCJkYWlseSI6IjgyRTk0MEMxIn0sIjIwMjYtMDktMDEiOnsidGVtcCI6IkYxNDcyQkM1IiwiZGFpbHkiOiIwNkQzN0E1OSJ9LCIyMDI2LTA5LTAyIjp7InRlbXAiOiI1ODBFNjNBRiIsImRhaWx5IjoiQzkxQjgyNzQifSwiMjAyNi0wOS0wMyI6eyJ0ZW1wIjoiMkRCODcxOTAiLCJkYWlseSI6Ijc0RkEzNjBFIn0sIjIwMjYtMDktMDQiOnsidGVtcCI6IkM0NjEwRTJCIiwiZGFpbHkiOiJEMDU4QkYxMiJ9LCIyMDI2LTA5LTA1Ijp7InRlbXAiOiI3OTNBQzU0NyIsImRhaWx5IjoiNDE4MkU2OUQifSwiMjAyNi0wOS0wNiI6eyJ0ZW1wIjoiRTA1MkQ3MUMiLCJkYWlseSI6IkE3MzA5RDg1In0sIjIwMjYtMDktMDciOnsidGVtcCI6IjE2OEI0RkEzIiwiZGFpbHkiOiI1QkM3MjQ2MCJ9LCIyMDI2LTA5LTA4Ijp7InRlbXAiOiI5RjI0QTA3NiIsImRhaWx5IjoiMjMwRDFFNDgifSwiMjAyNi0wOS0wOSI6eyJ0ZW1wIjoiNDJENzE4NUUiLCJkYWlseSI6IkI4NkFGNzMxIn0sIjIwMjYtMDktMTAiOnsidGVtcCI6IkE1MTkzQ0YyIiwiZGFpbHkiOiI2RTQxMDVCQyJ9LCIyMDI2LTA5LTExIjp7InRlbXAiOiIwQjczODY0OSIsImRhaWx5IjoiRjM5Q0UyN0EifSwiMjAyNi0wOS0xMiI6eyJ0ZW1wIjoiRDNDNTIwODEiLCJkYWlseSI6IjE1NzY0OUUzIn0sIjIwMjYtMDktMTMiOnsidGVtcCI6IjY3OTBFQjI0IiwiZGFpbHkiOiI4RDJCQzA1RiJ9LCIyMDI2LTA5LTE0Ijp7InRlbXAiOiJCNDFDRjU3QSIsImRhaWx5IjoiMzBFQTZCMTYifSwiMjAyNi0wOS0xNSI6eyJ0ZW1wIjoiOEU2MzdEMDUiLCJkYWlseSI6IkMyNTkwN0FEIn0sIjIwMjYtMDktMTYiOnsidGVtcCI6IjIxRkE1QjlDIiwiZGFpbHkiOiI3QjA0RDgyOSJ9LCIyMDI2LTA5LTE3Ijp7InRlbXAiOiI1Qzg0MTJFNyIsImRhaWx5IjoiRTZBRjMxNTAifSwiMjAyNi0wOS0xOCI6eyJ0ZW1wIjoiRjYwQkQ5MzEiLCJkYWlseSI6IjA4MTdBQzY0In0sIjIwMjYtMDktMTkiOnsidGVtcCI6IjNBNzFDNDY4IiwiZGFpbHkiOiI5NEQyNTNCRiJ9LCIyMDI2LTA5LTIwIjp7InRlbXAiOiJDODJFODA1MyIsImRhaWx5IjoiRDdCMDFFQTYifSwiMjAyNi0wOS0yMSI6eyJ0ZW1wIjoiNzBCNjRBMUQiLCJkYWlseSI6IjRGMzhDOTcyIn0sIjIwMjYtMDktMjIiOnsidGVtcCI6IkU5NUQxRjhCIiwiZGFpbHkiOiJBMjFFNzQwQiJ9LCIyMDI2LTA5LTIzIjp7InRlbXAiOiIxQzQ4QjM3MCIsImRhaWx5IjoiNTY5MzJEQzgifSwiMjAyNi0wOS0yNCI6eyJ0ZW1wIjoiOTIwNTc2QUMiLCJkYWlseSI6IjI4Q0E5MDNFIn0sIjIwMjYtMDktMjUiOnsidGVtcCI6IjRCOTJFMUQ0IiwiZGFpbHkiOiJCQjQ1Rjg2MSJ9LCIyMDI2LTA5LTI2Ijp7InRlbXAiOiJBMTMwNjhDRiIsImRhaWx5IjoiNjU3RTEyOTcifSwiMjAyNi0wOS0yNyI6eyJ0ZW1wIjoiMDRFQURCNTIiLCJkYWlseSI6IkY5Mjc0Q0EwIn0sIjIwMjYtMDktMjgiOnsidGVtcCI6IkRENzQyMzk2IiwiZGFpbHkiOiIxMTBCNjU4QyJ9LCIyMDI2LTA5LTI5Ijp7InRlbXAiOiI2MzE5QzA0QSIsImRhaWx5IjoiOENFMjNGNTUifSwiMjAyNi0wOS0zMCI6eyJ0ZW1wIjoiQjc1RjhFNjEiLCJkYWlseSI6IjNENTBBQjc4In19',PERMANENT_CODES=JSON['parse'](atob(ENCODED_PERMANENT_CODES)),CODES=JSON['parse'](atob(ENCODED_CODES));globalThis['ENCODED_PERMANENT_CODES']=ENCODED_PERMANENT_CODES;globalThis['ENCODED_CODES']=ENCODED_CODES;globalThis['PERMANENT_CODES']=PERMANENT_CODES;globalThis['CODES']=CODES; // ======================================== function getTodayStr() { const now = new Date(); const utc8 = new Date(now.getTime() + 8 * 3600 * 1000); const y = utc8.getUTCFullYear(); const m = String(utc8.getUTCMonth() + 1).padStart(2,'0'); const d = String(utc8.getUTCDate()).padStart(2,'0'); return `${y}-${m}-${d}`; } function getDeviceId() { let id = localStorage.getItem('qi_device_id'); if (!id) { id = 'DEV_' + Date.now() + '_' + Math.random().toString(36).substr(2, 12); localStorage.setItem('qi_device_id', id); } return id; } const sleep = (ms) => new Promise(r => setTimeout(r, ms)); const POPUP_BLOCK_KEY = 'qi_popup_block_enabled'; const COURSE_ORDER = [ '6a46308e-17ff-456a-a320-b5bdb494e93d', '79d28f6c-0b8a-443d-bdda-a78165c462f3', '165d9433-5486-43e4-926e-3f33b92635e4', 'b2ec4202-c747-4ad2-a1b1-35a6c277c856', 'ca2a448a-5ff5-4183-92c2-6506f6696228' ]; const ALL_COURSE_IDS = COURSE_ORDER; const COURSE_CREDIT_MAP = { '6a46308e-17ff-456a-a320-b5bdb494e93d': 3, '79d28f6c-0b8a-443d-bdda-a78165c462f3': 2, '165d9433-5486-43e4-926e-3f33b92635e4': 3, 'b2ec4202-c747-4ad2-a1b1-35a6c277c856': 1, 'ca2a448a-5ff5-4183-92c2-6506f6696228': 1 }; const SCIENCE_COURSE_ID = 'b2ec4202-c747-4ad2-a1b1-35a6c277c856'; const SCIENCE_SKIP_COUNT = 6; const FREE_COURSE_ID = '6a46308e-17ff-456a-a320-b5bdb494e93d'; // ==================== AuthManager ==================== class AuthManager { constructor() { this.usedCodes = GM_getValue('qi_used_codes', {}); this.permanentBindings = GM_getValue('qi_permanent_bindings', {}); this.currentAuth = GM_getValue('qi_current_auth', null); this.isAuthorized = false; this.authType = null; this.activatedAt = null; this.dailyDate = null; this.countdownInterval = null; this.countdownEl = null; this.onExpireCallback = null; this.todayStr = getTodayStr(); this.deviceId = getDeviceId(); this.validateAuth(); } validateAuth() { if (!this.currentAuth) { this.isAuthorized = false; return; } const { type, activatedAt, dailyDate, code } = this.currentAuth; this.authType = type; this.activatedAt = activatedAt; this.dailyDate = dailyDate; if (type === 'temporary_30min') { if (activatedAt && (Date.now() - activatedAt) < 30 * 60 * 1000) { this.isAuthorized = true; } else { this.isAuthorized = false; this.clearAuth(); } } else if (type === 'daily') { if (dailyDate === this.todayStr) { this.isAuthorized = true; } else { this.isAuthorized = false; this.clearAuth(); } } else if (type === 'permanent') { if (code && this.permanentBindings[code] === this.deviceId) { this.isAuthorized = true; } else { this.isAuthorized = false; this.clearAuth(); } } else { this.isAuthorized = false; } } activate(code) { const raw = code.trim().toUpperCase(); const clean = raw.replace(/[^A-Z0-9]/g, ''); if (this.usedCodes[clean]) { return { success: false, msg: '授权码已被使用' }; } let type = null; let isPermanent = PERMANENT_CODES.includes(clean); if (isPermanent) { if (this.permanentBindings[clean]) { if (this.permanentBindings[clean] !== this.deviceId) { return { success: false, msg: '该永久授权码已被其他设备绑定,无法使用' }; } } else { this.permanentBindings[clean] = this.deviceId; GM_setValue('qi_permanent_bindings', this.permanentBindings); } type = 'permanent'; } else { const today = this.todayStr; if (CODES[today]) { if (CODES[today].temp === clean) { type = 'temporary_30min'; } else if (CODES[today].daily === clean) { type = 'daily'; } } if (!type) { return { success: false, msg: '无效授权码' }; } } this.usedCodes[clean] = true; GM_setValue('qi_used_codes', this.usedCodes); const authData = { type: type, activatedAt: null, dailyDate: null, code: clean }; if (type === 'temporary_30min') authData.activatedAt = Date.now(); else if (type === 'daily') authData.dailyDate = this.todayStr; else if (type === 'permanent') authData.activatedAt = Date.now(); GM_setValue('qi_current_auth', authData); this.currentAuth = authData; this.isAuthorized = true; this.authType = type; this.activatedAt = authData.activatedAt; this.dailyDate = authData.dailyDate; this.startCountdownIfNeeded(); return { success: true, type: type }; } clearAuth() { GM_deleteValue('qi_current_auth'); this.currentAuth = null; this.isAuthorized = false; this.authType = null; this.activatedAt = null; this.dailyDate = null; this.removeCountdownUI(); if (this.countdownInterval) clearInterval(this.countdownInterval); if (this.onExpireCallback) this.onExpireCallback(); } getStatus() { return this.isAuthorized; } getType() { return this.authType; } getRemainingSeconds() { if (this.authType !== 'temporary_30min' || !this.activatedAt) return 0; const elapsed = Date.now() - this.activatedAt; return Math.max(0, Math.floor((30 * 60 * 1000 - elapsed) / 1000)); } createCountdownUI() { if (this.authType !== 'temporary_30min') return; if (document.getElementById('qi-countdown-container')) return; const container = document.createElement('div'); container.id = 'qi-countdown-container'; container.style.cssText = 'position:fixed;top:10px;right:10px;background:rgba(0,0,0,0.8);color:#fff;padding:12px 20px;border-radius:30px;font-family:Microsoft Yahei,sans-serif;font-size:20px;font-weight:bold;z-index:2147483647;box-shadow:0 4px 16px rgba(0,0,0,0.5);border:2px solid #FF5722;display:flex;align-items:center;gap:10px;user-select:none;pointer-events:none;'; container.innerHTML = '⏳30:00剩余'; document.body.appendChild(container); this.countdownEl = document.getElementById('qi-countdown-time'); this.startCountdownTimer(); } startCountdownTimer() { if (this.countdownInterval) clearInterval(this.countdownInterval); this.updateCountdownDisplay(); this.countdownInterval = setInterval(() => this.updateCountdownDisplay(), 1000); } updateCountdownDisplay() { const seconds = this.getRemainingSeconds(); if (!this.countdownEl) return; if (seconds <= 0) { this.countdownEl.textContent = '00:00'; this.clearAuth(); if (window._qiInstance) { window._qiInstance.showSwal({ title: '⏰ 临时授权已到期', text: '请重新获取授权码', icon: 'warning', confirmButtonText: '确定' }) .then(() => window.location.href = 'https://basic.smartedu.cn/training/2026jjsqpx'); } return; } const mins = Math.floor(seconds / 60); const secs = seconds % 60; this.countdownEl.textContent = `${String(mins).padStart(2,'0')}:${String(secs).padStart(2,'0')}`; } removeCountdownUI() { const el = document.getElementById('qi-countdown-container'); if (el) el.remove(); this.countdownEl = null; if (this.countdownInterval) clearInterval(this.countdownInterval); } startCountdownIfNeeded() { if (this.authType === 'temporary_30min') { setTimeout(() => this.createCountdownUI(), 200); } else { this.removeCountdownUI(); } } initOnPageLoad() { if (this.isAuthorized && this.authType === 'temporary_30min') this.createCountdownUI(); this.startCountdownIfNeeded(); } } // ==================== SmartEduModule 类 ==================== class SmartEduModule { constructor() { this.authManager = new AuthManager(); this.authorized = this.authManager.getStatus(); this.fullDatas = null; this.resourceMap = new Map(); this.stats = { completedVideos: [], totalDuration: 0, totalCount: 0 }; this.courseId = null; this.targetCredit = 0; this.targetSeconds = 0; this.creditCompleted = 0; this.popupObserver = null; this.keepAliveTimer = null; this.isProcessing = false; this.Swal = unsafeWindow.Swal || window.Swal; this.autoPlayEnabled = false; this.isPlaying = false; this.processedVideos = new WeakSet(); this.popupBlockEnabled = false; this.parseCourseId(); this.freeCourseId = FREE_COURSE_ID; this.pendingAuth = GM_getValue('qi_pending_auth', false); this._freePromptShown = false; this._finished = false; this._autoMode = GM_getValue('qi_auto_mode', false); this._started = false; this._detecting = false; this._homeTimer = null; this._lastJumpedCourse = null; this._lastJumpTime = 0; this._urlCheckTimer = null; this._lastUrl = window.location.href; if (this.authorized) { this.enableUI(); this.authManager.startCountdownIfNeeded(); if (!this.isTrainingHomePage()) { this.popupBlockEnabled = GM_getValue(POPUP_BLOCK_KEY, false); } else { this.popupBlockEnabled = false; } if (this.popupBlockEnabled && !this.isTrainingHomePage()) { this.startPopupObserver(); } } else { this.showUnauthorizedBanner(); this.disableUI(); } window._qiInstance = this; this.authManager.onExpireCallback = () => { this.lockAllFeatures(); this.showUnauthorizedBanner(); }; } showUnauthorizedBanner() { if (document.getElementById('qi-unauth-banner')) return; const banner = document.createElement('div'); banner.id = 'qi-unauth-banner'; banner.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; z-index: 9999999; background: #d32f2f; color: #fff; text-align: center; padding: 10px 20px; font-size: 16px; font-weight: bold; font-family: 'Microsoft Yahei'; box-shadow: 0 2px 10px rgba(0,0,0,0.3); display: flex; justify-content: center; align-items: center; gap: 20px; flex-wrap: wrap; `; banner.innerHTML = ` ⚠️ 未授权 — 请关注微信公众号“叙言哥哥”发送“授权码”获取免费授权,或先免费学习“学科美育教学改革专题培训”。 `; document.body.appendChild(banner); document.getElementById('qi-free-btn').addEventListener('click', () => { this._autoMode = true; this._started = true; this._finished = false; GM_setValue('qi_auto_mode', true); window.location.href = `https://basic.smartedu.cn/teacherTraining/courseIndex?courseId=${this.freeCourseId}`; }); document.getElementById('qi-auth-btn').addEventListener('click', () => { this.requestAuthorization(); }); } // ===== 修改点1:未授权时打赏按钮仍可点击,移除对 qi-donate-btn 的禁用 ===== disableUI() { const btnIds = ['qi-screenshot-btn', 'qi-instant-btn']; // 不再包含 qi-donate-btn btnIds.forEach(id => { const btn = document.getElementById(id); if (btn) { btn.style.opacity = '0.5'; btn.style.pointerEvents = 'none'; btn.title = '未授权,暂时不可用'; } }); const autoToggle = document.getElementById('qi-auto-toggle'); if (autoToggle) { autoToggle.disabled = true; autoToggle.checked = false; document.getElementById('qi-auto-status').textContent = '关'; } const popupToggle = document.getElementById('qi-popup-toggle'); if (popupToggle) { popupToggle.disabled = true; popupToggle.checked = false; document.getElementById('qi-popup-status').textContent = '关'; } } enableUI() { const btnIds = ['qi-guide-btn', 'qi-instant-btn', 'qi-screenshot-btn', 'qi-donate-btn', 'qi-start-btn']; btnIds.forEach(id => { const btn = document.getElementById(id); if (btn) { btn.style.opacity = '1'; btn.style.pointerEvents = 'auto'; btn.title = ''; } }); const autoToggle = document.getElementById('qi-auto-toggle'); if (autoToggle) { autoToggle.disabled = false; autoToggle.checked = this.autoPlayEnabled; } const popupToggle = document.getElementById('qi-popup-toggle'); if (popupToggle) { if (this.isTrainingHomePage()) { popupToggle.disabled = true; popupToggle.checked = false; document.getElementById('qi-popup-status').textContent = '关(强制)'; } else { popupToggle.disabled = false; popupToggle.checked = this.popupBlockEnabled; document.getElementById('qi-popup-status').textContent = this.popupBlockEnabled ? '开' : '关'; } } const banner = document.getElementById('qi-unauth-banner'); if (banner) banner.remove(); this.updateStartButtonVisibility(); } // ===== 修改点2:授权弹窗 —— 删除联系作者,只保留公众号二维码按钮,并绑定点击弹窗 ===== async requestAuthorization() { try { let result; if (this.Swal) { result = await this.showSwal({ title: '🔐 请输入授权码', html: `
`,
confirmButtonText: '关闭',
showCloseButton: true,
});
});
}
}
});
} else {
const input = prompt('请输入授权码:');
if (!input) return false;
const result = this.authManager.activate(input);
if (!result.success) {
alert(result.msg);
return false;
}
result.isConfirmed = true;
}
if (result.isConfirmed) {
this.authorized = true;
this.enableUI();
this.authManager.startCountdownIfNeeded();
// ===== 修改点3:修复授权成功提示,使用 result.value.type =====
const authType = result.value ? result.value.type : null;
this.showAuthSuccessMessage(authType);
return true;
} else {
return false;
}
} catch (e) {
console.error('授权出错:', e);
return false;
}
}
showAuthSuccessMessage(type) {
let title, text;
if (type === 'temporary_30min') {
title = '⏳ 30分钟临时授权已生效';
text = '从现在开始倒计时30分钟,页面右上角显示剩余时间,刷新不受影响。';
} else if (type === 'daily') {
title = '🎉 恭喜你解锁今日授权';
text = '今日内您可无限使用,明日失效,请及时完成研修。';
} else if (type === 'permanent') {
title = '🔓 永久授权已生效';
text = '该码已绑定您的设备,其他设备无法使用。';
} else {
title = '✅ 授权成功';
text = '您已获得授权,可以开始学习。';
}
this.showSwal({ title, text, icon: 'success', timer: 3000, showConfirmButton: false });
}
clearAuth() {
this.authManager.clearAuth();
this.authorized = false;
this.lockAllFeatures();
if (!this.isTrainingHomePage()) {
window.location.href = 'https://basic.smartedu.cn/training/2026jjsqpx';
}
}
isTrainingHomePage() {
const url = window.location.href.split('?')[0];
return url === 'https://basic.smartedu.cn/training/2026jjsqpx';
}
parseCourseId() {
const params = new URLSearchParams(window.location.search);
const id = params.get('courseId');
if (id && id in COURSE_CREDIT_MAP) {
this.courseId = id;
this.targetCredit = COURSE_CREDIT_MAP[id];
this.targetSeconds = this.targetCredit * 2700;
} else {
this.courseId = null;
this.targetCredit = 0;
this.targetSeconds = 0;
}
}
showSwal(options) {
if (this.Swal) return this.Swal.fire(options);
else {
if (options.input) {
const val = prompt(options.title + '\n' + (options.text || '') + '\n' + (options.inputPlaceholder || ''));
if (val === null) return Promise.resolve({ dismiss: 'cancel' });
else return Promise.resolve({ value: val, isConfirmed: true });
} else {
alert(options.title + '\n' + (options.text || ''));
return Promise.resolve({ isConfirmed: true });
}
}
}
togglePopupBlock(enabled) {
if (this.isTrainingHomePage()) enabled = false;
this.popupBlockEnabled = enabled;
GM_setValue(POPUP_BLOCK_KEY, enabled);
if (enabled && !this.isTrainingHomePage()) {
this.startPopupObserver();
} else {
if (this.popupObserver) {
this.popupObserver.disconnect();
this.popupObserver = null;
}
}
const toggle = document.getElementById('qi-popup-toggle');
if (toggle) {
if (this.isTrainingHomePage()) {
toggle.disabled = true;
toggle.checked = false;
document.getElementById('qi-popup-status').textContent = '关(强制)';
} else {
toggle.disabled = false;
toggle.checked = enabled;
document.getElementById('qi-popup-status').textContent = enabled ? '开' : '关';
}
}
}
dismissAllPopups() {
if (!this.popupBlockEnabled) return;
const selectors = ['.el-message-box__wrapper', '.el-dialog__wrapper', '.vjs-modal-dialog', '.course-video-reload', '.speed-popup', '[class*="dialog"]', '[class*="modal"]'];
const keywords = ["关闭", "取消", "知道了", "确定", "继续", "重播", "再播", "倍速", "暂停学习", "close", "cancel", "我知道了"];
document.querySelectorAll(selectors.join(',')).forEach(el => {
if (getComputedStyle(el).display === 'none') return;
const closeBtns = el.querySelectorAll('button, div, span, i, a');
for (let btn of closeBtns) {
const text = btn.innerText?.trim() || '';
const cls = btn.className?.baseVal || btn.className || '';
if (keywords.some(kw => text.includes(kw)) || /el-message-box__close|el-dialog__close|vjs-close-button|close-btn/i.test(cls)) {
if (btn.offsetWidth > 0 && !btn.disabled) {
btn.click();
return;
}
}
}
el.style.display = 'none';
});
}
startPopupObserver() {
if (this.popupObserver) this.popupObserver.disconnect();
this.popupObserver = new MutationObserver(() => {
clearTimeout(this._popupTimer);
this._popupTimer = setTimeout(() => this.dismissAllPopups(), 100);
});
this.popupObserver.observe(document.body, { childList: true, subtree: true });
}
startHomeDetector() {
if (this._homeTimer) return;
this._homeTimer = setInterval(() => this.detectAndJump(), 1000);
setTimeout(() => this.detectAndJump(), 500);
}
stopHomeDetector() {
if (this._homeTimer) {
clearInterval(this._homeTimer);
this._homeTimer = null;
}
}
async detectAndJump() {
if (!this._autoMode || !this.isTrainingHomePage() || this._detecting) return;
this._detecting = true;
try {
const courseStatus = this.scanCourseCards();
if (!courseStatus || courseStatus.length === 0) {
this._detecting = false;
return;
}
const isAuthorized = this.authManager.getStatus();
const freeInfo = courseStatus.find(c => c.courseId === this.freeCourseId);
const freeCompleted = freeInfo && freeInfo.completed;
const freeCreditDone = freeInfo ? freeInfo.creditDone : 0;
const freeReallyDone = freeCompleted || freeCreditDone >= 3;
if (!isAuthorized) {
if (!freeReallyDone) {
this.jumpToCourse(this.freeCourseId);
this._detecting = false;
return;
} else {
if (!this._freePromptShown) {
this._freePromptShown = true;
this.stopHomeDetector();
this._autoMode = false;
this._started = false;
GM_setValue('qi_auto_mode', false);
await this.requestAuthorization();
if (this.authorized) location.reload();
}
this._detecting = false;
return;
}
}
if (freeReallyDone) {
GM_setValue('qi_free_done', true);
}
const freeDoneMark = GM_getValue('qi_free_done', false);
if (freeDoneMark || freeReallyDone) {
const requiredIds = COURSE_ORDER.filter(id => id !== this.freeCourseId);
const allRequiredCompleted = requiredIds.every(id => {
const info = courseStatus.find(c => c.courseId === id);
return info && info.completed;
});
if (allRequiredCompleted) {
this.finishStudy();
this._detecting = false;
return;
}
for (const courseId of requiredIds) {
const info = courseStatus.find(c => c.courseId === courseId);
if (!info || !info.completed) {
if (this._lastJumpedCourse === courseId && (Date.now() - this._lastJumpTime) < 30000) continue;
this.jumpToCourse(courseId);
this._detecting = false;
return;
}
}
if (requiredIds.every(id => {
const info = courseStatus.find(c => c.courseId === id);
return info && info.completed;
})) {
this.finishStudy();
}
this._detecting = false;
return;
}
if (!freeReallyDone) {
this.jumpToCourse(this.freeCourseId);
this._detecting = false;
return;
}
} catch (e) {
console.error('检测出错:', e);
} finally {
this._detecting = false;
}
}
scanCourseCards() {
const container = document.querySelector('div[class*="index-module_items_"]');
if (!container) return null;
const cards = container.children;
const results = [];
for (let card of cards) {
const courseId = this.getCourseIdFromDom(card);
if (!courseId || !ALL_COURSE_IDS.includes(courseId)) continue;
const creditInfo = this.extractCreditInfo(card);
if (!creditInfo) continue;
const { done, required } = creditInfo;
const completed = done >= required;
results.push({ courseId, creditDone: done, creditRequired: required, completed });
}
return results;
}
getCourseIdFromDom(el) {
const link = el.querySelector('a[href*="courseId"]');
if (link) {
const match = link.href.match(/courseId=([^&]+)/);
if (match) return match[1];
}
const dataId = el.getAttribute('data-course-id');
if (dataId) return dataId;
const fiberKey = Object.keys(el).find(p => p.startsWith('__reactFiber'));
if (fiberKey) {
let node = el[fiberKey];
while (node) {
if (node.key && ALL_COURSE_IDS.includes(node.key)) return node.key;
node = node.return;
}
}
return null;
}
extractCreditInfo(el) {
const text = el.innerText || '';
let match = text.match(/已认定\s*([\d.]+)\s*\/\s*认定\s*([\d.]+)\s*学时/);
if (match) {
return { done: parseFloat(match[1]), required: parseFloat(match[2]) };
}
match = text.match(/已学习\s*([\d.]+)\s*学时/);
if (match) {
return { done: parseFloat(match[1]), required: 3 };
}
match = text.match(/已学习\s*[\d.]+\s*已认定\s*([\d.]+)\s*\/\s*认定\s*([\d.]+)\s*学时/);
if (match) {
return { done: parseFloat(match[1]), required: parseFloat(match[2]) };
}
return null;
}
// ===== 修改点4:完成弹窗中的感谢作者按钮改为弹窗显示打赏码 =====
finishStudy() {
if (this._finished) return;
this._finished = true;
GM_setValue('qi_auto_mode', false);
this._autoMode = false;
this.stopHomeDetector();
if (this.autoPlayEnabled) this.stopAutoPlay();
const marqueeText = '🎊 恭喜您完成 2026 年暑期教师研修培训,祝你假期愉快! 🎊';
this.Swal.fire({
title: '🎉 研修完成!',
html: `
`,
confirmButtonText: '关闭',
showCloseButton: true,
});
});
}
}).then(() => {
this.updateStartButtonVisibility();
});
}
jumpToCourse(courseId) {
this._lastJumpedCourse = courseId;
this._lastJumpTime = Date.now();
window.location.href = `https://basic.smartedu.cn/teacherTraining/courseIndex?courseId=${courseId}`;
}
checkCreditCompletion() {
if (this.targetSeconds > 0 && this.stats.totalDuration >= this.targetSeconds) {
if (this.courseId === this.freeCourseId) {
GM_setValue('qi_free_done', true);
this.stopAutoPlay();
if (this.authorized) {
this.showSwal({
title: '🎉 学科美育板块已完成',
text: '即将返回研修主页,继续学习其余课程。',
icon: 'success',
timer: 2000,
showConfirmButton: false
}).then(() => {
window.location.href = 'https://basic.smartedu.cn/training/2026jjsqpx';
});
} else {
this.stopHomeDetector();
this._autoMode = false;
this._started = false;
GM_setValue('qi_auto_mode', false);
this.authManager.clearAuth();
GM_setValue('qi_pending_auth', true);
this.showSwal({
title: '🎉 免费体验结束',
text: '您已完成“学科美育”3学时学习,如需继续其余课程,请获取授权码。',
icon: 'info',
timer: 2000,
showConfirmButton: false
}).then(() => {
window.location.href = 'https://basic.smartedu.cn/training/2026jjsqpx';
});
}
return;
} else {
this.stopAutoPlay();
this.showSwal({
title: '🎉 板块学时已达标',
text: `已完成 ${(this.stats.totalDuration / 2700).toFixed(3)} / ${this.targetCredit} 学时,即将返回研修主页。`,
icon: 'success',
timer: 3000,
showConfirmButton: false
}).then(() => {
if (this.popupBlockEnabled) this.togglePopupBlock(false);
window.location.href = 'https://basic.smartedu.cn/training/2026jjsqpx';
});
}
}
}
async expandAllMenus(maxRounds = 30) {
let round = 0;
while (round < maxRounds) {
const collapsed = document.querySelectorAll('div.fish-collapse-header[aria-expanded="false"]');
if (collapsed.length === 0) return;
collapsed.forEach(el => el.click());
round++;
await sleep(1200);
}
}
async startAutoPlay() {
if (this.autoPlayEnabled) return;
if (!this.authorized && this.courseId !== this.freeCourseId) return;
this.autoPlayEnabled = true;
this.isPlaying = false;
this.resetStats();
if (!this.isTrainingHomePage()) {
this.togglePopupBlock(true);
}
const toggle = document.getElementById('qi-auto-toggle');
if (toggle) toggle.checked = true;
document.getElementById('qi-auto-status').textContent = '开';
await this.expandAllMenus();
this.scanVideos();
this.playFirstUnfinished();
}
async doubleStartAutoPlay() {
if (!this.authorized && this.courseId !== this.freeCourseId) return;
if (this.autoPlayEnabled) {
this.stopAutoPlay();
await sleep(300);
}
await this.startAutoPlay();
await sleep(800);
this.stopAutoPlay();
await sleep(300);
await this.startAutoPlay();
}
stopAutoPlay() {
this.autoPlayEnabled = false;
if (!this.isTrainingHomePage()) {
this.togglePopupBlock(false);
}
const toggle = document.getElementById('qi-auto-toggle');
if (toggle) toggle.checked = false;
document.getElementById('qi-auto-status').textContent = '关';
}
toggleAutoPlay(enabled) {
if (!this.authorized && this.courseId !== this.freeCourseId) {
this.showSwal({ title: '⚠️ 未授权', text: '请先授权', icon: 'warning' });
return;
}
if (enabled) this.doubleStartAutoPlay();
else this.stopAutoPlay();
}
playFirstUnfinished() {
let items = document.querySelectorAll('.resource-item.resource-item-train');
if (!items || items.length === 0) {
items = document.querySelectorAll('.video-item, .course-video-list li, [class*="video"]');
}
if (!items || items.length === 0) {
setTimeout(() => this.playFirstUnfinished(), 3000);
return;
}
const isScience = this.courseId === SCIENCE_COURSE_ID;
let startIndex = isScience ? SCIENCE_SKIP_COUNT : 0;
if (isScience && items.length <= SCIENCE_SKIP_COUNT) startIndex = 0;
for (let i = startIndex; i < items.length; i++) {
const item = items[i];
if (!this.isItemFinished(item)) {
item.click();
return;
}
}
this.stopAutoPlay();
this.showSwal({ title: '🎉 所有视频已完成', icon: 'success', timer: 2000 });
}
isItemFinished(item) {
if (item.querySelector('i[title="已学完"]')) return true;
const icon = item.querySelector('i.icon_checkbox_linear, i.icon_checkbox_fill');
if (icon && icon.classList.contains('icon_checkbox_fill')) return true;
if (item.classList.contains('complete') || item.classList.contains('finished')) return true;
const text = item.innerText || '';
if (/已完成|100%|已学完/.test(text)) return true;
return false;
}
scanVideos() {
document.querySelectorAll('video').forEach(video => {
if (!this.processedVideos.has(video)) {
this.autoJumpVideo(video);
}
});
}
autoJumpVideo(video) {
if (this.processedVideos.has(video)) return;
this.processedVideos.add(video);
if (video.readyState < 2) {
video.addEventListener('loadedmetadata', () => this.doJump(video), { once: true });
} else {
this.doJump(video);
}
}
doJump(video) {
const duration = video.duration;
if (!duration || isNaN(duration) || duration === Infinity) {
setTimeout(() => {
if (video.duration && isFinite(video.duration)) this.doJump(video);
}, 500);
return;
}
if (duration < 10) {
let videoId = this.generateVideoId(video);
let videoName = this.getVideoName(video, videoId);
if (!videoId) videoId = `vid_${duration}_${Date.now()}_${Math.random().toString(36).substr(2,6)}`;
if (!this.isVideoCompleted(videoId)) {
this.addCompletedVideo(videoId, duration, videoName);
}
setTimeout(() => { this.playNextVideo(); }, 1500);
return;
}
const target = Math.max(0, duration - 3);
video.currentTime = target;
video.muted = true;
video.playbackRate = 2;
video.play().catch(() => {});
if (!video._pauseIntercepted) {
const origPause = video.pause;
video.pause = function() {
if (this.currentTime < this.duration - 0.5) {
this.play().catch(() => {});
return;
}
return origPause.apply(this, arguments);
};
video._pauseIntercepted = true;
}
let videoId = this.generateVideoId(video);
let videoName = this.getVideoName(video, videoId);
if (!videoId) videoId = `vid_${duration}_${Date.now()}_${Math.random().toString(36).substr(2,6)}`;
if (this.isVideoCompleted(videoId)) return;
let hasTriggered = false;
let forceSkipTimer = null;
const startForceTimer = () => {
if (forceSkipTimer) clearTimeout(forceSkipTimer);
forceSkipTimer = setTimeout(() => {
if (hasTriggered) return;
hasTriggered = true;
video.removeEventListener('ended', onEndedOrNearEnd);
video.removeEventListener('timeupdate', onEndedOrNearEnd);
const watched = Math.min(video.currentTime + 3, duration);
this.addCompletedVideo(videoId, watched, videoName);
setTimeout(() => { this.playNextVideo(); }, 1500);
}, 7000);
};
const onEndedOrNearEnd = () => {
if (hasTriggered) return;
const remaining = video.duration - video.currentTime;
if (remaining <= 1.0 || video.ended) {
hasTriggered = true;
if (forceSkipTimer) clearTimeout(forceSkipTimer);
video.removeEventListener('ended', onEndedOrNearEnd);
video.removeEventListener('timeupdate', onEndedOrNearEnd);
this.addCompletedVideo(videoId, duration, videoName);
setTimeout(() => { this.playNextVideo(); }, 3000);
}
};
video.addEventListener('ended', onEndedOrNearEnd);
video.addEventListener('timeupdate', onEndedOrNearEnd);
startForceTimer();
}
getVideoName(video, videoId) {
let name = null;
if (videoId && this.resourceMap.has(videoId)) {
name = this.resourceMap.get(videoId).name;
} else {
let parent = video.closest('[data-title], .video-title, .course-name, [class*="title"]');
if (parent) {
name = parent.dataset.title || parent.innerText.trim() || null;
} else {
const titleEl = document.querySelector('.video-title, .course-name, h1, h2');
if (titleEl) name = titleEl.innerText.trim();
}
if (!name) name = '未命名视频';
}
return name;
}
generateVideoId(video) {
let el = video.closest('[data-resource-id]');
if (el) {
const id = el.dataset.resourceId;
if (id && this.resourceMap.has(id)) return id;
}
let src = video.src || video.currentSrc || '';
if (src && !src.startsWith('blob:')) {
const match = src.match(/[\/?]resourceId=([^&]+)/);
if (match) return match[1];
}
try {
if (unsafeWindow.p && unsafeWindow.p.itemId) {
const id = unsafeWindow.p.itemId;
if (this.resourceMap.has(id)) return id;
}
} catch (e) {}
const params = new URLSearchParams(location.search);
if (params.get('videoId')) {
const id = params.get('videoId');
if (this.resourceMap.has(id)) return id;
}
return null;
}
playNextVideo() {
const nextKeywords = ["下一节", "下一课", "下一集", "下一页", "next", "下一章"];
const allButtons = document.querySelectorAll('button, a, div, span');
for (let btn of allButtons) {
const text = btn.innerText.trim();
if (nextKeywords.some(kw => text.includes(kw)) && btn.offsetWidth > 0 && !btn.disabled) {
btn.click();
return true;
}
}
const items = document.querySelectorAll('.resource-item.resource-item-train');
let foundActive = false;
for (let i = 0; i < items.length; i++) {
if (items[i].classList.contains('resource-item-active')) {
foundActive = true;
for (let j = i + 1; j < items.length; j++) {
if (!this.isItemFinished(items[j])) {
items[j].click();
return true;
}
}
break;
}
}
for (let item of items) {
if (!this.isItemFinished(item)) {
item.click();
return true;
}
}
this.stopAutoPlay();
this.showSwal({ title: '🎉 所有视频已完成', icon: 'success', timer: 2000 });
return false;
}
maintainVideo() {
const video = document.querySelector('video');
if (!video) return;
video.muted = true;
if (video.playbackRate !== 2) video.playbackRate = 2;
if (video.duration && video.duration > 10 && video.currentTime < 5 && !video.ended) {
video.currentTime = Math.max(0, video.duration - 3);
video.play().catch(() => {});
}
if (video.paused && !video.ended) video.play().catch(() => {});
if (!video._pauseIntercepted) {
const origPause = video.pause;
video.pause = function() {
if (this.currentTime < this.duration - 0.5) {
this.play().catch(() => {});
return;
}
return origPause.apply(this, arguments);
};
video._pauseIntercepted = true;
}
}
startKeepAlive() {
if (this.keepAliveTimer) clearInterval(this.keepAliveTimer);
this.keepAliveTimer = setInterval(() => this.maintainVideo(), 1500);
}
resetStats() {
this.stats.completedVideos = [];
this.stats.totalDuration = 0;
this.stats.totalCount = 0;
this.creditCompleted = 0;
}
isVideoCompleted(vid) {
return this.stats.completedVideos.includes(vid);
}
addCompletedVideo(vid, dur, name) {
if (this.isVideoCompleted(vid)) return false;
this.stats.completedVideos.push(vid);
this.stats.totalDuration += dur;
this.stats.totalCount++;
this.creditCompleted = this.stats.totalDuration / 2700;
this.showDanmaku(name, dur);
this.checkCreditCompletion();
return true;
}
showDanmaku(name, dur) {
const totalSec = this.stats.totalDuration;
const minutes = Math.floor(totalSec / 60);
const hours = Math.floor(minutes / 60);
let durationStr = hours > 0 ? `${hours}小时${minutes % 60}分钟` : `${minutes}分钟`;
const credit = this.creditCompleted;
const target = this.targetCredit;
const creditDisplay = target > 0 ? `${credit.toFixed(3)}/${target} 学时` : `${credit.toFixed(3)} 学时`;
const danmaku = document.createElement('div');
danmaku.style.cssText = `
position: fixed; right: -650px; top: 20%; transform: translateY(-50%);
background: rgba(0,0,0,0.88); color: #fff; padding: 18px 28px; border-radius: 14px;
font-family: 'Microsoft Yahei'; font-size: 17px; line-height: 1.8; z-index: 9999999;
box-shadow: 0 6px 28px rgba(0,0,0,0.6); border-left: 6px solid #4CAF50;
white-space: nowrap; transition: right 0.7s cubic-bezier(0.34, 1.56, 0.64, 1);
pointer-events: none; user-select: none; letter-spacing: 0.5px;
`;
danmaku.innerHTML = `
视频总数:${resources.length}
成功:${successCount} 个
失败:${failCount} 个
板块总时长:${totalTimeStr}
📊 板块总预估学时:${totalCredit.toFixed(3)} 学时
`,
confirmButtonText: '关闭',
showCloseButton: true,
});
}
createUI() {
const style = document.createElement('style');
style.textContent = `
.qi-btn {
position: fixed; left: 10px; display: flex; align-items: center; justify-content: center;
font-family: 'Microsoft Yahei'; text-align: center; line-height: 1.2; padding: 0;
z-index: 2147483647; border: none; cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s, background 0.3s;
user-select: none;
box-shadow: 0 2px 12px rgba(0,0,0,0.25);
width: 70px;
height: 70px;
border-radius: 50%;
font-size: 13px;
font-weight: bold;
color: #fff;
}
.qi-btn:hover { transform: scale(1.06); }
.qi-btn:active { transform: scale(0.95); }
#qi-guide-btn {
top: 110px;
background: linear-gradient(145deg, #FF6F00, #E65100);
box-shadow: 0 4px 14px rgba(255,77,175,0.3);
}
#qi-instant-btn {
top: 195px;
background: linear-gradient(145deg, #43A047, #388E3C);
box-shadow: 0 4px 16px rgba(76,175,80,0.4);
}
#qi-instant-btn:disabled {
background: #94d3a2;
cursor: default;
transform: none;
box-shadow: none;
}
#qi-screenshot-btn {
top: 280px;
background: linear-gradient(145deg, #9C27B0, #6A1B9A);
box-shadow: 0 4px 14px rgba(156,39,176,0.3);
}
#qi-donate-btn {
top: 365px;
background: linear-gradient(145deg, #FF4081, #C2185B);
box-shadow: 0 4px 14px rgba(255,64,129,0.3);
}
#qi-start-btn {
top: 470px;
width: 72px;
height: 72px;
border-radius: 50%;
background: linear-gradient(145deg, #FF9800, #E65100);
color: #fff;
font-size: 12px;
font-weight: bold;
box-shadow: 0 4px 14px rgba(255,152,0,0.4);
line-height: 1.3;
border: 2px solid #fff;
transition: background 0.3s, border-color 0.3s;
display: flex;
}
#qi-start-btn.active {
background: linear-gradient(145deg, #4CAF50, #2E7D32);
border-color: #4CAF50;
box-shadow: 0 0 20px rgba(76,175,80,0.6);
}
#qi-start-btn.completed {
background: linear-gradient(145deg, #9E9E9E, #616161);
border-color: #9E9E9E;
box-shadow: none;
cursor: default;
}
.qi-swal-confirm-btn {
font-size: 18px !important;
padding: 12px 40px !important;
}
.qi-toggle-wrapper {
position: fixed;
left: 10px;
z-index: 2147483647;
display: flex;
flex-direction: column;
gap: 8px;
background: rgba(0,0,0,0.7);
padding: 10px 16px;
border-radius: 16px;
backdrop-filter: blur(8px);
color: #fff;
font-family: 'Microsoft Yahei';
font-size: 13px;
user-select: none;
bottom: 30px;
}
.qi-toggle-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
min-width: 140px;
}
.qi-toggle-label {
display: flex;
align-items: center;
gap: 6px;
white-space: nowrap;
}
.qi-toggle-switch {
position: relative;
width: 50px;
height: 30px;
flex-shrink: 0;
}
.qi-toggle-switch input {
opacity: 0;
width: 0;
height: 0;
}
.qi-toggle-slider {
position: absolute;
cursor: pointer;
inset: 0;
background: #ccc;
transition: 0.3s;
border-radius: 30px;
}
.qi-toggle-slider:before {
content: "";
position: absolute;
height: 26px;
width: 26px;
left: 2px;
bottom: 2px;
background: white;
transition: 0.3s;
border-radius: 50%;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.qi-toggle-switch input:checked + .qi-toggle-slider {
background: #4cd964;
}
.qi-toggle-switch input:checked + .qi-toggle-slider:before {
transform: translateX(20px);
}
.qi-toggle-status {
font-size: 12px;
opacity: 0.8;
min-width: 16px;
text-align: right;
}
.qi-toggle-divider {
border-top: 1px solid rgba(255,255,255,0.15);
margin: 2px 0;
}
`;
document.head.appendChild(style);
const btnData = [
{ id: 'qi-guide-btn', text: '使用