浏览代码

feat: Add category navigation and delete prompts to the backend, and optimize the frontend menu items.

dqzboy 1 年之前
父节点
当前提交
0bec0e5066
共有 3 个文件被更改,包括 484 次插入162 次删除
  1. 2 4
      hubcmdui/README.md
  2. 414 135
      hubcmdui/web/admin.html
  3. 68 23
      hubcmdui/web/index.html

+ 2 - 4
hubcmdui/README.md

@@ -105,13 +105,13 @@ docker logs -f [容器ID或名称]
 
 <table>
     <tr>
-        <td width="50%" align="center"><img src="https://github.com/user-attachments/assets/8c4241a5-e5cc-418c-8020-75eebe7f2fd1"?raw=true"></td>
+        <td width="50%" align="center"><img src="https://github.com/user-attachments/assets/e69f0473-04c1-473d-a580-6e9a85c4053c"?raw=true"></td>
     </tr>
 </table>
 
 <table>
     <tr>
-        <td width="50%" align="center"><img src="https://github.com/user-attachments/assets/4690d899-0ee3-40e5-b5a2-861e750210ed"?raw=true"></td>
+        <td width="50%" align="center"><img src="https://github.com/user-attachments/assets/7f3196c6-5da7-409a-ab49-1037ad0db1d6"?raw=true"></td>
     </tr>
 </table>
 
@@ -120,8 +120,6 @@ docker logs -f [容器ID或名称]
 ## 🫶 赞助
 如果你觉得这个项目对你有帮助,请给我点个Star。并且情况允许的话,可以给我一点点支持,总之非常感谢支持😊
 
