/* * @Author: HenryDu8133 813367384@qq.com * @Date: 2026-06-19 17:30:23 * @LastEditors: HenryDu8133 813367384@qq.com * @LastEditTime: 2026-06-19 17:35:05 * @FilePath: \TicketMachine\web\public-status.js * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ (() => { const STATUS_CLASSES = ['is-checking', 'is-online', 'is-offline']; const ENDPOINTS = [ '/api/public/config', '/api/public/popular', '/api/assets/manifest' ]; const ASSISTANT_SCRIPT_ID = 'tm-ai-assistant-script'; const ASSISTANT_ASSET_VERSION = '2'; const roots = () => Array.from(document.querySelectorAll('[data-server-status-root]')); const setStatus = (state, text) => { roots().forEach((root) => { root.classList.remove(...STATUS_CLASSES); root.classList.add(`is-${state}`); const value = root.querySelector('[data-server-status-value]'); if (value) value.textContent = text; }); }; const probe = async () => { for (const endpoint of ENDPOINTS) { const separator = endpoint.includes('?') ? '&' : '?'; const controller = new AbortController(); const timeoutId = window.setTimeout(() => controller.abort(), 3500); try { const response = await fetch(`${endpoint}${separator}_=${Date.now()}`, { cache: 'no-store', signal: controller.signal }); if (response.ok) { window.clearTimeout(timeoutId); return true; } } catch (error) { void error; } window.clearTimeout(timeoutId); } return false; }; const refresh = async () => { if (!roots().length) return; if (navigator.onLine === false) { setStatus('offline', '网络离线'); return; } setStatus('checking', '检测中'); const online = await probe(); setStatus(online ? 'online' : 'offline', online ? '连接正常' : '连接异常'); }; let timerId = null; const isAssistantEligiblePage = (body) => { if (!body) return false; if (body.classList.contains('jr-admin-page') || body.classList.contains('jr-admin-login-page')) return false; return body.classList.contains('jr-public-page') || body.classList.contains('public-search') || body.classList.contains('jr-order-page') || body.classList.contains('jr-ticket-board-page'); }; const loadAssistant = () => { const body = document.body; if (!isAssistantEligiblePage(body)) return; if (document.getElementById(ASSISTANT_SCRIPT_ID) || window.__tmAiAssistantLoaded) return; const script = document.createElement('script'); script.id = ASSISTANT_SCRIPT_ID; script.src = `/ai-assistant.js?v=${ASSISTANT_ASSET_VERSION}`; script.defer = true; document.head.appendChild(script); }; const init = () => { loadAssistant(); if (!roots().length || timerId !== null) return; refresh(); timerId = window.setInterval(refresh, 30000); window.addEventListener('online', refresh); window.addEventListener('offline', () => setStatus('offline', '网络离线')); document.addEventListener('visibilitychange', () => { if (!document.hidden) refresh(); }); }; if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init, { once: true }); } else { init(); } })();