// ==UserScript== // @name 飞猫设备自动登录重启(增强配置版) // @namespace http://tampermonkey.net/ // @version 2.3 // @description 支持自定义每日执行时间、账号密码保存,去除操作弹窗,执行完自动跳转;定时状态本地存储 // @author You // @match http://192.168.88.1/* // @grant none // @run-at document-idle // ==/UserScript== (function() { 'use strict'; // ========== 本地存储工具(保存账号密码、定时时间、定时状态) ========== const storage = { get(key) { const value = localStorage.getItem(`feimao_${key}`); return value ? JSON.parse(value) : null; }, set(key, value) { localStorage.setItem(`feimao_${key}`, JSON.stringify(value)); }, remove(key) { localStorage.removeItem(`feimao_${key}`); } }; // ========== 配置(从本地存储加载,包含定时状态) ========== let config = { username: storage.get('username') || "", password: storage.get('password') || "", scheduleTime: storage.get('scheduleTime') || "03:00", // 从本地存储读取定时状态,无则默认关闭 isScheduled: storage.get('isScheduled') || false }; // ========== 选择器(无特殊伪类,兼容所有浏览器) ========== const selectors = { usernameInput: 'input.n-input__input-el[type="text"]', passwordInput: 'input.n-input__input-el[type="password"]', loginBtn: 'button.n-button.w-full.mt-24px', homeRestartBtnBase: 'div.text-center.cursor-pointer', restartPageBtnBase: 'button.n-button--primary-type.n-button--large-type.px-52px', confirmBtnBase: 'button.n-button--warning-type.n-button--small-type' }; let timer = null; // 定时任务对象 let isRunning = false; // 防止重复执行 // ========== 1. 去除弹窗:删除所有操作触发的alert ========== // ========== 2. 账号密码保存与配置面板 ========== function createConfigPanel() { const panel = document.createElement("div"); panel.style = ` position:fixed;left:20px;bottom:20px;width:300px;background:#fff;padding:15px;border-radius:8px;box-shadow:0 2px 15px rgba(0,0,0,0.2);z-index:9998; font-size:14px;color:#333; `; panel.innerHTML = `

脚本配置

