fix: 修复前端导航和页面跳转问题
- 添加统一的导航菜单到所有页面 - 修复页面路由映射和高亮状态 - 创建 navigation.js 统一管理页面跳转 - 添加 test_navigation.py 路由测试工具 - 支持仪表板、预警管理、智能对话、HTTP对话页面间无缝切换 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
142
src/web/static/js/navigation.js
Normal file
142
src/web/static/js/navigation.js
Normal file
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* 通用导航管理脚本
|
||||
* 用于处理页面间导航和活动状态
|
||||
*/
|
||||
|
||||
class NavigationManager {
|
||||
constructor() {
|
||||
this.currentPage = this.getCurrentPage();
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
// 设置当前页面的活动状态
|
||||
this.setActiveNavigation();
|
||||
|
||||
// 添加导航点击事件监听
|
||||
this.addNavigationListeners();
|
||||
|
||||
// 添加页面加载完成后的处理
|
||||
this.addPageLoadHandlers();
|
||||
}
|
||||
|
||||
getCurrentPage() {
|
||||
const path = window.location.pathname;
|
||||
if (path === '/' || path === '/dashboard') return 'dashboard';
|
||||
if (path === '/alerts') return 'alerts';
|
||||
if (path === '/chat') return 'chat';
|
||||
if (path === '/chat-http') return 'chat-http';
|
||||
return 'dashboard';
|
||||
}
|
||||
|
||||
setActiveNavigation() {
|
||||
// 清除所有活动状态
|
||||
document.querySelectorAll('.nav-link').forEach(link => {
|
||||
link.classList.remove('active');
|
||||
});
|
||||
|
||||
// 设置当前页面的活动状态
|
||||
const activeSelectors = {
|
||||
'dashboard': 'a.nav-link[href="/dashboard"]',
|
||||
'alerts': 'a.nav-link[href="/alerts"]',
|
||||
'chat': 'a.nav-link[href="/chat"]',
|
||||
'chat-http': 'a.nav-link[href="/chat-http"]'
|
||||
};
|
||||
|
||||
const selector = activeSelectors[this.currentPage];
|
||||
if (selector) {
|
||||
document.querySelectorAll(selector).forEach(link => {
|
||||
link.classList.add('active');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
addNavigationListeners() {
|
||||
// 对导航链接添加点击处理
|
||||
document.querySelectorAll('a.nav-link[href^="/"]').forEach(link => {
|
||||
link.addEventListener('click', (e) => {
|
||||
const href = link.getAttribute('href');
|
||||
|
||||
// 如果是当前页面,阻止默认行为
|
||||
if (href === window.location.pathname) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示加载状态
|
||||
this.showLoadingState();
|
||||
|
||||
// 正常跳转
|
||||
// 注意:这里不阻止默认行为,让浏览器正常跳转
|
||||
});
|
||||
});
|
||||
|
||||
// 对 dashboard.html 的侧边栏导航特殊处理
|
||||
document.querySelectorAll('.sidebar a.nav-link[href^="/"]').forEach(link => {
|
||||
link.addEventListener('click', (e) => {
|
||||
this.showLoadingState();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
showLoadingState() {
|
||||
// 显示加载提示
|
||||
const loadingHtml = `
|
||||
<div id="navigation-loading" class="position-fixed top-0 start-0 w-100 h-100 d-flex justify-content-center align-items-center"
|
||||
style="background: rgba(255,255,255,0.9); z-index: 9999;">
|
||||
<div class="text-center">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">加载中...</span>
|
||||
</div>
|
||||
<p class="mt-2 mb-0">页面跳转中...</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.insertAdjacentHTML('beforeend', loadingHtml);
|
||||
}
|
||||
|
||||
addPageLoadHandlers() {
|
||||
// 页面加载完成后移除加载状态
|
||||
window.addEventListener('load', () => {
|
||||
const loading = document.getElementById('navigation-loading');
|
||||
if (loading) {
|
||||
loading.remove();
|
||||
}
|
||||
});
|
||||
|
||||
// 处理浏览器前进后退
|
||||
window.addEventListener('popstate', () => {
|
||||
this.currentPage = this.getCurrentPage();
|
||||
this.setActiveNavigation();
|
||||
});
|
||||
}
|
||||
|
||||
// 手动导航到指定页面
|
||||
navigateTo(page) {
|
||||
const urls = {
|
||||
'dashboard': '/dashboard',
|
||||
'alerts': '/alerts',
|
||||
'chat': '/chat',
|
||||
'chat-http': '/chat-http'
|
||||
};
|
||||
|
||||
const url = urls[page];
|
||||
if (url && url !== window.location.pathname) {
|
||||
this.showLoadingState();
|
||||
window.location.href = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载完成后初始化导航管理器
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
window.navigationManager = new NavigationManager();
|
||||
});
|
||||
|
||||
// 导航函数,可以在控制台或页面中使用
|
||||
window.navigateTo = (page) => {
|
||||
if (window.navigationManager) {
|
||||
window.navigationManager.navigateTo(page);
|
||||
}
|
||||
};
|
||||
@@ -179,6 +179,50 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 导航栏 -->
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/dashboard">
|
||||
<i class="fas fa-shield-alt me-2"></i>
|
||||
TSP助手预警管理
|
||||
</a>
|
||||
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav me-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/dashboard">
|
||||
<i class="fas fa-tachometer-alt me-1"></i>仪表板
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/alerts">
|
||||
<i class="fas fa-bell me-1"></i>预警管理
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/chat">
|
||||
<i class="fas fa-comments me-1"></i>智能对话
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/chat-http">
|
||||
<i class="fas fa-comment-dots me-1"></i>对话(HTTP)
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="navbar-nav ms-auto">
|
||||
<span class="navbar-text">
|
||||
<i class="fas fa-circle text-success"></i> WebSocket连接
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<!-- 侧边栏 -->
|
||||
@@ -327,6 +371,7 @@
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="{{ url_for('static', filename='js/navigation.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/chat.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -179,6 +179,50 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 导航栏 -->
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/dashboard">
|
||||
<i class="fas fa-shield-alt me-2"></i>
|
||||
TSP助手预警管理
|
||||
</a>
|
||||
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav me-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/dashboard">
|
||||
<i class="fas fa-tachometer-alt me-1"></i>仪表板
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/alerts">
|
||||
<i class="fas fa-bell me-1"></i>预警管理
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/chat">
|
||||
<i class="fas fa-comments me-1"></i>智能对话
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/chat-http">
|
||||
<i class="fas fa-comment-dots me-1"></i>对话(HTTP)
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="navbar-nav ms-auto">
|
||||
<span class="navbar-text">
|
||||
<i class="fas fa-circle text-info"></i> HTTP轮询
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<!-- 侧边栏 -->
|
||||
@@ -327,6 +371,7 @@
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="{{ url_for('static', filename='js/navigation.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/chat_http.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -387,11 +387,11 @@
|
||||
控制面板
|
||||
</h5>
|
||||
<nav class="nav flex-column">
|
||||
<a class="nav-link active" href="#dashboard" data-tab="dashboard" data-i18n="sidebar-dashboard">
|
||||
<a class="nav-link active" href="/dashboard" data-i18n="sidebar-dashboard">
|
||||
<i class="fas fa-home"></i>
|
||||
仪表板
|
||||
</a>
|
||||
<a class="nav-link" href="#chat" data-tab="chat" data-i18n="sidebar-conversations">
|
||||
<a class="nav-link" href="/chat" data-i18n="sidebar-conversations">
|
||||
<i class="fas fa-comments"></i>
|
||||
智能对话
|
||||
</a>
|
||||
@@ -399,7 +399,7 @@
|
||||
<i class="fas fa-brain"></i>
|
||||
Agent管理
|
||||
</a>
|
||||
<a class="nav-link" href="#alerts" data-tab="alerts" data-i18n="sidebar-alerts">
|
||||
<a class="nav-link" href="/alerts" data-i18n="sidebar-alerts">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
预警管理
|
||||
</a>
|
||||
@@ -415,9 +415,9 @@
|
||||
<i class="fas fa-sync"></i>
|
||||
飞书同步
|
||||
</a>
|
||||
<a class="nav-link" href="#conversation-history" data-tab="conversation-history" data-i18n="sidebar-conversation-history">
|
||||
<i class="fas fa-history"></i>
|
||||
对话历史
|
||||
<a class="nav-link" href="/chat-http" data-i18n="sidebar-conversation-history">
|
||||
<i class="fas fa-comment-dots"></i>
|
||||
HTTP对话
|
||||
</a>
|
||||
<a class="nav-link" href="#token-monitor" data-tab="token-monitor" data-i18n="sidebar-token-monitor">
|
||||
<i class="fas fa-coins"></i>
|
||||
@@ -2472,6 +2472,7 @@
|
||||
<!-- 脚本 -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
|
||||
<script src="{{ url_for('static', filename='js/navigation.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/dashboard.js') }}?v=1.0.9"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -12,14 +12,43 @@
|
||||
<!-- 导航栏 -->
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#">
|
||||
<a class="navbar-brand" href="/dashboard">
|
||||
<i class="fas fa-shield-alt me-2"></i>
|
||||
TSP助手预警管理
|
||||
</a>
|
||||
<div class="navbar-nav ms-auto">
|
||||
<span class="navbar-text" id="monitor-status">
|
||||
<i class="fas fa-circle text-warning"></i> 监控状态检查中...
|
||||
</span>
|
||||
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav me-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/dashboard">
|
||||
<i class="fas fa-tachometer-alt me-1"></i>仪表板
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/alerts">
|
||||
<i class="fas fa-bell me-1"></i>预警管理
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/chat">
|
||||
<i class="fas fa-comments me-1"></i>智能对话
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/chat-http">
|
||||
<i class="fas fa-comment-dots me-1"></i>对话(HTTP)
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="navbar-nav ms-auto">
|
||||
<span class="navbar-text" id="monitor-status">
|
||||
<i class="fas fa-circle text-warning"></i> 监控状态检查中...
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -650,6 +679,7 @@
|
||||
<!-- 脚本 -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script src="{{ url_for('static', filename='js/navigation.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user