2025-07-31 13:26:17 +08:00

289 lines
8.4 KiB
HTML

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>首页</title>
<!-- Bootstrap 5 CSS -->
<link href="../static/plugin/bootstrap-5.3.7-dist/css/bootstrap.min.css"
th:href="@{/plugin/bootstrap-5.3.7-dist/css/bootstrap.min.css}"
rel="stylesheet">
<!-- jQuery -->
<script src="../static/plugin/jquery-3.7.1/jquery-3.7.1.min.js"
th:src="@{/plugin/jquery-3.7.1/jquery-3.7.1.min.js}"></script>
<style>
.sidebar {
width: 200px;
height: calc(100vh - 56px);
position: fixed;
top: 56px;
left: 0;
overflow-y: auto;
background-color: #f8f9fa;
border-right: 1px solid #dee2e6;
}
.content {
margin-left: 200px;
margin-top: 56px;
padding: 20px;
height: calc(100vh - 56px);
overflow-y: auto;
}
.nav-link.active {
background-color: #0d6efd;
color: white !important;
}
.loading {
text-align: center;
padding: 20px;
}
/* 二级菜单样式 */
.submenu {
padding-left: 1rem;
display: none;
}
.submenu .list-group-item {
border-left: 3px solid #0d6efd;
}
.menu-has-children::after {
content: "▶";
float: right;
transition: transform 0.2s;
}
.menu-has-children.active::after {
transform: rotate(90deg);
}
.menu-has-children.active + .submenu {
display: block;
}
/* 菜单项间距调整 */
.menu-item {
cursor: pointer;
}
</style>
</head>
<body>
<!-- 顶部导航栏 -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary fixed-top">
<div class="container-fluid">
<a class="navbar-brand" href="#">权限管理系统</a>
<div class="d-flex">
<span class="navbar-text text-white me-3" id="currentUser"></span>
<button class="btn btn-outline-light btn-sm" id="logoutBtn">退出</button>
</div>
</div>
</nav>
<!-- 主体内容 -->
<div class="d-flex">
<!-- 左侧菜单 -->
<div class="sidebar bg-light">
<div class="list-group list-group-flush mt-3" id="menuContainer">
<!-- 菜单将通过AJAX动态加载 -->
<div class="loading">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">菜单加载中...</span>
</div>
</div>
</div>
</div>
<!-- 右侧内容区域 -->
<div class="content flex-grow-1">
<div id="content-container">
<!-- 默认加载欢迎页内容 -->
<div class="loading">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">加载中...</span>
</div>
</div>
</div>
</div>
</div>
<!-- Bootstrap 5 JS -->
<script src="../static/plugin/bootstrap-5.3.7-dist/js/bootstrap.bundle.min.js"
th:src="@{/plugin/bootstrap-5.3.7-dist/js/bootstrap.bundle.min.js}"></script>
<script>
$(document).ready(function () {
// 页面加载完成后默认加载欢迎页
loadContent('/view/welcome');
// 加载菜单
loadMenu();
// 退出登录
$('#logoutBtn').on('click', function () {
window.location.href = '/logout';
});
// 获取当前用户信息(模拟)
$('#currentUser').text('当前用户: admin');
// 加载内容的函数
function loadContent(url) {
// 显示加载动画
$('#content-container').html(`
<div class="loading">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">加载中...</span>
</div>
</div>
`);
// 使用AJAX加载内容
$.ajax({
url: url,
type: 'GET',
success: function (data) {
$('#content-container').html(data);
},
error: function () {
$('#content-container').html(`
<div class="alert alert-danger">
内容加载失败,请稍后重试。
</div>
`);
}
});
}
// 加载菜单的函数
function loadMenu() {
$.ajax({
url: '/menu/list',
type: 'GET',
success: function (res) {
let menus = res.data;
if (menus.length > 0 && menus[0].id) {
renderMenu(menus);
// 存储到本地存储中
localStorage.setItem('menuTree', JSON.stringify(menus));
} else {
let menus = localStorage.getItem('menuTree');
if (menus) {
menus = JSON.parse(menus);
renderMenu(menus);
}
}
// 绑定菜单事件
bindMenuEvents();
},
error: function () {
$('#menuContainer').html(`
<div class="alert alert-danger m-3">
菜单加载失败,请稍后重试。
</div>
`);
}
});
}
// 渲染菜单函数
function renderMenu(menus) {
let menuHtml = '';
// 添加默认欢迎页
menuHtml += `
<a href="#" class="list-group-item list-group-item-action menu-item active" data-url="/view/welcome">
欢迎页
</a>
`;
// 递归渲染菜单
menus.forEach(menu => {
menuHtml += renderMenuItem(menu);
});
$('#menuContainer').html(menuHtml);
}
// 渲染单个菜单项
function renderMenuItem(menu) {
// 只显示type为1或2的菜单项
if (menu.type !== "1" && menu.type !== "2") {
return '';
}
let menuHtml = '';
if (menu.type === "1") {
// 一级菜单(有子菜单)
menuHtml += `
<a href="#" class="list-group-item list-group-item-action menu-has-children menu-item">
${menu.name}
</a>
`;
// 渲染子菜单
if (menu.children && menu.children.length > 0) {
menuHtml += '<div class="submenu">';
menu.children.forEach(child => {
menuHtml += renderMenuItem(child);
});
menuHtml += '</div>';
}
} else if (menu.type === "2") {
// 二级菜单(页面链接)
menuHtml += `
<a href="#" class="list-group-item list-group-item-action menu-item" data-url="/v/${menu.tag}">
${menu.name}
</a>
`;
}
return menuHtml;
}
// 绑定菜单事件
function bindMenuEvents() {
// 菜单点击事件(页面链接)
$('.menu-item').not('.menu-has-children').on('click', function (e) {
e.preventDefault();
// 移除所有活动状态
$('.menu-item').removeClass('active');
// 判断父元素是不是菜单,如果是菜单,则添加活动状态
if ($(this).parent().hasClass('submenu')) {
//获取当前元素的前一个兄弟元素
$(this).parent().prev().addClass('active');
}
// 为当前点击的菜单项添加活动状态
$(this).addClass('active');
// 获取目标URL并加载内容
const url = $(this).data('url');
if (url) {
loadContent(url);
}
});
// 二级菜单展开/收起 - 优化后的逻辑
$('.menu-has-children').on('click', function (e) {
e.preventDefault();
// 切换当前菜单的展开状态
$(this).toggleClass('active');
// 阻止事件冒泡,避免影响其他菜单
e.stopPropagation();
});
}
});
</script>
</body>
</html>