用vscode及人工智能插件磨合的一个后台管理页面(完成就分享,多少有点粗糙,不喜欢可以疯狂抽我)

1、预览

image

2、资源介绍和运行环境

# 1、总共有4个文件:index.html、script.js、style.css、package.json,新建一个项目目录放入这4个文件,目录不能有中文,node要求不能有中文
# 2、然后新建pages文件夹,里面自己新建4个页面:about.html,dictionary.html,menu.html,users.html (根据自己的项目加减)
# 3、首先确保安装了node,去报npm能用
# 4、在项目根目录也就是有package.json的目录,打开终端(cmd)执行npm install ,安装依赖,我配置的vite构建工具(知道的不用解释,不知道的就直接安装就行,会多出来node_modules文件夹和package-lock.json文件,反正我前端也不熟😄)
# 5、好了以后,运行起来项目,终端中执行  npm run dev 提示 http://localhost:5173 大概就成功了,浏览器可以输入网址运行
# (vite支持热更新之类的,就是你javascript 和 html  css修改完马上见效果,vite自带http服务器,所以选择vite,其他工具也行 webpack啥的,反正我也不熟)

3、功能说明

# 1、项目分一级导航菜单和左侧菜单栏
# 2、一级导航菜单位于“xx企业管理系统”后面,比如你看到的“系统管理”,后续也可以增加一些“业务管理”、“流程管理”,总之它是比较大的块,让你可以分块管理
# 3、一级导航菜单尽量少一点吧,毕竟它在系统名称后面,也没多少空间
# 4、script.js有一个变量记载了菜单的json数据结构:
const MENU_PERMISSIONS = {
        "系统管理": {
            "url": "#",
            "icon": "fa fa-folder",
            "target": "expand",
            "is_menu": "1",
            "children": {
                "系统信息管理": {
                    "url": "#",
                    "icon": "fa fa-desktop",
                    "target": "expand",
                    "is_menu": "1",
                    "children": {
                        "菜单管理": {
                            "url": "/pages/menu.html",
                            "icon": "fa fa-sitemap",
                            "target": "iframe",
                            "is_menu": "1"
                        },
                        "字典管理": {
                            "url": "/pages/dictionary.html",
                            "icon": "fa fa-sitemap",
                            "target": "iframe",
                            "is_menu": "1"
                        },
                        "用户管理": {
                            "url": "/pages/users.html",
                            "icon": "fa fa-sitemap",
                            "target": "iframe",
                            "is_menu": "1"
                        }
                    }
                }
            }
        }
    };
# 5、你可以自己按照规则扩展一些菜单,上面的例子可以看到第一个键值对的key=“系统管理”,就是一级菜单,
# 6、每个菜单都是一个键值对,键就是菜单的名称,url是菜单路径,只有target=iframe的时候它才是具体的路径,否则设置成“#”
# 7、icon是图标,应该跟你的引入的font-awesome版本强相关,必须是里面有的选项
# 8、target是菜单打开方式,如果是expand其实就是展开和关闭的菜单,iframe是可以打开新的页面的,我们当前项目打开到iframe标签中
# 9、is_menu:1代表菜单,0代表不是菜单
# 10、所以你用这个项目,就需要整理出这个菜单的json数据,你的数据库菜单表必须至少包含这些字段才行
# 11、首页在页面加载的时候默认打开的,左侧菜单栏点击菜单,都会在首页后面增加新的标签页,并自动增加一个iframe标签
# 12、其他自己演示一下就知道了