`; document.body.appendChild(panel); // 保存配置 document.getElementById('feimao-save').addEventListener('click', () => { const username = document.getElementById('feimao-username').value.trim(); const password = document.getElementById('feimao-password').value.trim(); const scheduleTime = document.getElementById('feimao-schedule-time').value; if (!username || !password) { console.log("[配置] 账号密码不能为空!"); return; } if (!scheduleTime) { console.log("[配置] 请选择执行时间!"); return; } // 更新配置并保存到本地存储 config.username = username; config.password = password; config.scheduleTime = scheduleTime; storage.set('username', username); storage.set('password', password); storage.set('scheduleTime', scheduleTime); console.log(`[配置] 保存成功!账号:${username},每日执行时间:${scheduleTime}`); }); // 清除配置(新增:清除定时状态) document.getElementById('feimao-clear').addEventListener('click', () => { storage.remove('username'); storage.remove('password'); storage.remove('scheduleTime'); storage.remove('isScheduled'); // 清除定时状态存储 // 重置配置 config.username = ""; config.password = ""; config.scheduleTime = "03:00"; config.isScheduled = false; // 重置定时状态为关闭 // 同步更新页面输入框和按钮 document.getElementById('feimao-username').value = ""; document.getElementById('feimao-password').value = ""; document.getElementById('feimao-schedule-time').value = "03:00"; const toggleBtn = document.getElementById('feimao-toggle-schedule'); toggleBtn.textContent = "开启每日定时"; toggleBtn.style.background = "#67c23a"; // 停止定时任务 stopDailySchedule(); console.log("[配置] 已清除所有保存信息和定时状态"); }); // 开启/停止每日定时(新增:保存定时状态到本地) document.getElementById('feimao-toggle-schedule').addEventListener('click', (e) => { if (!config.username || !config.password) { console.log("[定时] 请先填写并保存账号密码!"); return; } config.isScheduled = !config.isScheduled; // 保存定时状态到本地存储 storage.set('isScheduled', config.isScheduled); // 更新按钮文字和样式 e.target.textContent = config.isScheduled ? '停止每日定时' : '开启每日定时'; e.target.style.background = config.isScheduled ? '#f56c6c' : '#67c23a'; if (config.isScheduled) { startDailySchedule(); console.log(`[定时] 已开启每日${config.scheduleTime}执行(状态已存储)`); } else { stopDailySchedule(); console.log("[定时] 已停止每日定时(状态已存储)"); } }); } // ========== 3. 自定义每日定时功能 ========== function getTimeToSchedule(hour, minute) { const now = new Date(); const scheduleTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hour, minute); if (scheduleTime < now) { scheduleTime.setDate(scheduleTime.getDate() + 1); } return scheduleTime - now; } function startDailySchedule() { stopDailySchedule(); const [hour, minute] = config.scheduleTime.split(':').map(Number); const delay = getTimeToSchedule(hour, minute); timer = setTimeout(() => { autoLoginAndRestart(); timer = setInterval(autoLoginAndRestart, 86400000); }, delay); } function stopDailySchedule() { if (timer) { clearTimeout(timer); clearInterval(timer); timer = null; } } // ========== 4. 核心功能(含跳转) ========== function fillInput(el, value) { el.value = value; el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true })); console.log(`[成功] 填写${el.placeholder}: ${value}`); } function waitForHomePage(callback) { let retryCount = 0; const check = () => { if (window.location.hash === "#/pc/home") { console.log("[成功] 进入home页面"); callback(); } else if (retryCount < 20) { retryCount++; setTimeout(check, 500); } else { console.error("[失败] 超时未进home页面"); isRunning = false; } }; check(); } function waitForRestartPage(callback) { let retryCount = 0; const check = () => { if (window.location.hash === "#/pc/system/restart") { console.log("[成功] 进入重启确认页"); callback(); } else if (retryCount < 15) { retryCount++; console.log(`[等待] 未进重启确认页,重试第${retryCount}次`); setTimeout(check, 500); } else { console.error("[失败] 超时未进重启确认页"); isRunning = false; } }; check(); } function findHomeRestartBtn(callback) { let retryCount = 0; const check = () => { const allDivs = document.querySelectorAll(selectors.homeRestartBtnBase); let targetBtn = null; for (let div of allDivs) { if (div.innerText.includes("重启")) { targetBtn = div; break; } } if (targetBtn) callback(targetBtn); else if (retryCount < 20) { retryCount++; setTimeout(check, 500); } else { console.error("[失败] 未找到home页重启按钮"); isRunning = false; } }; check(); } function findConfirmPageBtn(btnText, callback) { let retryCount = 0; const baseSelector = btnText === "重启" ? selectors.restartPageBtnBase : selectors.confirmBtnBase; const check = () => { const allBtns = document.querySelectorAll(baseSelector); let targetBtn = null; for (let btn of allBtns) { const span = btn.querySelector("span.n-button__content"); if (span && span.innerText === btnText) { targetBtn = btn; break; } } if (targetBtn) { console.log(`[成功] 找到确认页“${btnText}”按钮`); callback(targetBtn); } else if (retryCount < 15) { retryCount++; console.log(`[等待] 确认页“${btnText}”按钮未找到,重试第${retryCount}次`); setTimeout(check, 500); } else { console.error(`[失败] 超时未找到确认页“${btnText}”按钮`); isRunning = false; } }; check(); } // 跳转函数 function redirectToDevicePage() { setTimeout(() => { console.log("[跳转] 全流程完成,正在跳转到192.168.88.1..."); window.location.href = 'http://192.168.88.1'; }, 3000); } function autoLoginAndRestart() { if (isRunning || !config.username || !config.password) return; isRunning = true; console.log("[开始] 登录→重启全流程(增强配置版)"); waitForElement(selectors.usernameInput, (el) => { fillInput(el, config.username); waitForElement(selectors.passwordInput, (el) => { fillInput(el, config.password); waitForElement(selectors.loginBtn, (el) => { el.click(); console.log("[成功] 点击登录,等待跳home页"); waitForHomePage(() => { setTimeout(() => { findHomeRestartBtn((homeRestartBtn) => { homeRestartBtn.click(); console.log("[成功] 点击home页重启按钮,跳确认页"); waitForRestartPage(() => { setTimeout(() => { findConfirmPageBtn("重启", (restartPageBtn) => { restartPageBtn.click(); console.log("[成功] 点击确认页“重启”按钮"); setTimeout(() => { findConfirmPageBtn("确认", (confirmBtn) => { confirmBtn.click(); console.log("[成功] 点击确认页“确认”按钮,全流程完成!"); isRunning = false; redirectToDevicePage(); }); }, 1000); }); }, 2000); }); }); }, 3000); }); }, 15); }, 15); }, 15); } function waitForElement(selector, callback, maxRetry = 10) { let retryCount = 0; const check = () => { const el = document.querySelector(selector); if (el) callback(el); else if (retryCount < maxRetry) { retryCount++; console.log(`[等待] ${selector} 重试第${retryCount}次`); setTimeout(check, 500); } else { console.error(`[失败] 未找到${selector}`); isRunning = false; } }; check(); } // ========== 5. 手动执行按钮 ========== function createManualBtn() { const btn = document.createElement("button"); btn.textContent = "手动执行登录重启"; btn.style = `position:fixed;right:20px;bottom:20px;padding:10px 20px;background:#409eff;color:#fff;border:none;border-radius:5px;z-index:9999;font-size:14px;cursor:pointer;`; btn.onclick = () => { if (isRunning) { console.log("[手动执行] 操作中,请稍等!"); return; } if (!config.username || !config.password) { console.log("[手动执行] 请先在配置面板填写并保存账号密码!"); return; } autoLoginAndRestart(); console.log("[手动执行] 已触发全流程,查看控制台进度!"); }; document.body.appendChild(btn); } // ========== 初始化 ========== setTimeout(() => { createConfigPanel(); createManualBtn(); // 自动恢复定时任务(从存储读取状态) if (config.isScheduled && config.username && config.password) { startDailySchedule(); console.log(`[初始化] 自动恢复每日${config.scheduleTime}定时执行(状态从存储加载)`); } }, 1000); })();