284 lines
8.2 KiB
JavaScript
284 lines
8.2 KiB
JavaScript
/**
|
||
* 智能保镖 - 单页面应用
|
||
* 此脚本处理页面内容的无刷新加载和路由管理
|
||
*/
|
||
|
||
// 缓存已加载的页面内容
|
||
const pageCache = {};
|
||
// 当前页面
|
||
let currentPage = null;
|
||
// 页面内容预加载状态
|
||
let preloadingPages = false;
|
||
|
||
// 页面配置
|
||
const pages = {
|
||
'live-management': {
|
||
path: './live-management.html',
|
||
title: '直播管理 - 智能保镖',
|
||
isDefault: true, // 设置为默认页面
|
||
},
|
||
'smart-bodyguard': {
|
||
path: './smart-bodyguard.html',
|
||
title: '保镖设置 - 智能保镖',
|
||
},
|
||
'id-whitelist-blacklist': {
|
||
path: './id-whitelist-blacklist.html',
|
||
title: 'ID黑白名单 - 智能保镖',
|
||
},
|
||
'id-blacklist': {
|
||
path: './id-blacklist.html',
|
||
title: '拉黑记录 - 智能保镖',
|
||
},
|
||
'logging': {
|
||
path: './Logging.html',
|
||
title: '运行日志 - 智能保镖',
|
||
},
|
||
'tutorial': {
|
||
path: '#',
|
||
title: '使用教程 - 智能保镖',
|
||
},
|
||
'feedback': {
|
||
path: '#',
|
||
title: '意见反馈 - 智能保镖',
|
||
}
|
||
};
|
||
|
||
// 提取页面主要内容的函数
|
||
function extractMainContent(htmlContent, pageId) {
|
||
const parser = new DOMParser();
|
||
const doc = parser.parseFromString(htmlContent, 'text/html');
|
||
|
||
// 提取页面样式,确保样式能够正确应用
|
||
const styles = doc.querySelectorAll('style');
|
||
let styleContent = '';
|
||
styles.forEach(style => {
|
||
styleContent += style.outerHTML;
|
||
});
|
||
|
||
// 提取页面主要内容,具体选择器根据页面结构调整
|
||
let content;
|
||
|
||
// 非登录页面,直接获取主要内容
|
||
content = doc.querySelector('main');
|
||
// 如果没有找到main,尝试找其他容器
|
||
if (!content) {
|
||
content = doc.querySelector('.bg-white.rounded-xl') ||
|
||
doc.querySelector('body > .container') ||
|
||
doc.querySelector('body > div');
|
||
}
|
||
|
||
// 提取页面的脚本部分,以便执行
|
||
const scripts = doc.querySelectorAll('script:not([src])');
|
||
const scriptContents = Array.from(scripts).map(script => script.textContent).join('\n');
|
||
|
||
let contentHtml = '';
|
||
if (content) {
|
||
// 如果找到了内容元素,使用它的HTML
|
||
contentHtml = content.outerHTML;
|
||
} else {
|
||
// 如果没有找到特定内容元素,使用整个body内容
|
||
console.warn(`无法在${pageId}页面找到主要内容,使用完整body内容`);
|
||
contentHtml = doc.body.innerHTML;
|
||
}
|
||
|
||
return {
|
||
styles: styleContent,
|
||
content: contentHtml,
|
||
scripts: scriptContents
|
||
};
|
||
}
|
||
|
||
// 加载页面内容的函数
|
||
async function loadPageContent(pageId) {
|
||
if (!pages[pageId]) {
|
||
console.error(`未找到页面: ${pageId}`);
|
||
return null;
|
||
}
|
||
|
||
// 如果页面内容已缓存,直接返回
|
||
if (pageCache[pageId]) {
|
||
return pageCache[pageId];
|
||
}
|
||
|
||
try {
|
||
const page = pages[pageId];
|
||
// 跳过非实际页面的加载
|
||
if (page.path === '#') {
|
||
return {
|
||
styles: '',
|
||
content: '<div class="flex items-center justify-center h-full"><p class="text-xl text-gray-500">此功能正在开发中...</p></div>',
|
||
scripts: ''
|
||
};
|
||
}
|
||
|
||
console.log(`正在加载页面: ${page.path}`);
|
||
const response = await fetch(page.path);
|
||
if (!response.ok) {
|
||
throw new Error(`无法加载页面: ${page.path}`);
|
||
}
|
||
|
||
const html = await response.text();
|
||
const extractedContent = extractMainContent(html, pageId);
|
||
|
||
// 缓存页面内容
|
||
pageCache[pageId] = extractedContent;
|
||
console.log(`页面 ${pageId} 加载成功`);
|
||
return extractedContent;
|
||
} catch (error) {
|
||
console.error(`加载页面失败: ${error.message}`);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// 在后台预加载所有页面内容
|
||
async function preloadPages() {
|
||
if (preloadingPages) return;
|
||
preloadingPages = true;
|
||
|
||
console.log('开始预加载所有页面...');
|
||
for (const pageId in pages) {
|
||
if (!pageCache[pageId] && pages[pageId].path !== '#') {
|
||
await loadPageContent(pageId);
|
||
console.log(`预加载完成: ${pageId}`);
|
||
}
|
||
}
|
||
|
||
preloadingPages = false;
|
||
console.log('所有页面预加载完成');
|
||
}
|
||
|
||
// 显示页面的函数
|
||
async function showPage(pageId) {
|
||
console.log(`尝试显示页面: ${pageId}`);
|
||
if (currentPage === pageId) return;
|
||
|
||
// 加载页面内容
|
||
const pageData = await loadPageContent(pageId);
|
||
if (!pageData) {
|
||
console.error(`无法显示页面: ${pageId}`);
|
||
return;
|
||
}
|
||
|
||
// 更新页面标题
|
||
document.title = pages[pageId].title || '智能保镖';
|
||
|
||
// 获取页面容器
|
||
const pageContainer = document.getElementById(`${pageId}-page`);
|
||
if (!pageContainer) {
|
||
console.error(`未找到页面容器: ${pageId}-page`);
|
||
return;
|
||
}
|
||
|
||
// 隐藏所有页面
|
||
document.querySelectorAll('.page-container').forEach(container => {
|
||
container.classList.remove('active');
|
||
});
|
||
|
||
// 更新导航状态
|
||
document.querySelectorAll('.sidebar-item').forEach(item => {
|
||
item.classList.remove('active');
|
||
if (item.getAttribute('data-page') === pageId) {
|
||
item.classList.add('active');
|
||
}
|
||
});
|
||
|
||
// 创建一个包含样式和内容的完整HTML
|
||
let pageHtml = '';
|
||
if (pageData.styles) {
|
||
pageHtml += pageData.styles;
|
||
}
|
||
pageHtml += pageData.content;
|
||
|
||
// 设置页面内容
|
||
pageContainer.innerHTML = pageHtml;
|
||
|
||
// 执行页面脚本
|
||
if (pageData.scripts) {
|
||
try {
|
||
console.log(`执行 ${pageId} 页面脚本`);
|
||
const scriptElement = document.createElement('script');
|
||
scriptElement.textContent = pageData.scripts;
|
||
document.body.appendChild(scriptElement);
|
||
// 清理,防止重复添加
|
||
setTimeout(() => {
|
||
document.body.removeChild(scriptElement);
|
||
}, 500);
|
||
} catch (error) {
|
||
console.error(`执行页面脚本失败: ${error.message}`);
|
||
}
|
||
}
|
||
|
||
// 显示页面
|
||
pageContainer.classList.add('active');
|
||
currentPage = pageId;
|
||
|
||
console.log(`页面 ${pageId} 已显示`);
|
||
|
||
// 在移动设备上,导航后自动关闭侧边栏
|
||
if (window.innerWidth < 1024) {
|
||
const sidebar = document.getElementById('sidebar');
|
||
sidebar.classList.add('hidden');
|
||
}
|
||
|
||
// 当显示 live-management 页面时,获取初始账号列表
|
||
if (pageId === 'live-management' && window.pywebview && window.pywebview.api) {
|
||
window.pywebview.api.get_initial_accounts();
|
||
}
|
||
}
|
||
|
||
// 路由处理函数
|
||
function handleRoute() {
|
||
let hash = window.location.hash.substring(1);
|
||
if (!hash) {
|
||
// 默认页面处理,直接使用live-management
|
||
hash = 'live-management';
|
||
window.location.hash = `#${hash}`;
|
||
}
|
||
console.log(`路由切换到: ${hash}`);
|
||
showPage(hash);
|
||
}
|
||
|
||
// 移动端菜单按钮事件
|
||
function setupMobileMenu() {
|
||
const menuButton = document.getElementById('mobile-menu-button');
|
||
const sidebar = document.getElementById('sidebar');
|
||
|
||
if (menuButton && sidebar) {
|
||
menuButton.addEventListener('click', () => {
|
||
console.log('按钮点击事件触发');
|
||
sidebar.classList.toggle('hidden');
|
||
if (!sidebar.classList.contains('hidden')) {
|
||
sidebar.classList.add('fixed', 'inset-0');
|
||
sidebar.classList.remove('lg:block', 'lg:w-64');
|
||
} else {
|
||
sidebar.classList.remove('fixed', 'inset-0');
|
||
sidebar.classList.add('lg:block', 'lg:w-64');
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
// 初始化应用
|
||
function initApp() {
|
||
console.log('应用初始化中...');
|
||
|
||
// 设置路由事件监听
|
||
window.addEventListener('hashchange', handleRoute);
|
||
|
||
// 设置移动端菜单
|
||
setupMobileMenu();
|
||
|
||
// 首次加载路由
|
||
handleRoute();
|
||
|
||
// 预加载其他页面,提高用户体验
|
||
setTimeout(() => {
|
||
preloadPages();
|
||
}, 1000);
|
||
|
||
console.log('应用初始化完成');
|
||
}
|
||
|
||
|
||
// 初始化应用
|
||
document.addEventListener('DOMContentLoaded', initApp);
|