4、index.html

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>系统管理界面</title>
    <!-- Bootstrap 5.3.0 CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- Font Awesome CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <!-- 主界面 -->
    <div class="container-fluid p-0">
        <!-- 侧边栏 -->
        <div class="sidebar col-md-3 col-lg-2 d-md-block">
            <div class="sidebar-header">
                <!-- <h6>菜单栏</h6> -->
            </div>
            <div class="position-sticky">
                <ul class="nav flex-column">


                </ul>
            </div>
        </div>

        <!-- 主内容区域 -->
        <main class="main-content">
            <!-- 系统名称 -->
            <div class="system-header">
                <div class="header-left">
                    <i id="menu-toggle" class="fas fa-bars me-3"></i>
                    <h4 class="system-title"><strong>xx企业管理系统</strong></h4>
                    <!-- 一级菜单导航,添加特定类名 -->
                    <div class="nav primary-nav">
                        <ul class="nav flex-column primary-nav-list">
                            <!-- 菜单项会通过 JS 动态生成 -->
                        </ul>
                    </div>
                </div>
                <div class="header-right">
                    <div class="search-box">
                        <input type="text" class="form-control" placeholder="搜索">
                        <i class="fas fa-search search-icon"></i>
                    </div>
                    <!-- 添加徽章 -->
                    <span class="position-relative">
                        <i class="fas fa-bell header-icon" title="消息"></i>
                        <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">
                            3
                        </span>
                    </span>
                    <!-- 将用户图标、用户信息和箭头图标放在一个 div 中 -->
                    <div class="user-dropdown-trigger dropdown-toggle" id="user-dropdown-trigger">
                        <i class="fas fa-user header-icon" title="用户"></i>
                        <span class="user-info">admin-管理员</span>
                    </div>
                    <div class="dropdown">
                        <ul class="dropdown-menu dropdown-menu-end" id="user-dropdown-menu">
                            <li><a class="dropdown-item" href="#">修改密码</a></li>
                            <li><a class="dropdown-item" href="#">安全退出</a></li>
                        </ul>
                    </div>
                </div>
            </div>

            <!-- 标签头信息 -->
            <div class="tag-header">
                <!-- 左箭头 -->
                <div class="tag-arrow">
                    <i id="tag-arrow-prev" class="fas fa-backward"></i>
                </div>

                <!-- 标签导航 -->
                <ul class="nav nav-tabs" id="tag-tabs">
                    <!-- <li class="nav-item">
                        <a class="nav-link active" data-url="pages/about.html" href="#">
                            首页
                        </a>
                    </li> -->
                </ul>

                <!-- 右箭头 -->
                <div class="tag-arrow">
                    <i id="tag-arrow-next" class="fas fa-forward"></i>
                </div>
            </div>

            <!-- 内容区域 -->
            <div class="content-area" id="content-container">
                <!-- 内容将通过JS动态加载 -->
            </div>

            <!-- 新增页脚 -->
            <footer class="custom-footer">
                <p>© 2025 后台管理. All rights reserved.</p>
            </footer>
        </main>
    </div>


    <!-- 修改密码模态框 -->
    <div class="modal fade" id="changePasswordModal" tabindex="-1" aria-labelledby="changePasswordModalLabel"
        aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="changePasswordModalLabel">修改密码</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <form id="changePasswordForm">
                        <div class="mb-3">
                            <label for="oldPassword" class="form-label">原始密码</label>
                            <input type="password" class="form-control" id="oldPassword" required>
                        </div>
                        <div class="mb-3">
                            <label for="newPassword" class="form-label">新密码</label>
                            <input type="password" class="form-control" id="newPassword" required>
                        </div>
                        <div class="mb-3">
                            <label for="confirmPassword" class="form-label">确认密码</label>
                            <input type="password" class="form-control" id="confirmPassword" required>
                        </div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
                    <button type="button" class="btn btn-primary" id="submitPasswordChange">提交</button>
                </div>
            </div>
        </div>
    </div>

    <!-- 消息弹框(重写alert) -->
    <div class="modal fade" id="infoModal" tabindex="-1" aria-labelledby="infoModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="alert alert-primary" role="alert">
                A simple primary alert—check it out!
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>

        </div>
    </div>


    <!-- jQuery 3.6.0 -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <!-- Bootstrap 5.3.0 Bundle with Popper -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script src="script.js"></script>
</body>

</html>

5、script.js

