XNSim/XNSimHtml/main.html

630 lines
24 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>XNSim - 主页面</title>
<link rel="icon" type="image/png" href="assets/icons/XNSim.png">
<link rel="shortcut icon" type="image/png" href="assets/icons/XNSim.png">
<link rel="stylesheet" href="style.css">
<script src="components/auth-component.js"></script>
<script src="components/main-toolbar.js"></script>
<script src="components/sub-toolbar.js"></script>
<script src="components/user-info.js"></script>
<script src="components/tabs-container.js"></script>
<script src="components/content-area.js"></script>
<script src="components/overview-page.js"></script>
<script src="components/update-history.js"></script>
<script src="components/run-log.js"></script>
<script src="components/system-info.js"></script>
<script src="components/help-component.js"></script>
<script src="components/system-log.js"></script>
<script src="components/run-env-config.js" type="module"></script>
<script src="components/model-config.js" type="module"></script>
<script src="components/service-config.js" type="module"></script>
<script src="components/interface-config.js" type="module"></script>
<script src="components/run-test.js"></script>
<script src="components/run-simulation.js"></script>
<script src="components/simulation-monitor.js"></script>
<script src="components/model-monitor.js"></script>
<script src="components/data-monitor.js"></script>
<script src="components/data-collection.js"></script>
<script src="components/profile-center.js"></script>
<script src="components/user-management.js"></script>
<script src="components/model-development.js"></script>
<script src="components/service-development.js"></script>
<script src="components/header-tools.js"></script>
<script src="components/qa-component.js"></script>
<script src="components/todo-component.js" type="module"></script>
<style>
.icon {
width: 24px;
height: 24px;
display: inline-block;
vertical-align: middle;
margin-bottom: 5px;
}
.icon-small {
width: 16px;
height: 16px;
}
/* 用户等级图标样式 */
.user-level-icon {
width: 20px;
height: 20px;
margin-right: 8px;
vertical-align: middle;
}
/* 主要内容区域样式 */
.main-content {
flex: 1;
display: flex;
flex-direction: column;
background-color: #fff;
height: 100vh;
padding: 0;
margin: 0;
overflow: hidden;
}
/* 内容包装器样式 */
.content-wrapper {
display: flex;
height: 100vh;
background: #fff;
}
/* 主工具栏样式 */
.main-toolbar {
width: 80px;
background: linear-gradient(180deg, #667eea 0%, #764ba2 100%);
display: flex;
flex-direction: column;
transition: width 0.3s ease;
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
}
/* 子工具栏样式 */
.sub-toolbar {
width: 200px;
background: linear-gradient(180deg, #7986E7 0%, #8B6DB3 100%);
position: relative;
transition: width 0.3s ease;
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
}
.sub-toolbar.collapsed {
width: 0;
}
.sub-toolbar-content {
width: 200px;
height: 100%;
overflow-y: auto;
overflow-x: hidden;
padding: 10px 0;
}
.sub-toolbar.collapsed .sub-toolbar-content {
display: none;
}
/* 主容器样式 */
.main-container {
width: 100%;
height: 100vh;
overflow: hidden;
}
/* 内容头部样式 */
.content-header {
display: flex;
justify-content: space-between;
align-items: center;
height: 54px;
background: white;
border-bottom: 1px solid #e0e0e0;
padding: 0 16px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
flex-shrink: 0;
}
.breadcrumb {
display: flex;
align-items: center;
color: #000000;
font-size: 20px;
font-weight: 1000;
height: 100%;
gap: 8px;
}
.breadcrumb .icon-small {
margin-right: 0;
margin-left: 0;
width: 20px;
height: 20px;
}
/* 添加新的样式 */
.header-right {
display: flex;
align-items: center;
gap: 16px;
}
/* 重置body样式 */
body {
margin: 0;
padding: 0;
overflow: hidden;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 15px;
}
/* 确保内容区域完全填充 */
.main-content > * {
width: 100%;
}
/* 内容区域容器 */
.content-area-container {
display: flex;
flex-direction: column;
flex: 1;
overflow: hidden;
}
tabs-container {
flex-shrink: 0;
}
content-area {
flex: 1;
overflow: hidden;
}
/* Toast 提示样式 */
.toast {
position: fixed;
top: 20px;
right: 20px;
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 12px 24px;
border-radius: 8px;
font-size: 14px;
z-index: 10000;
opacity: 0;
transition: opacity 0.3s ease;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.toast.show {
opacity: 1;
}
#authContainer, #mainContainer {
display: none;
}
#authContainer.visible, #mainContainer.visible {
display: block;
}
</style>
</head>
<body>
<div id="authContainer">
<auth-component></auth-component>
</div>
<div id="mainContainer" class="main-container">
<div class="content-wrapper">
<main-toolbar></main-toolbar>
<sub-toolbar></sub-toolbar>
<main class="main-content">
<div class="content-header">
<div class="breadcrumb">
<img src="assets/icons/png/con_b.png" alt="主页 / 概览" class="icon-small">
<span id="currentPath">主页 / 概览</span>
</div>
<div class="header-right">
<header-tools></header-tools>
<user-info></user-info>
</div>
</div>
<div class="content-area-container">
<tabs-container></tabs-container>
<content-area></content-area>
</div>
</main>
</div>
</div>
<script>
// Toast 提示函数
function showToast(message) {
const toast = document.createElement('div');
toast.className = 'toast';
toast.textContent = message;
document.body.appendChild(toast);
setTimeout(() => toast.classList.add('show'), 10);
setTimeout(() => {
toast.classList.remove('show');
setTimeout(() => toast.remove(), 300);
}, 2000);
}
document.addEventListener('DOMContentLoaded', () => {
const authComponent = document.querySelector('auth-component');
const authContainer = document.getElementById('authContainer');
const mainContainer = document.getElementById('mainContainer');
const tabsContainer = document.querySelector('tabs-container');
const contentArea = document.querySelector('content-area');
// 检查是否已登录
const checkAuth = () => {
const userInfo = localStorage.getItem('userInfo');
if (userInfo) {
authContainer.classList.remove('visible');
mainContainer.classList.add('visible');
// 初始化主页面
initializeMainPage();
} else {
authContainer.classList.add('visible');
mainContainer.classList.remove('visible');
}
};
// 初始化主页面
function initializeMainPage() {
// 初始化时创建概览标签页并加载概览内容
tabsContainer.createTab('overview', '概览', 'dashboard', '主页', 'home');
contentArea.loadContent('overview');
// 监听主工具栏选择事件
document.querySelector('main-toolbar').addEventListener('tool-selected', function(e) {
const { tool, text } = e.detail;
document.querySelector('sub-toolbar').setAttribute('current-tool', tool);
// 当选择主页时,显示概览
if (tool === 'home') {
tabsContainer.createTab('overview', '概览', 'dashboard', '主页', 'home');
}
});
// 监听子工具栏选择事件
document.querySelector('sub-toolbar').addEventListener('sub-item-selected', function(e) {
const { parent, text, icon } = e.detail;
const parentText = document.querySelector(`main-toolbar`).shadowRoot.querySelector(`[data-tool="${parent}"] span`).textContent;
updateBreadcrumb(parentText, text);
updateContent(text, icon, parentText, parent);
});
// 监听用户菜单动作
document.querySelector('user-info').addEventListener('menu-action', function(e) {
const { action } = e.detail;
handleMenuAction(action);
});
// 监听标签页激活事件
tabsContainer.addEventListener('tab-activated', function(e) {
const { id, parentText, title, parentTool, isTabSwitch } = e.detail;
// 更新面包屑导航
updateBreadcrumb(parentText, title);
// 只有在真正的标签切换时才加载内容
if (isTabSwitch) {
contentArea.loadContent(id);
}
// 同步更新面包屑导航
const breadcrumbIcon = document.querySelector('.breadcrumb .icon-small');
if (breadcrumbIcon) {
const iconName = getIconNameForTitle(title, parentTool);
breadcrumbIcon.src = `assets/icons/png/${iconName}_b.png`;
breadcrumbIcon.alt = `${parentText} / ${title}`;
}
});
// 监听标签页关闭事件
tabsContainer.addEventListener('tab-closed', function(e) {
const { id } = e.detail;
// 清除关闭标签页的内容缓存
contentArea.clearCache(id);
});
}
function handleMenuAction(action) {
const contentArea = document.querySelector('content-area');
const tabsContainer = document.querySelector('tabs-container');
switch(action) {
case 'profile':
tabsContainer.createTab('profile', '个人中心', 'user', '系统', 'system');
contentArea.loadContent('profile');
break;
case 'users':
tabsContainer.createTab('users', '用户管理', 'users', '系统', 'system');
contentArea.loadContent('users');
break;
case 'logout':
// 清除所有用户相关数据
localStorage.removeItem('userInfo');
localStorage.removeItem('authToken');
// 清除所有标签页
tabsContainer.clearAllTabs();
// 显示退出成功提示
showToast('已安全退出登录');
// 重新检查认证状态,这会触发返回登录页面
checkAuth();
break;
}
}
function updateBreadcrumb(mainMenu, subMenu) {
const currentPath = document.getElementById('currentPath');
currentPath.textContent = subMenu ? `${mainMenu} / ${subMenu}` : mainMenu;
}
function updateContent(title, icon, parentText, parentTool) {
const tabsContainer = document.querySelector('tabs-container');
const contentArea = document.querySelector('content-area');
if (title === '概览') {
// 直接激活第一个标签页(概览标签页)
const firstTab = tabsContainer.shadowRoot.querySelector('.tab');
if (firstTab) {
tabsContainer.activateTab(firstTab.getAttribute('data-tab'));
}
return;
}
// 特殊处理更新记录标签页
if (title === '更新记录') {
const id = 'update-history';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理运行日志标签页
if (title === '运行日志') {
const id = 'run-log';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理资源监控标签页
if (title === '资源监控') {
const id = 'system-info';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
contentArea.loadContent(id);
return;
}
// 处理系统日志标签页
if (title === '系统日志') {
const id = 'system-log';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
contentArea.loadContent(id);
return;
}
// 处理待办事项标签页
if (title === '待办事项') {
const id = 'todo';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
contentArea.loadContent(id);
return;
}
// 处理帮助标签页
if (title === '帮助') {
const id = 'help';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
contentArea.loadContent(id);
return;
}
// 处理Q&A标签页
if (title === 'Q&A') {
const id = 'qa';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
contentArea.loadContent(id);
return;
}
// 处理运行环境配置标签页
if (title === '运行环境配置') {
const id = 'run-env-config';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理模型配置标签页
if (title === '模型配置') {
const id = 'model-config';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理服务配置标签页
if (title === '服务配置') {
const id = 'service-config';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理接口配置标签页
if (title === '接口配置') {
const id = 'interface-config';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理模型开发标签页
if (title === '模型开发') {
const id = 'model-development';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理服务开发标签页
if (title === '服务开发') {
const id = 'service-development';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理运行测试标签页
if (title === '运行测试') {
const id = 'run-test';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理运行仿真标签页
if (title === '运行仿真') {
const id = 'run-simulation';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理仿真监控标签页
if (title === '仿真监控') {
const id = 'simulation-monitor';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理模型监控标签页
if (title === '模型监控') {
const id = 'model-monitor';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理数据监控标签页
if (title === '数据监控') {
const id = 'data-monitor';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理数据采集标签页
if (title === '数据采集') {
const id = 'data-collection';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理个人中心标签页
if (title === '个人中心') {
const id = 'profile';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 处理用户管理标签页
if (title === '用户管理') {
const id = 'users';
tabsContainer.createTab(id, title, icon, parentText, parentTool);
return;
}
// 默认情况下使用标题转换为ID
const id = title.toLowerCase().replace(/\s+/g, '-');
tabsContainer.createTab(id, title, icon, parentText, parentTool);
}
// 根据标题和父工具获取图标名称的辅助函数
function getIconNameForTitle(title, parentTool) {
const iconMap = {
'概览': 'dashboard',
'更新记录': 'clock',
'运行日志': 'file',
'资源监控': 'server',
'帮助': 'help',
'Q&A': 'question',
'运行环境配置': 'chip',
'模型配置': 'cube',
'服务配置': 'settings',
'接口配置': 'plug',
'运行测试': 'flask',
'运行仿真': 'rocket',
'仿真监控': 'desktop',
'模型监控': 'cubes',
'数据监控': 'chart-bar',
'数据采集': 'database',
'个人中心': 'user',
'用户管理': 'users',
'模型开发': 'cube',
'服务开发': 'settings'
};
return iconMap[title] || parentTool || 'con';
}
// 监听登录事件
authComponent.addEventListener('login', async (e) => {
const data = e.detail;
try {
const response = await fetch('/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
const result = await response.json();
if (result.success) {
localStorage.setItem('userInfo', JSON.stringify(result.user));
showToast(`欢迎回来,${result.user.username}`);
authContainer.classList.remove('visible');
mainContainer.classList.add('visible');
// 初始化主页面
initializeMainPage();
} else {
showToast(result.message || '登录失败,请检查用户名和密码');
}
} catch (error) {
console.error('登录错误:', error);
showToast('登录过程中发生错误');
}
});
// 监听注册事件
authComponent.addEventListener('register', async (e) => {
const data = e.detail;
try {
const response = await fetch('/api/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
const result = await response.json();
if (result.success) {
showToast('注册成功!请登录');
// 切换到登录表单
const loginToggle = authComponent.shadowRoot.getElementById('loginToggle');
loginToggle.click();
} else {
showToast(result.message || '注册失败,请稍后重试');
}
} catch (error) {
console.error('注册错误:', error);
showToast('注册过程中发生错误');
}
});
// 初始检查认证状态
checkAuth();
});
</script>
</body>
</html>