/** * @file router.js * @brief Hash-based SPA 路由器 — 页面注册 + 导航 + 调度 */ var Router = { pages: {}, currentHash: '', /** * @brief 注册页面渲染函数 * @param {string} hash '#dashboard' 等 * @param {function} render 渲染回调 (container) */ register: function(hash, render) { this.pages[hash] = { render: render }; }, /** * @brief 调度到指定 hash */ dispatch: function(hash) { if (!hash) { hash = window.location.hash || '#dashboard'; } /* 登录守卫 */ if (hash !== '#login' && !localStorage.getItem('rtu_logged_in')) { window.location.hash = '#login'; return; } if (hash === '#login' && localStorage.getItem('rtu_logged_in')) { window.location.hash = '#dashboard'; return; } if (hash === this.currentHash) return; this.currentHash = hash; updateNavActive(hash); this._render(hash); }, /** * @brief 强制重绘当前页面 (用于 WS 推送刷新, hash 不变) */ reload: function() { if (this.currentHash) this._render(this.currentHash); }, _render: function(hash) { var page = this.pages[hash]; if (!page) { window.location.hash = '#dashboard'; return; } var titleMap = { '#dashboard': I18n.t('dash.title'), '#out': I18n.t('nav.out'), '#yk': I18n.t('nav.yk'), '#ao': I18n.t('nav.ao'), '#param': I18n.t('nav.param'), '#datacenter': I18n.t('nav.datacenter'), '#plc_debug': I18n.t('nav.plc_debug'), '#plc_config': I18n.t('nav.plc_config'), '#monitor': I18n.t('nav.monitor'), '#terminal': I18n.t('nav.terminal'), '#login': I18n.t('login.title') }; document.getElementById('page-title').textContent = titleMap[hash] || ''; document.getElementById('page-subtitle').textContent = ''; var container = document.getElementById('page-container'); container.innerHTML = ''; page.render(container); } }; /* ---- 侧栏导航 ---- */ var NAV = [ { h: '#dashboard', key: 'nav.dashboard', icon: 'dashboard' }, { h: '#out', key: 'nav.out', icon: 'signal', section: 'signal_mgmt' }, { h: '#yk', key: 'nav.yk', icon: 'zap' }, { h: '#ao', key: 'nav.ao', icon: 'sliders' }, { h: '#param', key: 'nav.param', icon: 'settings' }, { h: '#datacenter', key: 'nav.datacenter', icon: 'database', section: 'tools' }, { h: '#plc_debug', key: 'nav.plc_debug', icon: 'bug' }, { h: '#plc_config', key: 'nav.plc_config', icon: 'cpu' }, { h: '#monitor', key: 'nav.monitor', icon: 'activity' }, { h: '#terminal', key: 'nav.terminal', icon: 'terminal' }, ]; function buildNav() { var html = ''; var lastSection = null; NAV.forEach(function(item) { if (item.section && item.section !== lastSection) { var secKey = 'nav.section.' + item.section; html += ''; lastSection = item.section; } html += '' + Icon.get(item.icon, 'nav-icon') + I18n.t(item.key) + ''; }); document.getElementById('nav-links').innerHTML = html; } function updateNavActive(hash) { document.querySelectorAll('#nav-links a').forEach(function(a) { a.classList.toggle('active', a.dataset.hash === hash); }); } function toggleNav() { document.getElementById('nav-sidebar').classList.toggle('open'); }