document.addEventListener('DOMContentLoaded', function () { // 页面加载完成后执行
    const menuToggle = document.getElementById('menu-toggle'); // 隐藏菜单栏的图标
    const sidebar = document.querySelector('.sidebar'); // 菜单栏
    const tagTabs = document.getElementById('tag-tabs'); // 标签栏
    const contentContainer = document.getElementById('content-container'); // 内容容器
    const tagArrowPrev = document.getElementById('tag-arrow-prev'); // 标签栏左箭头
    const tagArrowNext = document.getElementById('tag-arrow-next'); // 标签栏右箭头

    const userDropdownTrigger = document.getElementById('user-dropdown-trigger'); // 用户下拉菜单触发器
    const userDropdownMenu = document.getElementById('user-dropdown-menu'); // 用户下拉菜单

    const changePasswordLink = document.querySelector('#user-dropdown-menu a[href="#"]:nth-child(1)'); // 修改密码链接
    const changePasswordModalElement = document.getElementById('changePasswordModal'); // 修改密码模态框
    const changePasswordModal = new bootstrap.Modal(changePasswordModalElement); // 修改密码模态框实例
    const submitButton = document.getElementById('submitPasswordChange'); // 密码修改 提交按钮
    const primaryNavList = document.querySelector('.primary-nav-list'); // 顶部一级菜单
    const sidebarNav = document.querySelector('.sidebar .nav'); // 侧边菜单栏的nav

    // 菜单权限配置(如果是Django项目,下面菜单里的url应该是类似于"/menu/"这种)
    const MENU_PERMISSIONS = {
        "系统管理": {
            "url": "#",
            "icon": "fa fa-folder",
            "target": "expand",
            "is_menu": "1",
            "children": {
                "系统信息管理": {
                    "url": "#",
                    "icon": "fa fa-desktop",
                    "target": "expand",
                    "is_menu": "1",
                    "children": {
                        "菜单管理": {
                            "url": "/pages/menu.html",
                            "icon": "fa fa-sitemap",
                            "target": "iframe",
                            "is_menu": "1"
                        },
                        "字典管理": {
                            "url": "/pages/dictionary.html",
                            "icon": "fa fa-sitemap",
                            "target": "iframe",
                            "is_menu": "1"
                        },
                        "用户管理": {
                            "url": "/pages/users.html",
                            "icon": "fa fa-sitemap",
                            "target": "iframe",
                            "is_menu": "1"
                        }
                    }
                }
            }
        }
    };


    // 重写 alert 方法
    window.alert = function (message) {
        const infoModal = document.getElementById('infoModal');
        const alertElement = infoModal.querySelector('.alert');
        const hideTimeout = message.includes("错误") || message.includes("失败") || message.includes("异常") ||
            message.includes("fail") || message.includes("error") || message.includes("exception")
            ? 3000 : 2000;

        // 先移除之前可能添加的类
        alertElement.classList.remove('alert-danger', 'alert-success', 'alert-primary');

        if (message.includes("错误") || message.includes("失败") || message.includes("异常") ||
            message.includes("fail") || message.includes("error") || message.includes("exception")) {
            alertElement.classList.add('alert-danger');
        } else {
            alertElement.classList.add('alert-success');
        }

        // 设置弹窗内容
        alertElement.textContent = message;

        // 显示模态框
        const infoModalInstance = new bootstrap.Modal(infoModal);
        infoModalInstance.show();

        // 自动隐藏模态框
        setTimeout(() => {
            infoModalInstance.hide();
        }, hideTimeout);
    };


    // 1、生成顶部一级菜单
    function generatePrimaryMenu() {
        primaryNavList.innerHTML = '';
        for (const menuName in MENU_PERMISSIONS) {
            if (MENU_PERMISSIONS.hasOwnProperty(menuName)) {
                const listItem = document.createElement('li');
                listItem.className = 'nav-item';

                const link = document.createElement('a');
                link.className = 'nav-link';
                link.href = '#';
                link.textContent = menuName;

                // 为每个一级菜单添加点击事件(点击的时候生成菜单栏)
                link.addEventListener('click', function (e) {
                    e.preventDefault();
                    // 生成对应子菜单
                    generateSidebarMenu(MENU_PERMISSIONS[menuName].children);
                });

                listItem.appendChild(link);
                primaryNavList.appendChild(listItem);
            }
        }
        // 初始选中第一个一级菜单并生成对应子菜单
        if (primaryNavList.firstElementChild) {
            primaryNavList.firstElementChild.querySelector('.nav-link').click();
        }
    }

    // 2、生成侧边菜单栏
    function generateSidebarMenu(menuItems, parentElement = sidebarNav) {
        // 清空父元素内容
        parentElement.innerHTML = '';
        for (const menuName in menuItems) {
            if (menuItems.hasOwnProperty(menuName)) {
                const menuItem = menuItems[menuName];
                const listItem = document.createElement('li');
                listItem.className = 'nav-item';

                const link = document.createElement('a');
                link.className = 'nav-link';
                link.innerHTML = `<i class="${menuItem.icon} me-2"></i>${menuName}`;

                if (menuItem.target === 'expand') {
                    // 生成箭头图标,默认向左箭头,追加在link的后面
                    const arrowIcon = document.createElement('i');
                    arrowIcon.className = 'fas fa-angle-left ms-auto';
                    link.appendChild(arrowIcon);

                    link.href = '#';
                    link.addEventListener('click', function (e) { // 点击事件,展开和折叠
                        e.preventDefault();
                        const subMenu = this.nextElementSibling; // 获取下一个兄弟元素,即子菜单
                        if (subMenu) {
                            subMenu.classList.toggle('d-none');
                            // 切换箭头方向
                            arrowIcon.classList.toggle('fa-angle-left');
                            arrowIcon.classList.toggle('fa-angle-down');
                        }
                        this.classList.toggle('active');
                    });
                    listItem.appendChild(link);

                    // 生成子菜单
                    const subMenu = document.createElement('ul');
                    subMenu.className = 'nav flex-column d-none';
                    generateSidebarMenu(menuItem.children, subMenu);
                    listItem.appendChild(subMenu);
                } else if (menuItem.target === 'iframe') {
                    // 添加占位图标以保持对齐
                    const placeholderIcon = document.createElement('i');
                    placeholderIcon.className = 'fas fa-angle-left ms-auto opacity-0'; // 透明图标
                    link.appendChild(placeholderIcon);

                    link.href = '#';
                    link.setAttribute('data-url', menuItem.url);
                    link.addEventListener('click', function (e) {
                        e.preventDefault();
                        const pagePath = this.getAttribute('data-url'); // 获取页面路径
                        const pageName = this.textContent.trim(); // 获取页面名称
                        handleTabClick(pagePath, pageName);
                        // 移除其他侧边栏菜单项的 active 类
                        document.querySelectorAll('.sidebar .nav-link').forEach(item => {
                            if (item !== this) {
                                item.classList.remove('active');
                            }
                        });
                        this.classList.add('active');
                    });
                    listItem.appendChild(link);
                }

                parentElement.appendChild(listItem);
            }
        }
    }

    // 3、菜单栏点击事件(创建标签,传入一个“是否允许关闭”参数,默认是允许的true)
    function handleTabClick(pagePath, pageName, allowClose = true) {
        // 判断是否已经存在该标签页,如果存在则激活并加载内容
        const existingTab = document.querySelector(`#tag-tabs .nav-link[data-url="${pagePath}"]`);
        if (existingTab) {
            document.querySelectorAll('.nav-link').forEach(tab => tab.classList.remove('active'));
            existingTab.classList.add('active');
            const iframe = contentContainer.querySelector(`iframe[src="${pagePath}"]`);
            if (iframe) {
                // 隐藏所有 iframe
                contentContainer.querySelectorAll('.iframe-content').forEach(iframe => {
                    iframe.style.display = 'none';
                });
                // 显示当前选中的 iframe
                iframe.style.display = 'block';
            }
            existingTab.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'end' });
            return;
        }

        // 创建新标签页(不存在)
        const newTab = document.createElement('li');
        newTab.className = 'nav-item';
        if (allowClose) { // 允许关闭的话,添加关闭按钮
            newTab.innerHTML = `<a class="nav-link active" data-url="${pagePath}" href="#">
                ${pageName}
                <button type="button" class="btn-close btn-close-sm" aria-label="Close"></button>
            </a>`;
        } else {
            newTab.innerHTML = `<a class="nav-link active" data-url="${pagePath}" href="#">
                ${pageName} 
            </a>`  ;
        }

        document.querySelectorAll('.nav-link').forEach(tab => tab.classList.remove('active')); // 移除其他标签页的 active 类
        tagTabs.appendChild(newTab); // 添加新标签页到标签栏
        loadPageContent(pagePath, pageName); // 1、加载页面内容
        newTab.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'end' }); // 滚动到新标签页
        setupTabEvents(newTab); // 2、为新标签页设置事件
    }

    // 4、加载iframe页面内容的函数
    async function loadPageContent(pagePath, pageName) {
        let iframe = contentContainer.querySelector(`iframe[src = "${pagePath}"]`);

        try {
            // 先使用 fetch 检查状态码
            const response = await fetch(pagePath, { method: 'HEAD' });
            if (!response.ok) {
                const statusCode = response.status;
                let errorMessage;
                switch (statusCode) {
                    case 401:
                        errorMessage = '错误:会话失效,请重新登录!';
                        alert(errorMessage);
                        break;
                    case 403:
                        errorMessage = '错误:您没有权限访问该页面。';
                        break;
                    case 404:
                        errorMessage = '错误:页面未找到。';
                        break;
                    case 500:
                        errorMessage = '错误:服务器内部错误,请稍后再试。';
                        break;
                    default:
                        errorMessage = `错误:加载页面失败,错误码:${statusCode} `;
                }
                alert(errorMessage);

            }

            // 如果 iframe 不存在则创建新的
            if (!iframe) {
                // 创建 iframe 元素
                iframe = document.createElement('iframe');
                iframe.className = 'iframe-content';
                iframe.src = pagePath;
                // iframe.name = pagePath;
                iframe.title = pageName;
                iframe.style.display = 'none'; // 初始隐藏
                // 宽度100%,高度100%
                iframe.style.width = '100%';
                iframe.style.height = '100%';

                // 监听 iframe 的 load 事件
                iframe.addEventListener('load', () => {
                    console.log('页面加载成功:', pagePath);
                });

                // 监听 iframe 的 error 事件
                iframe.addEventListener('error', () => {
                    console.error('错误:加载页面时出错:', pagePath);
                    // 显示错误信息
                    contentContainer.innerHTML = `< div class="alert alert-danger" > 错误:加载页面失败:${pagePath}</div > `;
                });

                contentContainer.appendChild(iframe);
            }

            // 隐藏所有其他 iframe,然后显示当前iframe
            contentContainer.querySelectorAll('.iframe-content').forEach(iframe => {
                iframe.style.display = 'none';
            });
            iframe.style.display = 'block';
        } catch (error) {
            console.error('请求页面时出错:', error);
            contentContainer.innerHTML = `< div class="alert alert-danger" > 错误:请求页面时出错,请检查网络连接。</div > `;
        }
    }

    // 5、标签点击事件、标签关闭事件
    function setupTabEvents(tabElement) {
        const tabLink = tabElement.querySelector('.nav-link');
        const closeButton = tabElement.querySelector('.btn-close'); // 查找当前标签的关闭按钮

        // 标签点击事件
        tabLink.addEventListener('click', function (e) {
            e.preventDefault();
            document.querySelectorAll('.nav-link').forEach(tab => tab.classList.remove('active'));
            this.classList.add('active');
            const pagePath = this.getAttribute('data-url');
            const iframe = contentContainer.querySelector(`iframe[src = "${pagePath}"]`);
            if (iframe) {
                // 隐藏所有 iframe
                contentContainer.querySelectorAll('.iframe-content').forEach(iframe => {
                    iframe.style.display = 'none';
                });
                // 显示当前选中的 iframe
                iframe.style.display = 'block';
            }
            this.closest('.nav-item').scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'end' });
        });

        // 标签关闭事件(首页没有关闭标签)
        if (closeButton) {
            closeButton.addEventListener('click', function (e) {
                e.stopPropagation();
                const tabElement = this.closest('.nav-item');
                const isActive = tabLink.classList.contains('active');
                const pagePath = tabLink.getAttribute('data-url');

                const iframeToRemove = contentContainer.querySelector(`iframe[src = "${pagePath}"]`);

                if (iframeToRemove) {
                    iframeToRemove.remove();
                }

                tabElement.remove();

                if (isActive && tagTabs.children.length > 0) {
                    const lastTab = tagTabs.lastElementChild.querySelector('.nav-link');
                    lastTab.classList.add('active');
                    const lastPagePath = lastTab.getAttribute('data-url');
                    const lastIframe = contentContainer.querySelector(`iframe[src = "${lastPagePath}"]`);
                    if (lastIframe) {
                        // 隐藏所有 iframe
                        contentContainer.querySelectorAll('.iframe-content').forEach(iframe => {
                            iframe.style.display = 'none';
                        });
                        // 显示最后一个标签页对应的 iframe
                        lastIframe.style.display = 'block';
                    }
                    lastTab.closest('.nav-item').scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'end' });
                } else if (tagTabs.children.length === 0) {
                    contentContainer.innerHTML = '<div class="alert alert-info">请选择左侧菜单打开页面</div>';
                }
            });
        }
    }

    // 侧边栏折叠功能
    menuToggle.addEventListener('click', function () {
        sidebar.classList.toggle('collapsed');
    });

    // 标签行,左箭头点击事件
    tagArrowPrev.addEventListener('click', function () {
        const tabWidth = tagTabs.clientWidth;
        const scrollLeft = tagTabs.scrollLeft;
        const newScrollLeft = Math.max(0, scrollLeft - tabWidth);
        tagTabs.scrollTo({
            left: newScrollLeft,
            behavior: 'smooth'
        });
    });

    // 标签行,右箭头点击事件
    tagArrowNext.addEventListener('click', function () {
        const tabWidth = tagTabs.clientWidth;
        const scrollLeft = tagTabs.scrollLeft;
        const scrollWidth = tagTabs.scrollWidth;
        const newScrollLeft = Math.min(scrollWidth - tabWidth, scrollLeft + tabWidth);
        tagTabs.scrollTo({
            left: newScrollLeft,
            behavior: 'smooth'
        });
    });

    // 用户下拉菜单点击事件
    userDropdownTrigger.addEventListener('click', function (e) {
        e.stopPropagation();
        userDropdownMenu.classList.toggle('show');
    });

    // 点击页面其他地方隐藏菜单,
    document.addEventListener('click', function (e) {
        if (!userDropdownTrigger.contains(e.target) && !userDropdownMenu.contains(e.target)) {
            userDropdownMenu.classList.remove('show');
        }
    });

    // 修改密码链接点击事件
    changePasswordLink.addEventListener('click', function (e) {
        e.preventDefault();
        changePasswordModal.show();
    });

    // 修改密码提交
    submitButton.addEventListener('click', function () {
        const oldPassword = document.getElementById('oldPassword').value;
        const newPassword = document.getElementById('newPassword').value;
        const confirmPassword = document.getElementById('confirmPassword').value;
        // 旧密码不能为空
        if (oldPassword.trim() === '') {
            alert('错误:旧密码不能为空,请输入旧密码。');
            return;
        }
        // 验证新密码和确认密码一致
        if (newPassword !== confirmPassword) {
            alert('错误:新密码和确认密码不一致,请重新输入。');
            return;
        }
        // 新密码和旧密码不能一致
        if (newPassword === oldPassword) {
            alert('错误:新密码和旧密码不能一致,请重新输入。');
            return;
        }
        // 可以增加实际的密码修改逻辑,这里只是模拟提交
        changePasswordModal.hide(); // 关闭模态框
    });

    // 加载首页内容
    handleTabClick('/pages/about.html', '首页', false);

    // 生成一级菜单
    generatePrimaryMenu();

});