-> 项目作者自建公益服务:[服务地址查看](https://uk.dqzboy.xyz/)
-
 <table>
     <tr>
       <td width="50%" align="center"><b> Alipay </b></td>

+ 414 - 135
hubcmdui/web/admin.html

@@ -15,12 +15,9 @@
             background-color: #f6f8fa;
         }
         .container {
-            max-width: 1000px;
-            margin: 0 auto;
-            background: white;
-            padding: 20px;
-            border-radius: 8px;
-            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+            background: transparent;
+            box-shadow: none;
+            padding: 0;
         }
         h1, h2 {
             border-bottom: 2px solid #eaecef;
@@ -121,25 +118,74 @@
             display: none;
         }
         .login-modal {
-            display: none;
+            display: flex;
             position: fixed;
-            z-index: 1;
+            z-index: 1000;
             left: 0;
             top: 0;
             width: 100%;
             height: 100%;
             overflow: auto;
-            background-color: rgba(0,0,0,0.4);
+            background: linear-gradient(135deg, #43cea2 0%, #185a9d 100%);
+            justify-content: center;
+            align-items: center;
         }
         .login-content {
             background-color: rgba(255, 255, 255, 0.8);
-            backdrop-filter: blur(10px);
             margin: 15% auto;
             padding: 20px;
             border: 1px solid #888;
-            width: 30%;
-            border-radius: 8px;
+            width: 300px;
+            border-radius: 5px;
             box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+            position: relative;
+        }
+        .login-header h2 {
+            color: #333;
+            font-size: 28px;
+            margin-bottom: 20px;
+            text-align: center;
+        }
+        .login-form input[type="text"],
+        .login-form input[type="password"] {
+            width: 100%;
+            padding: 12px;
+            margin: 10px 0;
+            border: 1px solid #ddd;
+            border-radius: 4px;
+            box-sizing: border-box;
+            font-size: 16px;
+        }
+        .login-form button {
+            width: 100%;
+            padding: 12px;
+            background-color: #4CAF50;
+            color: white;
+            border: none;
+            border-radius: 4px;
+            cursor: pointer;
+            font-size: 18px;
+            margin-top: 20px;
+        }
+        .login-form button:hover {
+            background-color: #45a049;
+        }
+        .captcha-container {
+            display: flex;
+            align-items: center;
+            margin: 10px 0;
+        }
+        .captcha-container input {
+            flex: 1;
+            margin-right: 10px;
+        }
+        .captcha-container span {
+            padding: 12px;
+            background-color: #f1f1f1;
+            border: 1px solid #ddd;
+            border-radius: 4px;
+            cursor: pointer;
+            font-size: 14px;
         }
         .user-management {
             position: absolute;
@@ -164,78 +210,281 @@
             font-size: 12px;
             margin-top: 5px;
         }
+
+        .admin-container {
+            display: flex;
+            min-height: 100vh;
+        }
+
+        .sidebar {
+            width: 200px;
+            background-color: #f6f8fa;
+            border-right: 1px solid #e1e4e8;
+            padding-top: 20px;
+        }
+
+        .sidebar h2 {
+            padding: 0 20px;
+            margin-bottom: 20px;
+            font-size: 18px;
+            color: #24292e;
+        }
+
+        .sidebar ul {
+            list-style-type: none;
+            padding: 0;
+            margin: 0;
+        }
+
+        .sidebar li {
+            padding: 10px 20px;
+            cursor: pointer;
+            color: #0366d6;
+        }
+
+        .sidebar li:hover {
+            background-color: #f1f8ff;
+        }
+
+        .sidebar li.active {
+            background-color: #f1f8ff;
+            font-weight: bold;
+            border-right: 1px solid #e1e4e8;
+        }
+
+        .content-area {
+            flex-grow: 1;
+            padding: 20px 30px;
+        }
+
+        .content-section {
+            background-color: transparent;
+            box-shadow: none;
+            padding: 0;
+            margin-bottom: 30px;
+            display: none;
+        }
+
+        .content-section.active {
+            display: block;
+        }
+
+
+        /* 全局样式 */
+        .content-section {
+            background-color: #ffffff;
+            border-radius: 8px;
+            box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
+            padding: 20px;
+            margin-bottom: 20px;
+        }
+
+        .content-section h1.admin-title {
+            font-size: 24px;
+            color: #24292e;
+            margin-bottom: 20px;
+            padding-bottom: 10px;
+            border-bottom: 2px solid #e1e4e8;
+        }
+
+        .content-section h2.menu-label {
+            font-size: 18px;
+            color: #0366d6;
+            margin-top: 30px;
+            margin-bottom: 15px;
+        }
+
+        /* 表单元素样式 */
+        .content-section label {
+            display: block;
+            margin-top: 15px;
+            margin-bottom: 5px;
+            font-weight: 600;
+            color: #24292e;
+        }
+
+        .content-section input[type="text"],
+        .content-section input[type="url"],
+        .content-section input[type="password"] {
+            width: 100%;
+            padding: 8px 12px;
+            margin-bottom: 15px;
+            border: 1px solid #e1e4e8;
+            border-radius: 4px;
+            font-size: 14px;
+        }
+
+        .content-section input[type="text"],
+        .content-section input[type="url"],
+        .content-section input[type="password"] {
+            width: 100%;
+            max-width: 400px;
+            padding: 8px 12px;
+            margin-bottom: 15px;
+            border: 1px solid #e1e4e8;
+            border-radius: 4px;
+            font-size: 14px;
+        }
+
+        .content-section button {
+            background-color: #2ea44f;
+            color: white;
+            border: none;
+            padding: 10px 16px;
+            margin-top: 10px;
+            border-radius: 6px;
+            cursor: pointer;
+            font-size: 14px;
+            transition: background-color 0.3s ease;
+        }
+        .content-section button:hover {
+            background-color: #2c974b;
+        }
+        /* 表格样式优化 */
+        .content-section table {
+            width: 100%;
+            border-collapse: separate;
+            border-spacing: 0;
+            margin-top: 20px;
+        }
+
+        .content-section th,
+        .content-section td {
+            border: 1px solid #e1e4e8;
+            padding: 12px;
+            text-align: left;
+        }
+
+        .content-section th {
+            background-color: #f6f8fa;
+            font-weight: 600;
+            color: #24292e;
+        }
+
+        .content-section tr:nth-child(even) {
+            background-color: #f6f8fa;
+        }
+
+        /* 特定功能区域样式 */
+        #basic-config input[type="url"],
+        #basic-config input[type="text"] {
+            max-width: 400px;
+        }
+
+        #password-change .password-hint {
+            font-size: 12px;
+            color: #6a737d;
+            margin-top: 5px;
+            display: block;
+        }
+
+        #password-change #passwordStrength {
+            font-size: 14px;
+            margin-top: 5px;
+            display: block;
+        }
+
+        /* 响应式设计 */
+        @media (max-width: 768px) {
+            .content-section h1.admin-title {
+                font-size: 20px;
+            }
+
+            .content-section input[type="text"],
+            .content-section input[type="url"],
+            .content-section input[type="password"] {
+                max-width: 100%;
+            }
+        }
     </style>
 </head>
 <body>
