// ==UserScript== // @name 财小助(官网/校园网访问加强助手) // @namespace https://caixiaozhu.top:8082/ // @version 1.1.2 // @description 支持重财校园网快速切换与一网通版登录,新增官网主页专属新媒体导航弹窗。 // @author 你的名字 // @icon https://caixiaozhu.top:8082/images/logo.png // @match *://uia.cfec.edu.cn/* // @match *://10.149.255.220/* // @match *://jwmis.cfec.edu.cn/* // @match *://xsc.cfec.edu.cn:*/* // @match *://jgyth.cfec.edu.cn/* // @match *://cqrz.yuketang.cn/* // @match *://www.cfec.edu.cn/* // @match *://caixiaozhu.top:*/* // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @grant GM_xmlhttpRequest // @connect * // @run-at document-start // @license CC-BY-NC-ND-4.0 // @antifeature none // ==/UserScript== /** * ========================================================================= * 🛡️ 财小助(官网/校园网访问加强助手) - 版权与安全声明 * ========================================================================= * 1. 【隐私安全】本脚本纯本地运行!所有的学号、密码均保存在您个人的浏览器本地 * 存储中(GM_setValue),绝不会向任何第三方服务器发送您的凭证信息。 * 2. 【授权协议】CC-BY-NC-ND-4.0 (署名-非商业性使用-禁止演绎)。 * 您可以自由使用本脚本,但严禁将本代码修改后二次发布,严禁用于任何商业用途! * 3. 【免责声明】本脚本仅供重庆财经学院师生个人便捷登录使用,请勿在公共电脑 * 上保存密码。因使用本脚本导致的任何账号异常、信息泄露,作者不承担任何责任。 * 4. 【防篡改警告】若您是从非官方渠道下载的本脚本,请立即删除!任何人不得在 * 本脚本中添加窃取密码、劫持请求等恶意代码。 * ========================================================================= */ (async function () { 'use strict'; // ================= 配置区 ================= const SHORTCUTS = [ { name: '📚 教务', url: 'http://uia.cfec.edu.cn/cas/login?service=http%3A%2F%2Fjwmis.cfec.edu.cn%2Fsso%2Fzllogin' }, { name: '🎓 学工', url: 'http://xsc.cfec.edu.cn:82/sso' }, { name: '📝 请假申请', url: 'http://uia.cfec.edu.cn/cas/login?service=' + encodeURIComponent('http://xsc.cfec.edu.cn:82/sso?service=' + encodeURIComponent('http://xsc.cfec.edu.cn:82/leave/LeaveApply/list')) }, { name: '🛠️ 宿舍报修', url: 'http://uia.cfec.edu.cn/cas/login?service=' + encodeURIComponent('http://xsc.cfec.edu.cn:82/sso?service=' + encodeURIComponent('http://xsc.cfec.edu.cn:82/dormitoryRepair/stuDormitoryRepair/list')) }, { name: '☔ 雨课堂', url: 'https://cqrz.yuketang.cn/pro/portal/home/' } ]; const FRIEND_LINK = { name: '财小助官网', url: 'https://caixiaozhu.top:8082/' }; const QQ_GROUP_URL = 'https://qm.qq.com/cgi-bin/qm/qr?k=ph5b7OmdNWd2ciiBMmCA9Fh-qfrwoyMf&jump_from=webapi&authKey=eEKIrJWSWKfSir5HNPE5VQZLSkrHcl+jyslBdiF4lFjbFnu5CPk3eGMCm6YIjbVF'; const SCRIPT_HOME_URL = 'https://scriptcat.org/zh-CN/script-show-page/8596'; const UPDATE_PAGE_URL = 'https://scriptcat.org/zh-CN/script-show-page/8596'; // ========================================== const CURRENT_VERSION = '1.1.2'; const STORAGE_KEY = 'cfec_uia_config_v10'; const DEFAULT_CONFIG = { uiaProfiles: [], campusProfiles: [], uiaLastUsedId: '', campusLastUsedId: '', autoSubmit: true }; /* ---------- 存储层 ---------- */ const Store = { async get(key, def) { try { if (typeof GM !== 'undefined' && GM.getValue) { const v = await GM.getValue(key, def); return v === undefined ? def : v; } if (typeof GM_getValue === 'function') { const v = GM_getValue(key, def); return v instanceof Promise ? await v : (v === undefined ? def : v); } } catch (e) {} return def; }, async set(key, val) { try { if (typeof GM !== 'undefined' && GM.setValue) { await GM.setValue(key, val); return; } if (typeof GM_setValue === 'function') { const r = GM_setValue(key, val); if (r instanceof Promise) await r; } } catch (e) {} } }; let config = Object.assign({}, DEFAULT_CONFIG, await Store.get(STORAGE_KEY, {})); if (!config.uiaProfiles.length && !config.campusProfiles.length) { const legacy = await Store.get('cfec_uia_config_v9', null) || await Store.get('cfec_uia_config_v8', null); if (legacy) { config.uiaProfiles = legacy.uiaProfiles || legacy.profiles || []; config.campusProfiles = legacy.campusProfiles || []; config.uiaLastUsedId = legacy.uiaLastUsedId || legacy.lastUsedId || ''; config.campusLastUsedId = legacy.campusLastUsedId || ''; config.autoSubmit = legacy.autoSubmit !== false; await Store.set(STORAGE_KEY, config); } } function uid() { return 'p_' + Date.now().toString(36) + Math.random().toString(36).slice(2, 7); } async function persist() { await Store.set(STORAGE_KEY, config); } /* ---------- 环境判断 ---------- */ const isCampusNet = location.host === '10.149.255.220'; const isUia = location.host.includes('uia.cfec.edu.cn'); const isYuketang = location.host.includes('yuketang.cn'); const isWww = location.host === 'www.cfec.edu.cn'; // 官网标识 const getProfiles = () => isCampusNet ? config.campusProfiles : config.uiaProfiles; const getLastUsedId = () => isCampusNet ? config.campusLastUsedId : config.uiaLastUsedId; /* ---------- 基础工具 ---------- */ function qs(selectors) { for (const s of selectors) { try { const el = document.querySelector(s); if (el) return el; } catch (_) {} } return null; } function setNativeValue(el, value) { if (!el) return; const proto = Object.getPrototypeOf(el); const desc = Object.getOwnPropertyDescriptor(proto, 'value'); if (desc && desc.set) desc.set.call(el, value); else el.value = value; el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true })); } const UIA_USER_SELECTORS = ['#username', 'input[name="username"]', 'input[name="userName"]', 'input[name="loginName"]', 'input[name="account"]', 'input[id*="user" i]', 'input[placeholder*="账号"]', 'input[placeholder*="用户名"]', 'input[placeholder*="学号"]']; const UIA_PASS_SELECTORS = ['input[type="password"]', '#password', 'input[name="password"]']; const CAMPUS_USER_SELECTORS = ['input[placeholder*="校内学号"]', 'input[type="text"]']; const CAMPUS_PASS_SELECTORS = ['input[placeholder*="一站式门户密码"]', 'input[type="password"]']; const CAPTCHA_IMG_SELECTORS = ['img[src*="captcha" i]', 'img[src*="verify" i]', 'img[src*="validate" i]', 'img[id*="captcha" i]', 'img[class*="captcha" i]', 'img[src*="code" i]']; const CAPTCHA_INPUT_SELECTORS = ['input[name*="captcha" i]', 'input[id*="captcha" i]', 'input[name*="verify" i]', 'input[id*="verify" i]', 'input[name*="validate" i]', 'input[id*="validate" i]', 'input[placeholder*="验证码"]', 'input[placeholder*="校验码"]']; function findLoginButton() { const candidates = document.querySelectorAll('button, input[type="submit"], input[type="button"], a, div[role="button"]'); for (const el of candidates) { const text = (el.textContent || el.value || '').trim(); if (/^登\s*录$|^登\s*入$|^login$/i.test(text)) return el; } return document.querySelector('button[type="submit"], input[type="submit"]'); } function detectCaptcha() { if (isCampusNet) return { exists: false, img: null, input: null }; return { img: qs(CAPTCHA_IMG_SELECTORS), input: qs(CAPTCHA_INPUT_SELECTORS), exists: !!(qs(CAPTCHA_IMG_SELECTORS) || qs(CAPTCHA_INPUT_SELECTORS)) }; } /* ========================================================= 检查更新模块 ========================================================= */ let hasUpdate = false; function compareVersion(v1, v2) { const p1 = v1.split('.').map(Number); const p2 = v2.split('.').map(Number); const len = Math.max(p1.length, p2.length); for (let i = 0; i < len; i++) { const num1 = p1[i] || 0; const num2 = p2[i] || 0; if (num1 > num2) return 1; if (num1 < num2) return -1; } return 0; } function checkForUpdates() { if (hasUpdate) return; let checkUrl = ''; if (typeof GM_info !== 'undefined' && GM_info.script) { checkUrl = GM_info.script.updateURL || GM_info.script.downloadURL; } if (!checkUrl) return; try { GM_xmlhttpRequest({ method: "GET", url: checkUrl, headers: { "Cache-Control": "no-cache" }, onload: function(res) { if (res.status === 200) { const match = res.responseText.match(/@version\s+([\d.]+)/); if (match && match[1]) { const latestVersion = match[1]; if (compareVersion(latestVersion, CURRENT_VERSION) > 0) { hasUpdate = true; const link = widgetHost?.shadowRoot?.querySelector('#update-link'); if (link) link.style.display = 'inline'; } } } } }); } catch (e) { console.warn('[财小助] 检查更新失败', e); } } /* ========================================================= UI 模块:官网专属弹窗 (www.cfec.edu.cn) ========================================================= */ function showWwwPopup() { if (document.getElementById('cfec-www-popup')) return; const host = document.createElement('div'); host.id = 'cfec-www-popup'; host.style.cssText = 'position:fixed;inset:0;z-index:2147483647;'; const shadow = host.attachShadow({ mode: 'open' }); shadow.innerHTML = `
`; document.documentElement.appendChild(host); // 点击遮罩层关闭 shadow.getElementById('overlay').onclick = (e) => { if (e.target.id === 'overlay') { host.remove(); } }; } /* ========================================================= UI 模块:配置面板 ========================================================= */ let panelHost = null; function openConfigPanel(defaultTab = isCampusNet ? 'campus' : 'uia') { if (panelHost) { panelHost.style.display = 'flex'; return; } panelHost = document.createElement('div'); panelHost.style.cssText = 'position:fixed;inset:0;z-index:2147483647;display:flex;'; const shadow = panelHost.attachShadow({ mode: 'open' }); let currentTab = defaultTab; let viewMode = 'list'; let editingProfile = null; function render() { const activeList = currentTab === 'uia' ? config.uiaProfiles : config.campusProfiles; const lastId = currentTab === 'uia' ? config.uiaLastUsedId : config.campusLastUsedId; shadow.innerHTML = `
`; bindEvents(); } function renderList(list, lastId) { let html = ''; if (list.length === 0) html += '
暂无保存的账号
'; else html += list.map(p => `
${p.label || p.username}
${p.username}
`).join(''); if (currentTab === 'uia' && config.uiaProfiles.length > 0) html += `
`; else if (currentTab === 'campus' && config.uiaProfiles.length > 0) html += `
`; html += `
填表后自动点击登录
`; return html; } function renderEditForm() { const p = editingProfile || { label: '', username: '', password: '' }; return `
`; } function bindEvents() { const $ = s => shadow.querySelector(s); $('#btn-close').onclick = () => { panelHost.style.display = 'none'; }; $('#overlay').onclick = (e) => { if (e.target.id === 'overlay') panelHost.style.display = 'none'; }; if (viewMode === 'list') { if ($('#tab-uia')) $('#tab-uia').onclick = () => { currentTab = 'uia'; render(); }; if ($('#tab-campus')) $('#tab-campus').onclick = () => { currentTab = 'campus'; render(); }; shadow.querySelectorAll('.item').forEach(el => { el.onclick = (e) => { if (e.target.closest('[data-action]')) return; if (currentTab === 'uia') config.uiaLastUsedId = el.dataset.id; else config.campusLastUsedId = el.dataset.id; persist(); render(); showToast(`已切换默认账号`); }; }); shadow.querySelectorAll('[data-action="edit"]').forEach(el => { el.onclick = (e) => { e.stopPropagation(); editingProfile = (currentTab === 'uia' ? config.uiaProfiles : config.campusProfiles).find(x => x.id === el.dataset.id); viewMode = 'edit'; render(); }; }); shadow.querySelectorAll('[data-action="del"]').forEach(el => { el.onclick = (e) => { e.stopPropagation(); if (confirm('确定删除此账号?')) { if (currentTab === 'uia') { config.uiaProfiles = config.uiaProfiles.filter(x => x.id !== el.dataset.id); if (config.uiaLastUsedId === el.dataset.id) config.uiaLastUsedId = config.uiaProfiles[0]?.id || ''; } else { config.campusProfiles = config.campusProfiles.filter(x => x.id !== el.dataset.id); if (config.campusLastUsedId === el.dataset.id) config.campusLastUsedId = config.campusProfiles[0]?.id || ''; } persist(); render(); } }; }); $('#btn-add').onclick = () => { editingProfile = null; viewMode = 'edit'; render(); }; $('#btn-finish').onclick = () => { panelHost.style.display = 'none'; }; $('#chk-autosubmit').onchange = (e) => { config.autoSubmit = e.target.checked; persist(); }; if ($('#btn-copy-to-campus')) { $('#btn-copy-to-campus').onclick = () => { let count = 0; config.uiaProfiles.forEach(p => { if (!config.campusProfiles.find(c => c.username === p.username)) { config.campusProfiles.push({ id: uid(), label: p.label, username: p.username, password: p.password }); count++; } }); persist(); showToast(`成功复制 ${count} 个账号`); currentTab = 'campus'; render(); }; } if ($('#btn-copy-from-uia')) { $('#btn-copy-from-uia').onclick = () => { let count = 0; config.uiaProfiles.forEach(p => { if (!config.campusProfiles.find(c => c.username === p.username)) { config.campusProfiles.push({ id: uid(), label: p.label, username: p.username, password: p.password }); count++; } }); persist(); showToast(`成功拉取 ${count} 个账号`); render(); }; } } else { $('#btn-back').onclick = () => { viewMode = 'list'; render(); }; $('#btn-save').onclick = () => { const label = $('#edit-label').value.trim(), user = $('#edit-user').value.trim(), pass = $('#edit-pass').value; if (!user || !pass) { alert('账号密码不能为空'); return; } const list = currentTab === 'uia' ? config.uiaProfiles : config.campusProfiles; if (editingProfile) { editingProfile.label = label; editingProfile.username = user; editingProfile.password = pass; } else { const np = { id: uid(), label: label || user, username: user, password: pass }; list.push(np); if (currentTab === 'uia' && !config.uiaLastUsedId) config.uiaLastUsedId = np.id; if (currentTab === 'campus' && !config.campusLastUsedId) config.campusLastUsedId = np.id; } persist(); viewMode = 'list'; render(); }; } } document.documentElement.appendChild(panelHost); render(); } /* ========================================================= 自动化执行模块 ========================================================= */ let isAutoRunning = false; function showUiaInterruptCard(profile, uEl, pEl) { const host = document.createElement('div'); host.id = 'cfec-uia-interrupt'; host.style.cssText = 'position:fixed; top:15%; left:50%; transform:translateX(-50%); z-index:2147483647;'; const shadow = host.attachShadow({ mode: 'open' }); let countdown = 3, paused = false, timer = null; shadow.innerHTML = `
🔓
正在自动登录
账号: ${profile.label || profile.username}
`; document.documentElement.appendChild(host); const bar = shadow.getElementById('bar'); shadow.getElementById('card').onmouseenter = () => { paused = true; }; shadow.getElementById('card').onmouseleave = () => { paused = false; }; shadow.getElementById('btn-cancel').onclick = () => { clearInterval(timer); host.remove(); isAutoRunning = false; openConfigPanel('uia'); }; setTimeout(() => { bar.style.width = '0%'; }, 50); timer = setInterval(() => { if (paused) return; countdown--; if (countdown <= 0) { clearInterval(timer); host.remove(); executeLogin(uEl, pEl); } }, 1000); } function executeLogin(uEl, pEl) { const captcha = detectCaptcha(); if (captcha.exists && captcha.input) { captcha.input.style.outline = '3px solid #ef4444'; captcha.input.style.boxShadow = '0 0 0 4px rgba(239,68,68,.2)'; captcha.input.focus(); showToast('⚠️ 检测到验证码,请手动输入'); const submitFn = () => { const btn = findLoginButton(); if (btn) btn.click(); }; captcha.input.addEventListener('input', () => { const len = (captcha.input.value || '').trim().length; if (len >= (captcha.input.maxLength > 0 ? captcha.input.maxLength : 4)) submitFn(); }); captcha.input.addEventListener('keydown', (e) => { if (e.key === 'Enter') submitFn(); }); } else if (config.autoSubmit) { const btn = findLoginButton(); if (btn) btn.click(); else pEl.dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: 'Enter', keyCode: 13 })); } isAutoRunning = false; } function startAutoLogin() { if (isAutoRunning) return; const profiles = getProfiles(); if (profiles.length === 0) return; const uEl = qs(isCampusNet ? CAMPUS_USER_SELECTORS : UIA_USER_SELECTORS); const pEl = qs(isCampusNet ? CAMPUS_PASS_SELECTORS : UIA_PASS_SELECTORS); if (!uEl || !pEl || (uEl.value && pEl.value)) return; isAutoRunning = true; const lastId = getLastUsedId(); const profile = profiles.find(p => p.id === lastId) || profiles[0]; setNativeValue(uEl, profile.username); setNativeValue(pEl, profile.password); if (isCampusNet) { showToast(`正在登录校园网: ${profile.label || profile.username}`); setTimeout(() => executeLogin(uEl, pEl), 300); } else { showUiaInterruptCard(profile, uEl, pEl); } } /* ========================================================= 可拖拽侧边栏:财小助 ========================================================= */ let widgetHost = null; let isExpanded = isUia; function injectSidebarTab() { if (widgetHost) return; widgetHost = document.createElement('div'); widgetHost.id = 'cfec-uia-sidebar'; widgetHost.style.cssText = 'position:fixed; z-index:2147483640; right:20px; bottom:20px;'; const shadow = widgetHost.attachShadow({ mode: 'open' }); function render() { shadow.innerHTML = `
财小助(官网助手版)
v${CURRENT_VERSION} 检测到更新
`; bindEvents(); if (hasUpdate) { const link = shadow.querySelector('#update-link'); if (link) link.style.display = 'inline'; } } function bindEvents() { const $ = s => shadow.querySelector(s); $('#btn-expand').onclick = () => { isExpanded = true; render(); }; $('#btn-close').onclick = () => { isExpanded = false; render(); }; // 绑定折叠面板点击事件 shadow.querySelectorAll('.menu-title[data-target]').forEach(el => { el.onclick = () => { const targetId = el.dataset.target; const content = shadow.getElementById(targetId); const isActive = content.classList.contains('active'); shadow.querySelectorAll('.menu-title[data-target]').forEach(t => t.classList.remove('active')); shadow.querySelectorAll('.menu-content').forEach(c => c.classList.remove('active')); if (!isActive) { el.classList.add('active'); content.classList.add('active'); } }; }); shadow.querySelectorAll('.nav-link').forEach(el => { el.onmouseenter = () => { const url = el.dataset.url; if (!url) return; try { const origin = new URL(url).origin; const conn = document.createElement('link'); conn.rel = 'preconnect'; conn.href = origin; conn.crossOrigin = 'anonymous'; document.head.appendChild(conn); } catch (e) {} }; el.onclick = (e) => { e.preventDefault(); const url = el.dataset.url; if (location.host.includes('xsc.cfec.edu.cn')) { if (url.includes('leave/LeaveApply')) { window.location.href = 'http://xsc.cfec.edu.cn:82/leave/LeaveApply/list'; return; } if (url.includes('dormitoryRepair')) { window.location.href = 'http://xsc.cfec.edu.cn:82/dormitoryRepair/stuDormitoryRepair/list'; return; } } const isBlank = el.dataset.blank === 'true'; const isShortcut = SHORTCUTS.some(s => s.url === url); if (isShortcut && isUia && !checkIsLoggedIn()) { showLoginRequiredPrompt(); return; } if (isBlank) { window.open(url, '_blank'); } else { window.location.href = url; } }; }); const verBtn = shadow.querySelector('#version-btn'); if (verBtn) { verBtn.onclick = () => { window.open(SCRIPT_HOME_URL, '_blank'); }; } const updateLink = shadow.querySelector('#update-link'); if (updateLink) { updateLink.onclick = () => { window.open(UPDATE_PAGE_URL, '_blank'); }; } $('#btn-config').onclick = () => { openConfigPanel(isCampusNet ? 'campus' : 'uia'); }; } document.documentElement.appendChild(widgetHost); render(); } /* ========================================================= 状态检测与辅助功能 ========================================================= */ function checkIsLoggedIn() { if (isCampusNet) return !qs(CAMPUS_PASS_SELECTORS); const url = location.href; if (url.includes('/myAffairs')) return true; const bodyEl = document.body; if (!bodyEl) return false; const text = bodyEl.textContent || ''; if (['退出登录', '个人中心', '我的事务', '欢迎您'].some(m => text.includes(m))) return true; const hasLoginBtn = Array.from(document.querySelectorAll('a, button, span, div')).some(el => { const t = (el.innerText || '').trim(); const r = el.getBoundingClientRect(); return (t === '登录' || t === '登录/注册' || t === '用户登录') && r.width > 0 && r.height > 0 && r.top < 200 && r.left > window.innerWidth / 2; }); return !hasLoginBtn; } let alertTimer = null; function showProminentAlert() { if (isCampusNet) return; if (document.getElementById('cfec-uia-alert-box')) return; if (sessionStorage.getItem('cfec_uia_dismiss_alert') === '1') return; clearTimeout(alertTimer); alertTimer = setTimeout(() => { if (checkIsLoggedIn()) return; const host = document.createElement('div'); host.id = 'cfec-uia-alert-box'; host.style.cssText = 'position:fixed;top:15%;left:50%;transform:translateX(-50%);z-index:2147483647;'; const shadow = host.attachShadow({ mode: 'open' }); shadow.innerHTML = `
⚠️
您当前尚未登录
为了不影响您的正常使用,请先登录系统。
`; document.documentElement.appendChild(host); shadow.querySelector('#btn-login').onclick = () => { sessionStorage.removeItem('cfec_uia_dismiss_alert'); window.location.href = '/login'; }; shadow.querySelector('#btn-close').onclick = () => { host.remove(); sessionStorage.setItem('cfec_uia_dismiss_alert', '1'); }; }, 1500); } function showNoProfileAlert() { if (document.getElementById('cfec-uia-no-profile-box')) return; if (sessionStorage.getItem('cfec_uia_no_profile_dismissed') === '1') return; const host = document.createElement('div'); host.id = 'cfec-uia-no-profile-box'; host.style.cssText = 'position:fixed;top:15%;left:50%;transform:translateX(-50%);z-index:2147483647;'; const shadow = host.attachShadow({ mode: 'open' }); shadow.innerHTML = `
📢
尚未配置登录凭据
请添加账号密码,以便财小助为您提供自动登录服务。
`; document.documentElement.appendChild(host); shadow.querySelector('#btn-login').onclick = () => { host.remove(); openConfigPanel(isCampusNet ? 'campus' : 'uia'); }; shadow.querySelector('#btn-close').onclick = () => { host.remove(); sessionStorage.setItem('cfec_uia_no_profile_dismissed', '1'); }; } let pwdErrorAlertShown = false; function showPasswordErrorAlert() { if (pwdErrorAlertShown) return; pwdErrorAlertShown = true; const host = document.createElement('div'); host.id = 'cfec-uia-pwd-error-box'; host.style.cssText = 'position:fixed;top:20%;left:50%;transform:translateX(-50%);z-index:2147483647;'; const shadow = host.attachShadow({ mode: 'open' }); shadow.innerHTML = `
🚫
密码错误提示
系统检测到您的密码输入错误。
请前往 A校区1123 更改密码后再试。
`; document.documentElement.appendChild(host); shadow.querySelector('#btn-close').onclick = () => { host.remove(); }; } function showLoginRequiredPrompt() { if (document.getElementById('cfec-uia-login-required-box')) return; const host = document.createElement('div'); host.id = 'cfec-uia-login-required-box'; host.style.cssText = 'position:fixed;inset:0;z-index:2147483647;display:flex;align-items:center;justify-content:center;background:rgba(15,23,42,0.4);backdrop-filter:blur(2px);animation:fadeIn 0.2s ease;'; const shadow = host.attachShadow({ mode: 'open' }); shadow.innerHTML = `
🔒
请先登录一网通办
点击任意位置关闭
`; document.documentElement.appendChild(host); host.onclick = () => { host.remove(); }; } function checkPasswordError() { if (pwdErrorAlertShown) return; if (!isUia && !isCampusNet) return; const isLoginPage = isCampusNet || /\/login/i.test(location.pathname) || (qs(UIA_PASS_SELECTORS) !== null); if (!isLoginPage) return; const bodyText = document.body ? (document.body.innerText || '') : ''; const errorKeywords = ['密码错误', '账号或密码错误', '密码不正确', '用户名或密码错误', '密码有误']; if (errorKeywords.some(kw => bodyText.includes(kw))) { showPasswordErrorAlert(); } } function checkLoginExpired() { if (!isUia) return; const isLoginPage = /\/login/i.test(location.pathname) || (qs(UIA_PASS_SELECTORS) !== null); if (isLoginPage) return; const text = document.body ? (document.body.innerText || '') : ''; const expiredKeywords = ['请先登录', '登录已失效', '登录超时', '请登录后访问']; if (expiredKeywords.some(kw => text.includes(kw))) { const lastRedirect = sessionStorage.getItem('cfec_uia_last_redirect'); const now = Date.now(); if (!lastRedirect || now - parseInt(lastRedirect) > 5000) { sessionStorage.setItem('cfec_uia_last_redirect', now.toString()); window.location.href = '/login'; } } } function showToast(msg) { let toast = document.getElementById('cfec-uia-toast'); if (!toast) { toast = document.createElement('div'); toast.id = 'cfec-uia-toast'; toast.style.cssText = 'position:fixed;top:20px;left:50%;transform:translateX(-50%);z-index:2147483647;pointer-events:none;'; document.documentElement.appendChild(toast); } const shadow = toast.shadowRoot || toast.attachShadow({ mode: 'open' }); shadow.innerHTML = `
${msg}
`; toast.style.display = 'block'; clearTimeout(toast._timer); toast._timer = setTimeout(() => { toast.style.display = 'none'; }, 2500); } function checkPageState() { if (isWww) { showWwwPopup(); return; } injectSidebarTab(); if (isYuketang) { const loginBtn = Array.from(document.querySelectorAll('button, a, div, span')).find(el => { const t = (el.innerText || '').trim(); const r = el.getBoundingClientRect(); return (t === '登录' || t === '登录/注册') && r.width > 0 && r.height > 0 && r.top < 200; }); if (loginBtn && !document.getElementById('cfec-yuketang-cliked')) { const flag = document.createElement('div'); flag.id = 'cfec-yuketang-cliked'; flag.style.display = 'none'; document.body.appendChild(flag); loginBtn.click(); setTimeout(() => { if (flag.parentNode) flag.remove(); }, 10000); } return; } if (!isUia && !isCampusNet) return; checkPasswordError(); checkLoginExpired(); const hasAnyProfile = config.uiaProfiles.length > 0 || config.campusProfiles.length > 0; if (!hasAnyProfile) { showNoProfileAlert(); return; } const isLoginPage = isCampusNet || /\/login/i.test(location.pathname) || (qs(UIA_PASS_SELECTORS) !== null); if (isLoginPage) { const alertBox = document.getElementById('cfec-uia-alert-box'); if (alertBox) alertBox.remove(); startAutoLogin(); return; } const loggedIn = checkIsLoggedIn(); if (loggedIn) { clearTimeout(alertTimer); const alertBox = document.getElementById('cfec-uia-alert-box'); if (alertBox) alertBox.remove(); } else { showProminentAlert(); } } let checkTimeout = null; function scheduleCheck() { if (checkTimeout) clearTimeout(checkTimeout); checkTimeout = setTimeout(checkPageState, 300); } if (typeof GM_registerMenuCommand === 'function') { GM_registerMenuCommand('⚙️ 打开账号配置面板', () => openConfigPanel()); } let lastUrl = location.href; new MutationObserver(() => { if (location.href !== lastUrl) { lastUrl = location.href; scheduleCheck(); } }).observe(document, { subtree: true, childList: true }); new MutationObserver(scheduleCheck).observe(document.documentElement, { childList: true, subtree: true }); window.addEventListener('DOMContentLoaded', scheduleCheck); setTimeout(scheduleCheck, 1000); setTimeout(scheduleCheck, 3000); setTimeout(checkForUpdates, 1500); })();