6、style.css


body {
    height: 100vh;
    overflow: hidden;
}

/* 左侧滚动条 */

.sidebar {
    width: 250px;
    background-color: #2d3436;
    color: white;
    height: 100vh;
    /* padding-top: 20px; */
    position: fixed;
    overflow-y: auto;
    /* 滚动条隐藏 */
    scrollbar-width: none;
    transition: width 0.3s ease;
    /* padding-top: 60px; */
    /* border-top: 2px solid white; */
}

.sidebar .sidebar-header {
    height: 60px;
    width: 100%;
    margin: 0;
}

/* .sidebar .sidebar-header:hover {
    background-color: #337ab7;
} */

.sidebar .position-sticky {
    border-top: 1px solid #337ab7;
}

.sidebar.collapsed {
    /* 折叠状态 */
    width: 0;
    overflow-x: hidden;
}


.sidebar.collapsed~.main-content {
    margin-left: 0;
}

.sidebar .nav-link {
    color: #dfe6e9;
    padding: 10px 20px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/* 菜单层级缩进 */
.sidebar .nav .nav {
    padding-left: 20px;
    background-color: #434849;
}

.sidebar .nav .nav .nav {
    padding-left: 40px;
    background-color: #5a5c5c;
}

.sidebar .nav .nav .nav .nav {
    padding-left: 60px;
    background-color: #989999;
}

.sidebar .nav-link:hover {
    background-color: #636e72;
    color: white;
}

.sidebar .nav-link.active {
    /* background-color: #636e72; */
    color: #61b4fc;
}




/* 右侧内容主区域 */

.main-content {
    transition: margin-left 0.3s ease;
    /* 平滑过渡 */
    margin: 0;
    margin-left: 250px;
    padding: 0;
    height: 100vh;
    overflow-y: auto;
}



/* system-header 系统信息 */

.system-header {
    height: 60px;
    padding-left: 15px;
    margin: 0;
    background-color: #337ab7;
    color: white;
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* 让左侧内容和右侧内容分居两端 */
    border-bottom: none;
    /* 取消下边框线 */
}

.header-left {
    display: flex;
    align-items: center;
    gap: 15px;
    /* 设置左侧元素之间的间距 */
}

.header-right {
    display: flex;
    align-items: center;
    gap: 15px;
    /* 设置右侧元素之间的间距 */
    padding-right: 15px;
}

/* 调整搜索框样式 */
.header-right .search-box {
    width: 150px;
    /* 适当减小搜索框宽度 */
}

.header-right .search-box input {
    padding: 0.3em 0.6em;
    /* 减小输入框内边距 */
    font-size: 1em;
    /* 基于父元素的字号 */
}

.header-right .search-icon {
    font-size: 1em;
    /* 调整放大镜图标字号 */
}

/* 调整图标样式 */
.header-right .header-icon {
    font-size: 1.2em;
    /* 调整消息图标和用户图标的字号 */
}

/* 调整用户信息文本字号 */
.header-right .user-info {
    font-size: 1em;
    /* 调整用户信息文本字号 */
}

/* 调整下拉箭头按钮样式 */
.header-right .dropdown-toggle {
    font-size: 1em;
    /* 调整下拉箭头按钮字号 */
}

/* 调整下拉菜单项字号 */
.header-right .dropdown-menu .dropdown-item {
    font-size: 1em;
    /* 调整下拉菜单项字号 */
}

.search-box {
    position: relative;
    width: 200px;
    /* 设置搜索框宽度 */
}

.search-box input {
    padding-right: 30px;
    /* 为放大镜图标留出空间 */
}

.search-icon {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: #666;
}

.header-icon {
    font-size: 20px;
    cursor: pointer;
    transition: color 0.3s;
}

.header-icon:hover {
    color: #e0e0e0;
    /* 鼠标悬停时改变图标颜色 */
}

.user-info {
    font-size: 14px;
}

.dropdown {
    margin-top: 40px;
}

.dropdown-toggle {
    background: none;
    border: none;
    color: white;
    padding: 0;
}

.dropdown-menu {
    min-width: 150px;
}



/* system-header里的i标签样式 */
.system-header i {
    cursor: pointer;
}

.system-title {
    font-size: 24px;
    line-height: 60px;
    margin: 0;
    text-shadow: 3px 3px 7px #000;
    /* 水平偏移、垂直偏移、模糊半径、颜色 */
}




/* tag-header */

.tag-header {
    border-bottom: 2px solid #2d3436;
    display: flex;
    /* 使用 Flexbox 布局 */
    align-items: center;
    /* 垂直居中 */
    position: relative;
    /* 相对定位 */
    height: 40px;
}

/* 标签页左右箭头样式 */
.tag-header .tag-arrow {
    padding: 0 10px;
    cursor: pointer;
    color: #a6abad;
    border: 1px solid #a6abad;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* 标签页左右箭头鼠标悬浮样式 */
.tag-header .tag-arrow:hover {
    color: #000;
}

.tag-header .nav-tabs {
    flex: 1;
    /* 允许标签项自动扩展 */
    min-width: calc(100% - 80px);
    /* 减去左右边距 */
    overflow-x: auto;
    /* 允许水平滚动 */
    scrollbar-width: none;
    /* 隐藏滚动条 */
    white-space: nowrap;
    /* 防止标签项换行 */
    /* 标签容器禁止换行 */
    scroll-behavior: smooth;
    /* 平滑滚动效果 */
    flex-wrap: nowrap;
    /* 标签项保持行内布局 */
    /* 标签项保持行内布局 */

    /* 左右边距 */
    padding: 0;
}




/* 标签项保持行内布局 */
.tag-header .nav-tabs .nav-link {
    display: inline-block;
}


/* 标签页中的关闭按钮样式 */
.tag-header .btn-close {
    font-size: 9px;
}

/* 去掉标签页的圆角 */
.tag-header .nav-link {
    border-radius: 0;
    color: #646363;
}

.tag-header .nav-item {
    padding: 0;
    margin: 0;
}

/* 活跃的标签页样式 */
.tag-header .nav-link.active {
    background-color: #2d3436;
    /* border-radius: 0; */
    border: 1px solid #2d3436;
    color: white;
}

/* 标签页的边框清空 */
.tag-header ul,
.tag-header li {
    border: 0;
}

.tag-header .nav-link:hover {
    /* background-color: #e8edee; */
    color: #0a58ca;
}

.tag-header .nav-link.active .btn-close {
    filter: invert(1) !important;
    opacity: 1 !important;
}


.content-area {
    padding: 15px;
    width: 100%;
    height: calc(100% - 145px);
}


/* 调整侧边栏导航链接字号 */
.sidebar .nav-link {
    font-size: 14px;
}

/* 调整标签页导航链接字号 */
.tag-header .nav-tabs .nav-link {
    font-size: 14px;
}


.user-dropdown-trigger {
    display: flex;
    align-items: center;
    cursor: pointer;
    gap: 5px;
}

.dropdown-menu {
    position: absolute;
    top: 100%;
    right: 0;
    display: none;
}

.dropdown-menu.show {
    display: block;
}


/* 调整一级菜单导航容器 */
.primary-nav {
    display: flex;
    align-items: center;
}

/* 调整一级菜单导航列表 */
.primary-nav-list {
    flex-direction: row !important;

}


/* 调整一级菜单导航链接 */
.primary-nav-list .nav-link {
    color: white;
    font-size: 14px;
}

.primary-nav-list .nav-link:hover {
    color: #dfe6e9;
    /* 鼠标悬停时颜色变化 */
}


.custom-footer {
    height: 40px;
    /* 设置页脚宽度为 40px */
    margin: 0 auto;
    /* 水平居中 */
    text-align: center;
    /* 文字居中 */
    padding: 10px 0;
    /* 上下内边距 */
    border-top: 1px solid #ccc;
    /* 添加顶部边框 */
    background-color: #f7f7f7;
}

7、package.json

{
  "name": "admin-dashboard",
  "version": "1.0.0",
  "description": "后台管理系统",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "bootstrap": "^5.3.0",
    "jquery": "^3.6.0"
  },
  "devDependencies": {
    "vite": "^4.4.0"
  }
}
posted on 2025-07-28 16:41  94小渣渣  阅读(151)  评论(0)    收藏  举报