-    <div class="container hidden" id="adminContainer">
-        <h1 class="admin-title">Docker 镜像代理加速 - 管理面板</h1>
-        <form id="adminForm">
-            <label for="logoUrl">Logo URL: (可选)</label>
-            <input type="url" id="logoUrl" name="logoUrl">
-            <button type="button" onclick="saveLogo()">保存 Logo</button>
-            
-            <label for="proxyDomain">Docker镜像代理地址: (必填)</label>
-            <input type="text" id="proxyDomain" name="proxyDomain" required>
-            <button type="button" onclick="saveProxyDomain()">保存代理地址</button>
-            
-            <h2 class="menu-label">菜单项管理</h2>
-            <table id="menuTable">
-                <thead>
-                    <tr>
-                        <th>文本</th>
-                        <th>链接 (可选)</th>
-                        <th>新标签页打开</th>
-                        <th>操作</th>
-                    </tr>
-                </thead>
-                <tbody id="menuTableBody">
-                    <!-- 菜单项将在这里动态添加 -->
-                </tbody>
-            </table>
-            <button type="button" class="add-btn" onclick="showNewMenuItemRow()">添加菜单项</button>
-            
-            <h2 class="menu-label">广告管理</h2>
-            <table id="adTable">
-                <thead>
-                    <tr>
-                        <th>广告URL</th>
-                        <th>跳转URL</th>
-                        <th>操作</th>
-                    </tr>
-                </thead>
-                <tbody id="adTableBody">
-                    <!-- 广告项将在这里动态添加 -->
-                </tbody>
-            </table>
-            <button type="button" class="add-btn" onclick="showNewAdRow()">添加广告</button>
-
-            <!-- 修改密码的独立表单 -->
-            <div id="passwordChangeForm" style="margin-top: 20px;">
-                <h2 class="menu-label">修改密码</h2>
-                <label for="currentPassword">当前密码</label>
-                <input type="password" id="currentPassword" name="currentPassword">
-                <label for="newPassword">新密码</label>
-                <span class="password-hint" id="passwordHint">密码必须包含至少一个字母、一个数字和一个特殊字符,长度在8到16个字符之间</span>
-                <input type="password" id="newPassword" name="newPassword" oninput="checkPasswordStrength()">
-                <span id="passwordStrength" style="color: red;"></span>
-                <button type="button" onclick="changePassword()">修改密码</button>
+    <div class="admin-container hidden" id="adminContainer">
+        <div class="sidebar">
+            <h2>管理面板</h2>
+            <ul>
+                <li class="active" data-section="basic-config">基本配置</li>
+                <li data-section="menu-management">菜单管理</li>
+                <li data-section="ad-management">广告管理</li>
+                <li data-section="password-change">修改密码</li>
+            </ul>
+        </div>
+        <div class="content-area">
+            <div class="container">
+                <!-- 将原有的内容分成四个部分,每个部分对应一个侧边栏项目 -->
+                <div id="basic-config" class="content-section active">
+                    <label for="logoUrl">Logo URL: (可选)</label>
+                    <input type="url" id="logoUrl" name="logoUrl">
+                    <button type="button" onclick="saveLogo()">保存 Logo</button>
+
+                    <label for="proxyDomain">Docker镜像代理地址: (必填)</label>
+                    <input type="text" id="proxyDomain" name="proxyDomain" required>
+                    <button type="button" onclick="saveProxyDomain()">保存代理地址</button>
+                </div>
+                
+                <div id="menu-management" class="content-section">
+                    <h2 class="menu-label">菜单项管理</h2>
+                    <table id="menuTable">
+                        <thead>
+                            <tr>
+                                <th>文本</th>
+                                <th>链接 (可选)</th>
+                                <th>新标签页打开</th>
+                                <th>操作</th>
+                            </tr>
+                        </thead>
+                        <tbody id="menuTableBody">
+                            <!-- 菜单项将在这里动态添加 -->
+                        </tbody>
+                    </table>
+                    <button type="button" class="add-btn" onclick="showNewMenuItemRow()">添加菜单项</button>
+                </div>
+                
+                <div id="ad-management" class="content-section">
+                    <h2 class="menu-label">广告管理</h2>
+                    <table id="adTable">
+                        <thead>
+                            <tr>
+                                <th>广告图片URL</th>
+                                <th>跳转URL</th>
+                                <th>操作</th>
+                            </tr>
+                        </thead>
+                        <tbody id="adTableBody">
+                            <!-- 广告项将在这里动态添加 -->
+                        </tbody>
+                    </table>
+                    <button type="button" class="add-btn" onclick="showNewAdRow()">添加广告</button>
+                </div>
+                
+                <div id="password-change" class="content-section">
+                    <h2 class="menu-label">修改密码</h2>
+                    <label for="currentPassword">当前密码</label>
+                    <input type="password" id="currentPassword" name="currentPassword">
+                    <label for="newPassword">新密码</label>
+                    <span class="password-hint" id="passwordHint">密码必须包含至少一个字母、一个数字和一个特殊字符,长度在8到16个字符之间</span>
+                    <input type="password" id="newPassword" name="newPassword" oninput="checkPasswordStrength()">
+                    <span id="passwordStrength" style="color: red;"></span>
+                    <button type="button" onclick="changePassword()">修改密码</button>
+                </div>
             </div>
