RTU/test/web_root/js/app.js

224 lines
6.6 KiB
JavaScript

/**
* app.js — 应用主控
* 路由调度、页面生命周期管理、WebSocket 数据分发
*/
var App = (function() {
var currentPage = null;
var currentHash = '';
var pages = {};
/* ---- 页面注册 ---- */
function registerPage(hash, page) {
pages[hash] = page;
}
/* ---- 侧边栏导航 ---- */
var navLinks = [
{ hash: '#dashboard', label: '🏠 功能导航' },
{ hash: '#out', label: '📡 注册 (out)' },
{ hash: '#in', label: '📊 链接注册 (in)' },
{ hash: '#yk', label: '⚡ 遥控 (yk)' },
{ hash: '#ao', label: '🔧 参数 (ao)' },
{ hash: '#param', label: '⚙ 定值 (param)' },
{ hash: '#monitor', label: '📋 数据监控' }
];
function buildNav() {
var nav = document.getElementById('nav-links');
if (!nav) return;
var html = '';
for (var i = 0; i < navLinks.length; i++) {
var link = navLinks[i];
html += '<a href="' + link.hash + '" data-hash="' + link.hash + '">' + link.label + '</a>';
}
nav.innerHTML = html;
}
function updateNavActive(hash) {
var links = document.querySelectorAll('#nav-links a');
for (var i = 0; i < links.length; i++) {
var linkHash = links[i].getAttribute('data-hash');
if (linkHash === hash) {
links[i].classList.add('active');
} else {
links[i].classList.remove('active');
}
}
}
function showSidebar(show) {
var sidebar = document.getElementById('nav-sidebar');
if (sidebar) {
sidebar.style.display = show ? 'flex' : 'none';
}
var main = document.getElementById('main-content');
if (main) {
main.style.marginLeft = show ? '220px' : '0';
}
}
/* ---- WS 状态更新 ---- */
function updateWsStatus(status) {
var dot = document.getElementById('nav-status-dot');
var text = document.getElementById('nav-status-text');
if (dot) {
dot.className = 'nav-status-dot ' + status;
}
if (text) {
var map = { connected: '已连接', disconnected: '已断开', connecting: '连接中...' };
text.textContent = map[status] || status;
}
}
/* ---- 路由调度 ---- */
function dispatch(hash) {
// 未登录 → 跳转到 login
if (hash !== '#login' && !localStorage.getItem('rtu_logged_in')) {
window.location.hash = '#login';
return;
}
// 已登录但访问 login → 跳转到 dashboard
if (hash === '#login' && localStorage.getItem('rtu_logged_in')) {
window.location.hash = '#dashboard';
return;
}
if (hash === currentHash && currentPage) return;
var container = document.getElementById('page-container');
if (!container) return;
// 离开旧页面
if (currentPage && currentPage.onLeave) {
currentPage.onLeave();
}
// 渲染新页面
var page = pages[hash];
if (!page) {
// 默认跳转到 login
window.location.hash = '#login';
return;
}
container.innerHTML = '';
page.render(container);
if (page.onEnter) {
page.onEnter();
}
// 页面进入后立即推送缓存数据(如有)
var stMap = { '#out': 'out', '#in': 'in', '#yk': 'yk', '#ao': 'ao', '#param': 'param' };
var st = stMap[hash];
if (st && page.onData && lastDataCache[st]) {
page.onData(lastDataCache[st]);
}
currentPage = page;
currentHash = hash;
// 更新导航
updateNavActive(hash);
// 登录页隐藏侧边栏
if (hash === '#login') {
showSidebar(false);
document.body.classList.add('login-page');
} else {
showSidebar(true);
document.body.classList.remove('login-page');
}
}
/* ---- 数据缓存:保留每种信号类型的最后数据,切换页面时立即恢复 ---- */
var lastDataCache = {};
/* ---- WS 下行数据分发 ---- */
function onWsMessage(data, raw) {
if (!data || typeof data !== 'object') return;
var signalTypes = ['out', 'in', 'yk', 'ao', 'param'];
for (var i = 0; i < signalTypes.length; i++) {
var st = signalTypes[i];
if (data[st]) {
lastDataCache[st] = data[st];
}
}
// 仅向当前页面推送对应类型的数据
var signalTypeMap = {
'#out': 'out',
'#in': 'in',
'#yk': 'yk',
'#ao': 'ao',
'#param': 'param'
};
var signalType = signalTypeMap[currentHash];
if (signalType && currentPage && currentPage.onData && data[signalType]) {
currentPage.onData(data[signalType]);
}
}
/* ---- 初始化 ---- */
function init() {
// 注册页面
registerPage('#login', LoginPage);
registerPage('#dashboard', DashboardPage);
registerPage('#out', OutPage);
registerPage('#in', InPage);
registerPage('#yk', YkPage);
registerPage('#ao', AoPage);
registerPage('#param', ParamPage);
registerPage('#monitor', MonitorPage);
// 构建导航
buildNav();
// 初始化 WebSocket
var wsUrl = (location.protocol === 'https:' ? 'wss:' : 'ws:') + '//' + location.host + '/ws';
WsClient.connect(wsUrl);
// 监听 WS 状态
WsClient.onStatusChange(function(status) {
updateWsStatus(status);
});
// 监听 WS 下行消息
WsClient.onMessage(function(data, raw) {
onWsMessage(data, raw);
});
// 路由变化
window.addEventListener('hashchange', function() {
var hash = window.location.hash || '#login';
dispatch(hash);
});
// 登出按钮
var logoutBtn = document.getElementById('nav-logout');
if (logoutBtn) {
logoutBtn.onclick = function() {
localStorage.removeItem('rtu_logged_in');
window.location.hash = '#login';
};
}
// 首次加载
var initHash = window.location.hash || '#login';
dispatch(initHash);
}
return {
init: init,
dispatch: dispatch
};
})();
// 页面加载完成后启动
document.addEventListener('DOMContentLoaded', function() {
App.init();
});