// ==UserScript== // @name 华为人才在线课程助手 (Huawei Talent Helper) - Visual // @namespace http://tampermonkey.net/ // @version 0.81 // @description 【可视化回归版】恢复 GUI 界面,支持倍速调节与日志下载,采用 Shadow DOM 隔离检测。 // @author Antigravity // @match *://e.huawei.com/cn/talent/* // @match *://talent.shixizhi.huawei.com/* // @grant none // @run-at document-end // ==/UserScript== (function() { 'use strict'; const CONFIG = { autoNext: true, playbackSpeed: 1.0, minDelay: 5000, maxDelay: 15000 }; // 增强型日志系统 const logger = { buffer: JSON.parse(localStorage.getItem('huawei_helper_logs') || "[]"), log: function(msg, type = "INFO") { const time = new Date().toLocaleTimeString(); const logMsg = `[${time}] [${type}] ${msg}`; this.buffer.push(logMsg); // 持久化到 localStorage (保留最近 500 条) if (this.buffer.length > 500) this.buffer.shift(); localStorage.setItem('huawei_helper_logs', JSON.stringify(this.buffer)); if (type === "SUCCESS") console.log(`%c${logMsg}`, "color: #28a745; font-weight: bold;"); else if (type === "WARN") console.warn(logMsg); else console.log(logMsg); updateUIRunStatus(logMsg); }, download: function() { if (this.buffer.length === 0) { alert("当前没有可导出的日志。"); return; } const blob = new Blob([this.buffer.join("\n")], { type: "text/plain" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = `huawei_logs_${new Date().getTime()}.txt`; a.click(); URL.revokeObjectURL(url); this.log("日志已成功导出到本地。", "SUCCESS"); }, clear: function() { this.buffer = []; localStorage.removeItem('huawei_helper_logs'); this.log("日志已清空。"); } }; // UI 相关逻辑 (采用 Shadow DOM 提高安全性) let uiRoot = null; function createUI() { if (document.getElementById('huawei-helper-host')) return; const host = document.createElement('div'); host.id = 'huawei-helper-host'; host.style = "position: fixed; top: 50px; right: 20px; z-index: 2147483647;"; document.body.appendChild(host); uiRoot = host.attachShadow({ mode: 'closed' }); // 使用 closed 模式进一步隐藏 const panel = document.createElement('div'); panel.style = ` background: #fff; border: 2px solid #ee0000; padding: 12px; border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,0.2); font-family: system-ui, -apple-system, sans-serif; font-size: 13px; width: 200px; color: #333; `; panel.innerHTML = `