-        </form>
+        </div>
     </div>
 
     <div class="login-modal" id="loginModal">
         <div class="login-content">
-            <h2>登录</h2>
-            <label for="username">用户名</label>
-            <input type="text" id="username" name="username" required>
-            <label for="password">密码</label>
-            <input type="password" id="password" name="password" required>
-            <label for="captcha">验证码</label>
-            <div style="display: flex; align-items: center;">
-                <input type="text" id="captcha" name="captcha" required style="flex: 1;">
-                <span id="captchaText" onclick="refreshCaptcha()" style="margin-left: 10px; cursor: pointer;">点击刷新验证码</span>
+            <div class="login-header">
+                <h2>登入</h2>
             </div>
-            <button type="button" onclick="login()">登录</button>
+            <form class="login-form">
+                <input type="text" id="username" name="username" placeholder="用户名" required>
+                <input type="password" id="password" name="password" placeholder="密码" required>
+                <div class="captcha-container">
+                    <input type="text" id="captcha" name="captcha" placeholder="验证码" required>
+                    <span id="captchaText" onclick="refreshCaptcha()">点击刷新验证码</span>
+                </div>
+                <button type="button" onclick="login()">登录</button>
+            </form>
         </div>
     </div>
 
@@ -250,14 +499,16 @@
             return menuItems;
         }
 
