// ==UserScript==
// @name 飞猫设备自动登录重启(增强配置版)
// @namespace http://tampermonkey.net/
// @version 2.2
// @description 支持自定义每日执行时间、账号密码保存,去除操作弹窗,执行完自动跳转回192.168.88.1
// @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", // 默认每天3点执行
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 ==========
// (已移除原脚本中“已触发全流程”“定时启动/停止”相关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');
config.username = "";
config.password = "";
config.scheduleTime = "03:00";
document.getElementById('feimao-username').value = "";
document.getElementById('feimao-password').value = "";
document.getElementById('feimao-schedule-time').value = "03:00";
console.log("[配置] 已清除所有保存信息");
});
// 开启/停止每日定时
document.getElementById('feimao-toggle-schedule').addEventListener('click', (e) => {
if (!config.username || !config.password) {
console.log("[定时] 请先填写并保存账号密码!");
return;
}
config.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();
// 之后每天重复执行(24小时=86400000毫秒)
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() {
// 延迟3秒跳转(可根据设备情况调整,比如5000=5秒)
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);
})();