Files
asset_assistant/frontend/asset-assistant-system/assets/js/components/sidebar.js
2025-11-12 17:24:55 +08:00

177 lines
4.3 KiB
JavaScript
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.
/**
* 侧边栏菜单组件
*/
window.Sidebar = {
/**
* 初始化侧边栏
* @param {jQuery} container - 容器元素
*/
init(container) {
this.container = container;
this.collapse = localStorage.getItem(SystemConfig.menuCollapseKey) === 'true';
this.renderMenu();
this.bindEvents();
this.updateCollapseState();
},
/**
* 渲染菜单
*/
renderMenu() {
const menuHtml = this.generateMenuHtml(MenuConfig);
this.container.html(menuHtml);
},
/**
* 生成菜单HTML递归处理多级菜单
* @param {array} menuList - 菜单列表
* @returns {string} - 菜单HTML
*/
generateMenuHtml(menuList) {
let html = '<ul class="sidebar-menu">';
menuList.forEach(menu => {
const hasChildren = menu.children && menu.children.length > 0;
const isActive = window.location.pathname.includes(menu.url);
html += `<li class="menu-item ${hasChildren ? 'has-children' : ''} ${isActive ? 'active' : ''}" data-id="${menu.id}">`;
// 菜单标题
html += `<div class="menu-title">`;
html += `<span class="menu-icon">${menu.icon}</span>`;
html += `<span class="menu-text">${menu.title}</span>`;
if (hasChildren) {
html += `<span class="menu-toggle ${this.collapse ? 'collapsed' : ''}">${this.collapse ? '+' : '-'}</span>`;
}
html += `</div>`;
// 子菜单
if (hasChildren) {
html += `<ul class="sub-menu ${this.collapse ? 'hidden' : ''}">`;
html += this.generateMenuHtml(menu.children);
html += `</ul>`;
} else if (menu.url) {
// 菜单项链接
html += `<a href="${menu.url}" class="menu-link"></a>`;
}
html += `</li>`;
});
html += '</ul>';
return html;
},
/**
* 绑定事件
*/
bindEvents() {
// 菜单折叠/展开
this.container.on('click', '.menu-toggle', (e) => {
const $toggle = $(e.currentTarget);
const $subMenu = $toggle.closest('.menu-item').find('.sub-menu');
this.collapse = !this.collapse;
localStorage.setItem(SystemConfig.menuCollapseKey, this.collapse);
$toggle.text(this.collapse ? '+' : '-');
$subMenu.toggleClass('hidden', this.collapse);
this.updateCollapseState();
});
// 菜单项点击(无链接时展开子菜单)
this.container.on('click', '.menu-title:not(.has-children)', (e) => {
const $title = $(e.currentTarget);
const $link = $title.siblings('.menu-link');
if ($link.length) {
$link[0].click();
}
});
},
/**
* 更新折叠状态样式
*/
updateCollapseState() {
$('.sidebar').toggleClass('collapsed', this.collapse);
$('.main-content').toggleClass('sidebar-collapsed', this.collapse);
}
};
// 添加侧边栏样式
$('head').append(`
<style>
.sidebar {
width: 240px;
height: 100%;
background-color: var(--bg-light-color);
border-right: 1px solid var(--border-color);
transition: width 0.3s ease;
overflow: hidden;
}
.sidebar.collapsed {
width: 60px;
}
.sidebar-menu {
list-style: none;
}
.menu-item {
margin-bottom: 2px;
}
.menu-title {
display: flex;
align-items: center;
padding: 12px 16px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.menu-title:hover {
background-color: var(--hover-color);
}
.menu-item.active .menu-title {
background-color: var(--active-color);
}
.menu-icon {
margin-right: 12px;
font-size: 18px;
}
.menu-text {
flex: 1;
transition: opacity 0.3s ease;
}
.sidebar.collapsed .menu-text {
opacity: 0;
width: 0;
margin: 0;
}
.menu-toggle {
font-size: 14px;
cursor: pointer;
transition: transform 0.3s ease;
}
.sub-menu {
list-style: none;
background-color: var(--bg-color);
transition: all 0.3s ease;
}
.sub-menu.hidden {
display: none;
}
.menu-link {
display: block;
height: 100%;
width: 100%;
position: absolute;
top: 0;
left: 0;
}
.main-content {
flex: 1;
padding: 20px;
transition: margin-left 0.3s ease;
}
.main-content.sidebar-collapsed {
margin-left: -180px;
}
</style>
`);