-        function setupDeleteButtons() {
-            const deleteButtons = document.querySelectorAll('.delete-btn');
-            deleteButtons.forEach((button, index) => {
+        function setupMenuDeleteButtons() {
+            const deleteButtons = document.querySelectorAll('.menu-delete-btn');
+            deleteButtons.forEach((button) => {
                 button.addEventListener('click', () => {
                     const row = button.closest('tr');
-                    const index = row.getAttribute('data-index');
-                    console.log(`Deleting menu item at index: ${index}`); // 添加日志输出
-                    deleteMenuItem(index);
+                    const index = parseInt(row.getAttribute('data-index'));
+                    const menuText = row.querySelector('.menu-text').value;
+                    if (confirm(`确定要删除菜单项 "${menuText}" 吗?`)) {
+                        deleteMenuItem(index);
+                    }
                 });
             });
         }
@@ -278,14 +529,14 @@
                         </td>
                         <td>
                             <button type="button" class="action-btn edit-btn">编辑</button>
-                            <button type="button" class="action-btn delete-btn">删除</button>
+                            <button type="button" class="action-btn delete-btn menu-delete-btn">删除</button>
                         </td>
                     </tr>
                 `;
                 tbody.innerHTML += row;
             });
             setupEditButtons();
-            setupDeleteButtons();
+            setupMenuDeleteButtons();
         }
 
         function setMenuItems(items) {
@@ -380,7 +631,7 @@
             const tbody = document.getElementById('adTableBody');
             const newRow = `
                 <tr id="newAdRow">
-                    <td><input type="url" id="newAdUrl" placeholder="广告URL"></td>
+                    <td><input type="url" id="newAdUrl" placeholder="广告图片URL"></td>
                     <td><input type="url" id="newAdLink" placeholder="跳转URL"></td>
                     <td>
                         <button type="button" class="action-btn" onclick="saveNewAd()">保存</button>
@@ -398,11 +649,11 @@
             adImages.forEach((ad, index) => {
                 const row = `
                     <tr data-index="${index}">
-                        <td><input type="url" class="ad-url" value="${ad.url}" disabled></td>
+                        <td><input type="url" class="ad-url" value="${ad.url || ''}" disabled></td>
                         <td><input type="url" class="ad-link" value="${ad.link || ''}" disabled></td>
                         <td>
                             <button type="button" class="action-btn edit-btn">编辑</button>
-                            <button type="button" class="action-btn delete-btn">删除</button>
+                            <button type="button" class="action-btn delete-btn ad-delete-btn">删除</button>
                         </td>
                     </tr>
                 `;
@@ -414,7 +665,7 @@
 
         function setupAdEditButtons() {
             const editButtons = document.querySelectorAll('.edit-btn');
-            editButtons.forEach((button, index) => {
+            editButtons.forEach((button) => {
                 button.addEventListener('click', () => {
                     const row = button.closest('tr');
                     const urlInput = row.querySelector('.ad-url');
@@ -424,44 +675,50 @@
                         urlInput.disabled = false;
                         linkInput.disabled = false;
                         button.textContent = '保存';
-                        editingIndex = row.getAttribute('data-index');
-                        console.log(`Editing ad at index ${editingIndex}:`, { url: urlInput.value, link: linkInput.value });
                     } else {
+                        const index = parseInt(row.getAttribute('data-index'));
                         const url = urlInput.value || '';
                         const link = linkInput.value || '';
 
-                        adImages[editingIndex] = { url, link };
-                        renderAdItems(); // 重新渲染广告项
-                        saveAd(editingIndex, { url, link });
-                        editingIndex = -1;
+                        if (url) {
+                            adImages[index] = { url, link };
+                            saveAd(index, { url, link });
+                            urlInput.disabled = true;
+                            linkInput.disabled = true;
+                            button.textContent = '编辑';
+                        } else {
+                            alert('广告URL不能为空');
+                        }
                     }
                 });
             });
         }
 
         function setupAdDeleteButtons() {
-            const deleteButtons = document.querySelectorAll('.delete-btn');
-            deleteButtons.forEach((button, index) => {
+            const deleteButtons = document.querySelectorAll('.ad-delete-btn');
+            deleteButtons.forEach((button) => {
                 button.addEventListener('click', () => {
                     const row = button.closest('tr');
-                    const index = row.getAttribute('data-index');
-                    deleteAd(index);
+                    const index = parseInt(row.getAttribute('data-index'));
+                    const adUrl = row.querySelector('.ad-url').value;
+                    if (confirm(`确定要删除广告 "${adUrl}" 吗?`)) {
+                        deleteAd(index);
+                    }
                 });
             });
-        }   
+        }
 
         function saveNewAd() {
             const url = document.getElementById('newAdUrl').value || '';
             const link = document.getElementById('newAdLink').value || '';
 
             if (!url) {
-                alert('广告URL为必填项');
+                alert('广告图片URL为必填项');
                 return;
             }
 
             const newAd = { url, link };
             adImages.push(newAd);
-            renderAdItems(); // 先更新页面
             saveAd(adImages.length - 1, newAd);
             cancelNewAd();
         }
@@ -473,26 +730,6 @@
             }
         }
 
-        function renderAdItems() {
-            const tbody = document.getElementById('adTableBody');
-            tbody.innerHTML = '';
-            adImages.forEach((ad, index) => {
-                const row = `
-                    <tr data-index="${index}">
-                        <td><input type="url" class="ad-url" value="${ad.url}" disabled></td>
-                        <td><input type="url" class="ad-link" value="${ad.link}" disabled></td>
-                        <td>
-                            <button type="button" class="action-btn edit-btn">编辑</button>
-                            <button type="button" class="action-btn delete-btn">删除</button>
-                        </td>
-                    </tr>
-                `;
-                tbody.innerHTML += row;
-            });
-            setupAdEditButtons();
-            setupAdDeleteButtons();
-        }
-
         async function saveLogo() {
             const logoUrl = document.getElementById('logoUrl').value;
             if (!logoUrl) {
@@ -529,47 +766,60 @@
 
         async function deleteMenuItem(index) {
             try {
+                menuItems.splice(index, 1);
                 const response = await fetch('/api/config', {
                     method: 'POST',
                     headers: { 'Content-Type': 'application/json' },
-                    body: JSON.stringify({ menuItems: menuItems.filter((_, i) => i !== parseInt(index)) })
+                    body: JSON.stringify({ menuItems: menuItems })
                 });
                 if (response.ok) {
-                    menuItems.splice(index, 1);
-                    renderMenuItems(); // 先更新页面
-                    await loadConfig(); // 重新加载配置
+                    console.log('Menu item deleted successfully');
+                    renderMenuItems(); // 重新渲染菜单项
                 } else {
-                    alert('删除菜单项失败');
+                    throw new Error('Failed to delete menu item');
                 }
             } catch (error) {
-                console.error('删除菜单项失败: ' + error.message);
+                console.error('删除菜单项失败:', error);
                 alert('删除菜单项失败: ' + error.message);
             }
         }
 
         async function saveAd(index, ad) {
             console.log(`Saving ad at index ${index}:`, ad);
-            const config = { adImages: adImages };
-            config.adImages[index] = ad;
-            await saveConfig(config);
+            try {
+                const response = await fetch('/api/config', {
+                    method: 'POST',
+                    headers: { 'Content-Type': 'application/json' },
+                    body: JSON.stringify({ adImages: adImages })
+                });
+                if (response.ok) {
+                    console.log('Ad saved successfully');
+                    renderAdItems(); // 重新渲染广告项
+                } else {
+                    throw new Error('Failed to save ad');
+                }
+            } catch (error) {
+                console.error('保存广告失败:', error);
+                alert('保存广告失败: ' + error.message);
+            }
         }
 
         async function deleteAd(index) {
             try {
+                adImages.splice(index, 1);
                 const response = await fetch('/api/config', {
                     method: 'POST',
                     headers: { 'Content-Type': 'application/json' },
-                    body: JSON.stringify({ adImages: adImages.filter((_, i) => i !== parseInt(index)) })
+                    body: JSON.stringify({ adImages: adImages })
                 });
                 if (response.ok) {
-                    adImages.splice(index, 1);
-                    renderAdItems(); // 先更新页面
-                    await loadConfig(); // 重新加载配置
+                    console.log('Ad deleted successfully');
+                    renderAdItems(); // 重新渲染广告项
                 } else {
-                    alert('删除广告项失败');
+                    throw new Error('Failed to delete ad');
                 }
             } catch (error) {
-                console.error('删除广告项失败: ' + error.message);
+                console.error('删除广告项失败:', error);
                 alert('删除广告项失败: ' + error.message);
             }
         }
@@ -748,6 +998,35 @@
                 console.error('刷新验证码失败:', error);
             }
         }
+
+        document.addEventListener('DOMContentLoaded', function() {
+        const sidebarItems = document.querySelectorAll('.sidebar li');
+        const contentSections = document.querySelectorAll('.content-section');
+
+        function showSection(sectionId) {
+            contentSections.forEach(section => {
+                if (section.id === sectionId) {
+                    section.classList.add('active');
+                } else {
+                    section.classList.remove('active');
+                }
+            });
+        }
+
+        sidebarItems.forEach(item => {
+            item.addEventListener('click', function() {
+                const sectionId = this.getAttribute('data-section');
+                
+                sidebarItems.forEach(si => si.classList.remove('active'));
+                this.classList.add('active');
+                
+                showSection(sectionId);
+            });
+        });
+
+        // 初始化:显示第一个部分
+        showSection(sidebarItems[0].getAttribute('data-section'));
+    });
     </script>
 </body>
 </html>

+ 68 - 23
hubcmdui/web/index.html

@@ -36,20 +36,51 @@
         .logo {
             max-height: 70px;
         }
+        .logo-link {
+            display: inline-block;
+            text-decoration: none;
+        }
+
+        .logo-link:hover {
+            opacity: 0.8;
+            transition: opacity 0.3s ease;
+        }
         .nav-menu {
             display: flex;
-            gap: 20px;
+            gap: 10px;
             font-size: 18px;
             margin-left: auto;
         }
+
         .nav-menu a {
             color: #0366d6;
             text-decoration: none;
             font-weight: 500;
-            transition: color 0.3s;
+            transition: all 0.3s ease;
+            padding: 8px 12px;
+            border-radius: 5px;
+            position: relative;
         }
+
         .nav-menu a:hover {
-            color: #0056b3;
+            color: #0366d6;
+            background-color: rgba(3, 102, 214, 0.1);
+        }
+
+        .nav-menu a::after {
+            content: '';
+            position: absolute;
+            width: 0;
+            height: 2px;
+            bottom: 0;
+            left: 50%;
+            background-color: #0366d6;
+            transition: all 0.3s ease;
+        }
+
+        .nav-menu a:hover::after {
+            width: 100%;
+            left: 0;
         }
         .container {
             max-width: 800px;
@@ -238,32 +269,34 @@
         @media (max-width: 768px) {
             .nav-menu {
                 display: none;
-            }
-            .header-content {
                 flex-direction: column;
-            }
-            .logo {
-                margin-bottom: 10px;
-            }
-            .input-group {
-                flex-direction: column;
-            }
-            .container {
+                position: absolute;
+                top: 100%;
+                left: 0;
                 width: 100%;
-                padding: 10px;
+                background-color: #ffffff;
+                box-shadow: 0 2px 5px rgba(0,0,0,0.1);
+                padding: 10px 0;
             }
-            .carousel {
-                height: 300px;
+
+            .nav-menu.active {
+                display: flex;
             }
-            .carousel-item {
-                width: 80%;
-                height: 70%;
-                left: 10%;
+
+            .nav-menu a {
+                padding: 10px 20px;
+            }
+
+            .menu-toggle {
+                display: block;
+                font-size: 24px;
+                cursor: pointer;
             }
         }
+
         @media (min-width: 769px) {
-            .nav-menu {
-                display: flex;
+            .menu-toggle {
+                display: none;
             }
         }
         .notification {
@@ -287,7 +320,10 @@
     <!-- 页眉 -->
     <header class="header">
         <div class="header-content">
-            <img src="https://cdn.jsdelivr.net/gh/dqzboy/Blog-Image/BlogCourse/docker-proxy.png" alt="Logo" class="logo">
+            <a href="/" class="logo-link">
+                <img src="https://cdn.jsdelivr.net/gh/dqzboy/Blog-Image/BlogCourse/docker-proxy.png" alt="Logo" class="logo">
+            </a>
+            <div class="menu-toggle" id="menuToggle">☰</div>
             <nav class="nav-menu" id="navMenu">
                 <!-- 菜单项将通过 JavaScript 动态加载 -->
             </nav>
@@ -326,6 +362,15 @@
         // 设置当前年份
         document.getElementById('currentYear').textContent = new Date().getFullYear();
 
+        document.addEventListener('DOMContentLoaded', (event) => {
+            const menuToggle = document.getElementById('menuToggle');
+            const navMenu = document.getElementById('navMenu');
+
+            menuToggle.addEventListener('click', () => {
+                navMenu.classList.toggle('active');
+            });
+        });
+        
         let proxyDomain = ''; // 默认代理加速地址
         let currentIndex = 0;
         let items = [];