您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
智慧中小学平台自动学习助手|支持单账号快速处理|有网页版|秒过|快速
// ==UserScript== // @name 智慧中小学暑假研修学习助手-秒过 // @namespace http://tampermonkey.net/ // @version 3.0.2 // @description 智慧中小学平台自动学习助手|支持单账号快速处理|有网页版|秒过|快速 // @author beyondddd // @match https://www.smartedu.cn/* // @match https://basic.smartedu.cn/* // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_notification // @connect yanxiu.pro // @run-at document-end // ==/UserScript== (function() { 'use strict'; // 全局变量 let isCollapsed = GM_getValue('isCollapsed', false); let announcement = ''; let instructions = ''; // 创建样式 function createStyles() { const style = document.createElement('style'); style.textContent = ` :root { --primary-color: #4c6ef5; --primary-gradient: linear-gradient(135deg, #4c6ef5 0%, #364fc7 100%); --secondary-color: #20c997; --secondary-gradient: linear-gradient(135deg, #20c997 0%, #12b886 100%); --accent-color: #f03e3e; --warning-color: #fd7e14; --success-color: #51cf66; --danger-color: #f03e3e; --info-color: #339af0; } #smartedu-assistant { position: fixed; top: 20px; right: 20px; width: 380px; background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(20px); border-radius: 16px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15); z-index: 999999; border: 1px solid rgba(255, 255, 255, 0.3); font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Arial, sans-serif; transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); max-height: 90vh; overflow: hidden; } #smartedu-assistant.collapsed { width: 200px; height: 60px; } #smartedu-assistant.collapsed .assistant-content { display: none; } .assistant-header { background: var(--primary-gradient); color: white; padding: 15px 20px; border-radius: 16px 16px 0 0; display: flex; justify-content: space-between; align-items: center; cursor: pointer; user-select: none; } .assistant-title { font-weight: 700; font-size: 16px; display: flex; align-items: center; } .assistant-title i { margin-right: 8px; font-size: 18px; } .collapse-btn { background: rgba(255, 255, 255, 0.2); border: none; color: white; width: 32px; height: 32px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; font-size: 14px; } .collapse-btn:hover { background: rgba(255, 255, 255, 0.3); transform: scale(1.1); } .assistant-content { padding: 20px; max-height: calc(90vh - 90px); overflow-y: auto; } .announcement-section { background: linear-gradient(135deg, rgba(32, 201, 151, 0.1) 0%, rgba(18, 184, 134, 0.1) 100%); border-radius: 12px; padding: 15px; margin-bottom: 20px; border-left: 4px solid var(--secondary-color); } .announcement-title { color: var(--secondary-color); font-weight: 600; margin-bottom: 8px; font-size: 14px; display: flex; align-items: center; } .announcement-title i { margin-right: 6px; } .announcement-content { color: #4a5568; font-size: 13px; line-height: 1.5; } .form-group { margin-bottom: 16px; } .form-label { font-weight: 600; margin-bottom: 8px; color: #2d3748; font-size: 14px; display: flex; align-items: center; } .form-label i { margin-right: 8px; color: var(--primary-color); } .form-control { width: 100%; padding: 10px 12px; border: 2px solid #e2e8f0; border-radius: 8px; font-size: 13px; transition: all 0.3s ease; background: white; box-sizing: border-box; } .form-control:focus { border-color: var(--primary-color); outline: none; box-shadow: 0 0 0 3px rgba(76, 110, 245, 0.1); } .form-control::placeholder { color: #a0aec0; } .account-group { border: 1px solid #e2e8f0; border-radius: 12px; padding: 15px; margin-bottom: 16px; background: rgba(255, 255, 255, 0.7); transition: all 0.3s ease; } .account-group:hover { border-color: var(--primary-color); transform: translateY(-1px); box-shadow: 0 4px 12px rgba(76, 110, 245, 0.1); } .account-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; } .account-label { font-weight: 600; color: #4a5568; font-size: 14px; } .account-status { padding: 6px 12px; border-radius: 12px; font-size: 12px; font-weight: 600; display: flex; align-items: center; } .account-status i { margin-right: 4px; font-size: 11px; } .status-default { background: #f8f9fa; color: #6c757d; border: 1px solid #dee2e6; } .status-processing { background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%); color: #856404; border: 1px solid #ffeaa7; animation: pulse 2s infinite; } .status-success { background: linear-gradient(135deg, #d1f2eb 0%, #a3e9d0 100%); color: #155724; border: 1px solid #a3e9d0; } .status-error { background: linear-gradient(135deg, #f8d7da 0%, #f1aeb5 100%); color: #721c24; border: 1px solid #f1aeb5; } .status-warning { background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%); color: #856404; border: 1px solid #ffeaa7; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.7; } } .account-inputs { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; } .btn { padding: 12px 16px; border: none; border-radius: 8px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; font-size: 14px; display: flex; align-items: center; justify-content: center; text-decoration: none; color: #2d3748; margin-bottom: 8px; text-shadow: none; min-height: 44px; } .btn i { margin-right: 8px; font-size: 14px; } .btn:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); } /* 参考提供的六按钮配色方案 */ .btn-primary { background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); box-shadow: 0 4px 15px rgba(99, 102, 241, 0.3); color: #1f2937 !important; } .btn-primary:hover { background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%); color: #1f2937 !important; } .btn-success { background: linear-gradient(135deg, #10b981 0%, #34d399 100%); box-shadow: 0 4px 15px rgba(16, 185, 129, 0.3); color: #1f2937 !important; } .btn-success:hover { background: linear-gradient(135deg, #059669 0%, #10b981 100%); color: #1f2937 !important; } .btn-warning { background: linear-gradient(135deg, #f59e0b 0%, #fbbf24 100%); box-shadow: 0 4px 15px rgba(245, 158, 11, 0.3); color: #1f2937 !important; } .btn-warning:hover { background: linear-gradient(135deg, #d97706 0%, #f59e0b 100%); color: #1f2937 !important; } .btn-danger { background: linear-gradient(135deg, #ef4444 0%, #f87171 100%); box-shadow: 0 4px 15px rgba(239, 68, 68, 0.3); color: #1f2937 !important; border: 2px solid #fecaca; } .btn-danger:hover { background: linear-gradient(135deg, #dc2626 0%, #ef4444 100%); color: #1f2937 !important; border: 2px solid #fca5a5; } .btn-info { background: linear-gradient(135deg, #3b82f6 0%, #60a5fa 100%); box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3); color: #1f2937 !important; } .btn-info:hover { background: linear-gradient(135deg, #2563eb 0%, #3b82f6 100%); color: #1f2937 !important; } .button-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 20px; } .button-grid-triple { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-bottom: 20px; } .toast { position: fixed; top: 20px; left: 50%; transform: translateX(-50%) translateY(-100px); background: var(--secondary-gradient); color: white; padding: 12px 20px; border-radius: 8px; box-shadow: 0 8px 25px rgba(32, 201, 151, 0.3); z-index: 1000000; transition: transform 0.3s ease; font-weight: 600; display: flex; align-items: center; font-size: 14px; max-width: 300px; text-align: center; } .toast.show { transform: translateX(-50%) translateY(0); } .toast.error { background: linear-gradient(135deg, #f03e3e 0%, #e03131 100%); box-shadow: 0 8px 25px rgba(240, 62, 62, 0.3); } .toast i { margin-right: 8px; font-size: 16px; } .modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); backdrop-filter: blur(10px); z-index: 1000001; display: none; opacity: 0; transition: opacity 0.3s ease; } .modal.show { display: flex; align-items: center; justify-content: center; opacity: 1; } .modal-content { background: white; width: 90%; max-width: 600px; max-height: 80vh; border-radius: 16px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); transform: scale(0.9); transition: transform 0.3s ease; overflow: hidden; } .modal.show .modal-content { transform: scale(1); } .modal-header { background: var(--primary-gradient); color: white; padding: 20px; display: flex; justify-content: space-between; align-items: center; } .modal-title { font-size: 18px; font-weight: 700; } .close-btn { background: rgba(255, 255, 255, 0.2); border: none; color: white; width: 32px; height: 32px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 16px; transition: all 0.3s ease; } .close-btn:hover { background: rgba(255, 255, 255, 0.3); transform: rotate(90deg); } .modal-body { padding: 20px; overflow-y: auto; max-height: calc(80vh - 100px); } /* 自定义滚动条 */ .assistant-content::-webkit-scrollbar, .modal-body::-webkit-scrollbar { width: 6px; } .assistant-content::-webkit-scrollbar-track, .modal-body::-webkit-scrollbar-track { background: #f1f5f9; border-radius: 3px; } .assistant-content::-webkit-scrollbar-thumb, .modal-body::-webkit-scrollbar-thumb { background: var(--primary-gradient); border-radius: 3px; } /* 响应式调整 */ @media (max-width: 480px) { #smartedu-assistant { width: calc(100vw - 40px); right: 20px; left: 20px; } #smartedu-assistant.collapsed { width: 200px; left: auto; } .button-grid-triple { grid-template-columns: 1fr 1fr; } } /* FontAwesome图标补充 */ .fa { display: inline-block; font-style: normal; font-variant: normal; text-rendering: auto; line-height: 1; } `; document.head.appendChild(style); } // 创建主界面 function createUI() { const container = document.createElement('div'); container.id = 'smartedu-assistant'; if (isCollapsed) { container.classList.add('collapsed'); } container.innerHTML = ` <div class="assistant-header"> <div class="assistant-title"> <i class="fa">🎓</i> 学习助手 </div> <button class="collapse-btn" id="collapseBtn" title="${isCollapsed ? '展开' : '收起'}"> <i class="fa">${isCollapsed ? '📖' : '📚'}</i> </button> </div> <div class="assistant-content"> <div class="announcement-section"> <div class="announcement-title"> <i class="fa">📢</i> 系统公告 </div> <div class="announcement-content" id="announcement"> 正在加载公告... </div> </div> <div class="button-grid"> <button class="btn btn-primary" id="startBtn"> <i class="fa">▶️</i> 一键开刷 </button> <button class="btn btn-danger" id="clearBtn"> <i class="fa">🗑️</i> 清空全部 </button> </div> <div class="button-grid"> <button class="btn btn-warning" id="webVersionBtn"> <i class="fa">🌐</i> 使用网页版助手 </button> <button class="btn btn-success" id="buyBtn"> <i class="fa">🛒</i> 购买授权码 </button> </div> <div class="button-grid"> <button class="btn btn-info" id="instructionsBtn"> <i class="fa">❓</i> 使用说明 </button> <button class="btn btn-info" id="contactBtn"> <i class="fa">💬</i> 联系客服 </button> </div> <div class="form-group"> <div class="form-label"> <i class="fa">🔑</i> 授权码 </div> <input type="text" class="form-control" id="authCode" placeholder="请输入授权码"> </div> <div class="account-group"> <div class="account-header"> <div class="account-label">账号信息</div> <div class="account-status status-default" id="accountStatus"> <i class="fa">⏱️</i> 待处理 </div> </div> <div class="account-inputs"> <input type="text" class="form-control" id="username" placeholder="用户名"> <input type="password" class="form-control" id="password" placeholder="密码"> </div> </div> </div> `; document.body.appendChild(container); // 绑定事件监听器 bindEventListeners(); } // 绑定事件监听器 function bindEventListeners() { // 折叠/展开功能 document.getElementById('collapseBtn').addEventListener('click', toggleCollapse); document.querySelector('.assistant-header').addEventListener('click', function(e) { if (e.target.closest('.collapse-btn')) return; toggleCollapse(); }); // 按钮事件 document.getElementById('startBtn').addEventListener('click', startProcessing); document.getElementById('clearBtn').addEventListener('click', clearAll); document.getElementById('webVersionBtn').addEventListener('click', openWebVersion); document.getElementById('buyBtn').addEventListener('click', buyAuthCode); document.getElementById('instructionsBtn').addEventListener('click', showInstructions); document.getElementById('contactBtn').addEventListener('click', contactService); } // 创建模态框 function createModal() { const modal = document.createElement('div'); modal.id = 'instructionsModal'; modal.className = 'modal'; modal.innerHTML = ` <div class="modal-content"> <div class="modal-header"> <div class="modal-title">使用说明</div> <button class="close-btn" id="closeModalBtn"> <i class="fa">✖️</i> </button> </div> <div class="modal-body" id="modalBody"> 正在加载使用说明... </div> </div> `; document.body.appendChild(modal); // 绑定关闭事件 document.getElementById('closeModalBtn').addEventListener('click', closeModal); modal.addEventListener('click', function(e) { if (e.target === modal) { closeModal(); } }); } // 显示提示信息 function showToast(message, type = 'success') { const existingToast = document.getElementById('smartedu-toast'); if (existingToast) { existingToast.remove(); } const toast = document.createElement('div'); toast.id = 'smartedu-toast'; toast.className = `toast ${type}`; toast.innerHTML = `<i class="fa">${type === 'success' ? '✅' : '❌'}</i>${message}`; document.body.appendChild(toast); setTimeout(() => { toast.classList.add('show'); }, 100); setTimeout(() => { toast.classList.remove('show'); setTimeout(() => { if (toast.parentNode) { toast.parentNode.removeChild(toast); } }, 300); }, 3000); } // API请求函数 function makeRequest(url, options = {}) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: options.method || 'GET', url: url, headers: options.headers || {}, data: options.data, onload: function(response) { try { const data = JSON.parse(response.responseText); resolve(data); } catch (e) { resolve({ status: 'error', message: '响应解析失败' }); } }, onerror: function() { reject(new Error('网络请求失败')); } }); }); } // 配置 const API_BASE = 'http://yanxiu.pro:5000'; // 获取公告 async function fetchAnnouncement() { try { const data = await makeRequest(`${API_BASE}/api/announcement`); if (data.status === 'success') { document.getElementById('announcement').textContent = data.content; announcement = data.content; } } catch (error) { console.error('获取公告失败:', error); document.getElementById('announcement').textContent = '获取公告失败,请检查网络连接。'; } } // 获取使用说明 async function fetchInstructions() { try { const data = await makeRequest(`${API_BASE}/api/instructions`); if (data.status === 'success') { instructions = data.content; } } catch (error) { console.error('获取使用说明失败:', error); instructions = '<p>获取使用说明失败,请检查网络连接。</p>'; } } // 功能函数 function toggleCollapse() { const container = document.getElementById('smartedu-assistant'); const btn = document.querySelector('.collapse-btn i'); isCollapsed = !isCollapsed; GM_setValue('isCollapsed', isCollapsed); if (isCollapsed) { container.classList.add('collapsed'); btn.textContent = '📖'; document.getElementById('collapseBtn').title = '展开'; } else { container.classList.remove('collapsed'); btn.textContent = '📚'; document.getElementById('collapseBtn').title = '收起'; } } async function startProcessing() { const authCode = document.getElementById('authCode').value.trim(); const username = document.getElementById('username').value.trim(); const password = document.getElementById('password').value.trim(); if (!authCode) { showToast('请输入授权码', 'error'); return; } if (!username || !password) { showToast('请输入完整的账号密码', 'error'); return; } // 更新状态为处理中 const statusBox = document.getElementById('accountStatus'); statusBox.className = 'account-status status-processing'; statusBox.innerHTML = '<i class="fa">⚡</i> 处理中...'; try { const formData = new URLSearchParams(); formData.append('auth_code', authCode); formData.append('username1', username); formData.append('password1', password); const data = await makeRequest(`${API_BASE}/study`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, data: formData.toString() }); if (data.status === 'success' && data.accounts && data.accounts.length > 0) { const account = data.accounts[0]; if (account.status === 'success') { statusBox.className = 'account-status status-success'; statusBox.innerHTML = '<i class="fa">✅</i> 成功'; statusBox.title = account.message; showToast('学习完成!', 'success'); } else if (account.status === 'warning') { statusBox.className = 'account-status status-warning'; statusBox.innerHTML = '<i class="fa">⚠️</i> 已学习'; statusBox.title = account.message; showToast('该账号已经学习过', 'success'); } else { statusBox.className = 'account-status status-error'; statusBox.innerHTML = '<i class="fa">❌</i> 失败'; statusBox.title = account.message; showToast(account.message || '学习失败', 'error'); } } else { statusBox.className = 'account-status status-error'; statusBox.innerHTML = '<i class="fa">❌</i> 失败'; showToast(data.message || '处理失败', 'error'); } } catch (error) { console.error('提交请求失败:', error); statusBox.className = 'account-status status-error'; statusBox.innerHTML = '<i class="fa">❌</i> 失败'; showToast('网络错误,请重试', 'error'); } } function clearAll() { document.getElementById('username').value = ''; document.getElementById('password').value = ''; const statusBox = document.getElementById('accountStatus'); statusBox.className = 'account-status status-default'; statusBox.innerHTML = '<i class="fa">⏱️</i> 待处理'; statusBox.title = ''; showToast('已清空账号信息', 'success'); } function openWebVersion() { window.open('http://yanxiu.pro/', '_blank'); showToast('已打开网页版助手', 'success'); } function buyAuthCode() { window.open('https://68n.cn/8l2jB', '_blank'); } function showInstructions() { const modal = document.getElementById('instructionsModal'); const modalBody = document.getElementById('modalBody'); modalBody.innerHTML = instructions; modal.classList.add('show'); } function closeModal() { const modal = document.getElementById('instructionsModal'); modal.classList.remove('show'); } async function contactService() { const qqNumber = '1556818085'; try { await navigator.clipboard.writeText(qqNumber); showToast('客服QQ号已复制到剪切板!', 'success'); } catch (err) { const textArea = document.createElement('textarea'); textArea.value = qqNumber; textArea.style.position = 'fixed'; textArea.style.left = '-999999px'; document.body.appendChild(textArea); textArea.select(); try { document.execCommand('copy'); showToast('客服QQ号已复制到剪切板!', 'success'); } catch (err) { showToast(`复制失败,客服QQ:${qqNumber}`, 'error'); } document.body.removeChild(textArea); } } // 保存表单数据 function saveFormData() { const formData = { authCode: document.getElementById('authCode').value, username: document.getElementById('username').value, password: document.getElementById('password').value }; GM_setValue('formData', JSON.stringify(formData)); } // 恢复表单数据 function restoreFormData() { const savedData = GM_getValue('formData', '{}'); try { const formData = JSON.parse(savedData); if (formData.authCode) { document.getElementById('authCode').value = formData.authCode; } if (formData.username) { document.getElementById('username').value = formData.username; } if (formData.password) { document.getElementById('password').value = formData.password; } } catch (e) { console.log('恢复表单数据失败:', e); } } // 初始化 function init() { createStyles(); createUI(); createModal(); fetchAnnouncement(); fetchInstructions(); setTimeout(restoreFormData, 100); setInterval(saveFormData, 5000); console.log('智慧中小学学习助手已加载'); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();