Explorar el Código

页面样式和通知修改

Taio_O hace 1 semana
padre
commit
1833adfa4b
Se han modificado 6 ficheros con 157 adiciones y 155 borrados
  1. 70 100
      public/app.js
  2. 12 17
      public/index.html
  3. 69 5
      public/styles.css
  4. 1 2
      src/core/clashParser.js
  5. 3 12
      src/core/notifier.js
  6. 2 19
      src/core/scheduler.js

+ 70 - 100
public/app.js

@@ -149,14 +149,6 @@ function updateRecentResults(results) {
                         <i class="bi bi-speedometer2"></i>
                         延迟: ${result.latency}ms
                     </div>
-                    <div class="result-detail">
-                        <i class="bi bi-download"></i>
-                        下载: ${formatSpeed(result.downloadSpeed)}
-                    </div>
-                    <div class="result-detail">
-                        <i class="bi bi-upload"></i>
-                        上传: ${formatSpeed(result.uploadSpeed)}
-                    </div>
                 ` : `
                     <div class="result-detail">
                         <i class="bi bi-exclamation-triangle"></i>
@@ -171,19 +163,16 @@ function updateRecentResults(results) {
 }
 
 // 加载节点列表
-async function loadNodes(page = 1) {
+async function loadNodes() {
     try {
         showLoading();
         
         const search = document.getElementById('node-search')?.value || '';
-        const group = document.getElementById('group-filter')?.value || '';
         const status = document.getElementById('status-filter')?.value || '';
         
         const params = new URLSearchParams({
-            page: page,
-            limit: 20,
+            limit: 1000, // 设置一个很大的限制,获取所有节点
             ...(search && { search }),
-            ...(group && { group }),
             ...(status && { status })
         });
         
@@ -192,7 +181,6 @@ async function loadNodes(page = 1) {
         
         if (data.success) {
             updateNodesList(data.data);
-            currentNodesPage = page;
         }
         
         hideLoading();
@@ -209,59 +197,60 @@ function updateNodesList(data) {
     const { nodes, pagination } = data;
     
     if (nodes.length === 0) {
-        container.innerHTML = '<div class="text-center text-muted">暂无节点</div>';
+        container.innerHTML = '<div class="row"><div class="col-12"><div class="text-center text-muted">暂无节点</div></div></div>';
         return;
     }
     
-    const html = nodes.map(node => `
-        <div class="node-item">
-            <div class="node-header">
-                <div class="node-name">${node.name}</div>
-                <div class="node-status ${node.status}">${node.status === 'online' ? '在线' : '离线'}</div>
-            </div>
-            <div class="node-info">
-                <div class="node-info-item">
-                    <i class="bi bi-hdd-network"></i>
-                    类型: ${node.type}
-                </div>
-                <div class="node-info-item">
-                    <i class="bi bi-geo-alt"></i>
-                    服务器: ${node.server}
+    const html = '<div class="row">' + nodes.map((node, index) => `
+        <div class="col-md-6 mb-3">
+            <div class="node-item">
+                <div class="node-header">
+                    <div class="node-name">${node.name}</div>
+                    <div class="node-status ${node.status}">${node.status === 'online' ? '在线' : '离线'}</div>
                 </div>
-                <div class="node-info-item">
-                    <i class="bi bi-arrow-left-right"></i>
-                    端口: ${node.port}
-                </div>
-                <div class="node-info-item">
-                    <i class="bi bi-tags"></i>
-                    分组: ${node.group || '默认'}
-                </div>
-                ${node.testResults && node.testResults.length > 0 ? `
+                <div class="node-info">
                     <div class="node-info-item">
-                        <i class="bi bi-clock"></i>
-                        最后测速: ${formatTime(node.testResults[0].testTime)}
+                        <i class="bi bi-hdd-network"></i>
+                        类型: ${node.type}
                     </div>
-                ` : ''}
-            </div>
-            <div class="mt-2">
-                <button class="btn btn-sm btn-outline-primary" onclick="viewNodeDetail(${node.id})">
-                    <i class="bi bi-eye"></i> 详情
-                </button>
-                <button class="btn btn-sm btn-outline-success" onclick="testSingleNode(${node.id})">
-                    <i class="bi bi-speedometer"></i> 测速
-                </button>
+                    <div class="node-info-item">
+                        <i class="bi bi-geo-alt"></i>
+                        服务器: ${node.server}
+                    </div>
+                    <div class="node-info-item">
+                        <i class="bi bi-arrow-left-right"></i>
+                        端口: ${node.port}
+                    </div>
+
+                    ${node.testResults && node.testResults.length > 0 ? `
+                        <div class="node-info-item last-test">
+                            <i class="bi bi-clock"></i>
+                            最后测速: ${formatTime(node.testResults[0].testTime)}
+                            ${node.testResults[0].isSuccess ? `
+                                <span class="latency-separator">|</span>
+                                <i class="bi bi-speedometer2"></i>
+                                延迟: <span class="latency-value">${node.testResults[0].latency}ms</span>
+                            ` : ''}
+                        </div>
+                    ` : ''}
+                </div>
+                <div class="mt-2">
+                    <button class="btn btn-sm btn-outline-primary" onclick="viewNodeDetail(${node.id})">
+                        <i class="bi bi-eye"></i> 详情
+                    </button>
+                    <button class="btn btn-sm btn-outline-success" onclick="testSingleNode(${node.id})">
+                        <i class="bi bi-speedometer"></i> 测速
+                    </button>
+                </div>
             </div>
         </div>
-    `).join('');
+    `).join('') + '</div>';
     
     container.innerHTML = html;
-    
-    // 更新分页
-    updatePagination('nodes-pagination', pagination, loadNodes);
 }
 
 // 加载测速结果
-async function loadTestResults(page = 1) {
+async function loadTestResults() {
     try {
         showLoading();
         
@@ -271,8 +260,7 @@ async function loadTestResults(page = 1) {
         const endDate = document.getElementById('end-date')?.value || '';
         
         const params = new URLSearchParams({
-            page: page,
-            limit: 20,
+            limit: 1000, // 设置一个很大的限制,获取所有结果
             ...(nodeId && { nodeId }),
             ...(isSuccess && { isSuccess }),
             ...(startDate && { startDate }),
@@ -284,7 +272,6 @@ async function loadTestResults(page = 1) {
         
         if (data.success) {
             updateTestResults(data.data);
-            currentResultsPage = page;
         }
         
         hideLoading();
@@ -301,48 +288,39 @@ function updateTestResults(data) {
     const { results, pagination } = data;
     
     if (results.length === 0) {
-        container.innerHTML = '<div class="text-center text-muted">暂无测速结果</div>';
+        container.innerHTML = '<div class="row"><div class="col-12"><div class="text-center text-muted">暂无测速结果</div></div></div>';
         return;
     }
     
-    const html = results.map(result => `
-        <div class="result-item ${result.isSuccess ? 'result-success' : 'result-failure'}">
-            <div class="result-header">
-                <div class="result-node">${result.node ? result.node.name : '未知节点'}</div>
-                <div class="result-time">${formatTime(result.testTime)}</div>
-            </div>
-            <div class="result-details">
-                <div class="result-detail">
-                    <i class="bi ${result.isSuccess ? 'bi-check-circle text-success' : 'bi-x-circle text-danger'}"></i>
-                    状态: ${result.isSuccess ? '成功' : '失败'}
+    const html = '<div class="row">' + results.map((result, index) => `
+        <div class="col-md-6 mb-3">
+            <div class="result-item ${result.isSuccess ? 'result-success' : 'result-failure'}">
+                <div class="result-header">
+                    <div class="result-node">${result.node ? result.node.name : '未知节点'}</div>
+                    <div class="result-time">${formatTime(result.testTime)}</div>
                 </div>
-                ${result.isSuccess ? `
-                    <div class="result-detail">
-                        <i class="bi bi-speedometer2"></i>
-                        延迟: ${result.latency}ms
-                    </div>
-                    <div class="result-detail">
-                        <i class="bi bi-download"></i>
-                        下载: ${formatSpeed(result.downloadSpeed)}
-                    </div>
-                    <div class="result-detail">
-                        <i class="bi bi-upload"></i>
-                        上传: ${formatSpeed(result.uploadSpeed)}
-                    </div>
-                ` : `
+                <div class="result-details">
                     <div class="result-detail">
-                        <i class="bi bi-exclamation-triangle"></i>
-                        错误: ${result.error || '未知错误'}
+                        <i class="bi ${result.isSuccess ? 'bi-check-circle text-success' : 'bi-x-circle text-danger'}"></i>
+                        状态: ${result.isSuccess ? '成功' : '失败'}
                     </div>
-                `}
+                    ${result.isSuccess ? `
+                        <div class="result-detail">
+                            <i class="bi bi-speedometer2"></i>
+                            延迟: ${result.latency}ms
+                        </div>
+                    ` : `
+                        <div class="result-detail">
+                            <i class="bi bi-exclamation-triangle"></i>
+                            错误: ${result.error || '未知错误'}
+                        </div>
+                    `}
+                </div>
             </div>
         </div>
-    `).join('');
+    `).join('') + '</div>';
     
     container.innerHTML = html;
-    
-    // 更新分页
-    updatePagination('results-pagination', pagination, loadTestResults);
 }
 
 // 加载通知记录
@@ -576,12 +554,12 @@ async function showSystemStatus() {
 
 // 搜索节点
 function searchNodes() {
-    loadNodes(1);
+    loadNodes();
 }
 
 // 搜索结果
 function searchResults() {
-    loadTestResults(1);
+    loadTestResults();
 }
 
 // 导入节点
@@ -679,7 +657,7 @@ async function viewNodeDetail(nodeId) {
                             <tr><td>类型:</td><td>${node.type}</td></tr>
                             <tr><td>服务器:</td><td>${node.server}</td></tr>
                             <tr><td>端口:</td><td>${node.port}</td></tr>
-                            <tr><td>分组:</td><td>${node.group || '默认'}</td></tr>
+
                             <tr><td>状态:</td><td><span class="badge ${node.status === 'online' ? 'bg-success' : 'bg-danger'}">${node.status === 'online' ? '在线' : '离线'}</span></td></tr>
                         </table>
                     </div>
@@ -700,14 +678,6 @@ async function viewNodeDetail(nodeId) {
                                             <i class="bi bi-speedometer2"></i>
                                             延迟: ${node.testResults[0].latency}ms
                                         </div>
-                                        <div class="result-detail">
-                                            <i class="bi bi-download"></i>
-                                            下载: ${formatSpeed(node.testResults[0].downloadSpeed)}
-                                        </div>
-                                        <div class="result-detail">
-                                            <i class="bi bi-upload"></i>
-                                            上传: ${formatSpeed(node.testResults[0].uploadSpeed)}
-                                        </div>
                                     ` : `
                                         <div class="result-detail">
                                             <i class="bi bi-exclamation-triangle"></i>

+ 12 - 17
public/index.html

@@ -201,15 +201,10 @@
                     <div class="card">
                         <div class="card-body">
                             <div class="row">
-                                <div class="col-md-4">
+                                <div class="col-md-5">
                                     <input type="text" class="form-control" id="node-search" placeholder="搜索节点名称或服务器...">
                                 </div>
-                                <div class="col-md-2">
-                                    <select class="form-select" id="group-filter">
-                                        <option value="">所有分组</option>
-                                    </select>
-                                </div>
-                                <div class="col-md-2">
+                                <div class="col-md-3">
                                     <select class="form-select" id="status-filter">
                                         <option value="">所有状态</option>
                                         <option value="online">在线</option>
@@ -241,13 +236,13 @@
                         </div>
                         <div class="card-body">
                             <div id="nodes-list">
-                                <div class="text-center text-muted">
-                                    <i class="bi bi-hourglass-split"></i> 加载中...
+                                <div class="row">
+                                    <div class="text-center text-muted">
+                                        <i class="bi bi-hourglass-split"></i> 加载中...
+                                    </div>
                                 </div>
                             </div>
-                            <!-- 分页 -->
-                            <nav aria-label="节点分页" id="nodes-pagination">
-                            </nav>
+
                         </div>
                     </div>
                 </div>
@@ -307,13 +302,13 @@
                         </div>
                         <div class="card-body">
                             <div id="test-results">
-                                <div class="text-center text-muted">
-                                    <i class="bi bi-hourglass-split"></i> 加载中...
+                                <div class="row">
+                                    <div class="text-center text-muted">
+                                        <i class="bi bi-hourglass-split"></i> 加载中...
+                                    </div>
                                 </div>
                             </div>
-                            <!-- 分页 -->
-                            <nav aria-label="结果分页" id="results-pagination">
-                            </nav>
+
                         </div>
                     </div>
                 </div>

+ 69 - 5
public/styles.css

@@ -18,6 +18,36 @@ body {
     min-height: calc(100vh - 100px);
 }
 
+/* 主容器样式 - 添加左右内边距 */
+.container-fluid {
+    max-width: 1400px;
+    margin: 0 auto;
+    padding-left: 2rem;
+    padding-right: 2rem;
+}
+
+/* 响应式内边距 */
+@media (max-width: 1200px) {
+    .container-fluid {
+        padding-left: 1.5rem;
+        padding-right: 1.5rem;
+    }
+}
+
+@media (max-width: 768px) {
+    .container-fluid {
+        padding-left: 1rem;
+        padding-right: 1rem;
+    }
+}
+
+@media (max-width: 576px) {
+    .container-fluid {
+        padding-left: 0.75rem;
+        padding-right: 0.75rem;
+    }
+}
+
 /* 统计卡片 */
 .stat-card {
     border: none;
@@ -67,14 +97,17 @@ body {
 
 .node-header {
     display: flex;
-    justify-content: between;
+    justify-content: space-between;
     align-items: center;
     margin-bottom: 10px;
+    gap: 12px;
 }
 
 .node-name {
     font-weight: 600;
     color: #333;
+    flex: 1;
+    margin-right: 8px;
 }
 
 .node-status {
@@ -96,20 +129,45 @@ body {
 
 .node-info {
     display: grid;
-    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
+    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
     gap: 10px;
-    font-size: 0.9rem;
+    font-size: 0.85rem;
     color: #666;
 }
 
+.node-info-item.last-test {
+    grid-column: 1 / -1;
+    padding-top: 0;
+}
+
+.latency-info {
+    font-weight: 500;
+}
+
+.latency-value {
+    margin-left: 4px;
+    font-weight: 600;
+    color: #007bff;
+}
+
+.latency-separator {
+    margin: 0 8px;
+    color: #ccc;
+    font-weight: normal;
+}
+
 .node-info-item {
     display: flex;
     align-items: center;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
 }
 
 .node-info-item i {
-    margin-right: 5px;
-    width: 16px;
+    margin-right: 4px;
+    width: 14px;
+    flex-shrink: 0;
 }
 
 /* 测速结果样式 */
@@ -277,6 +335,8 @@ body {
 @media (max-width: 768px) {
     .node-info {
         grid-template-columns: 1fr;
+        gap: 6px;
+        font-size: 0.8rem;
     }
     
     .result-details {
@@ -286,6 +346,10 @@ body {
     .stat-card {
         margin-bottom: 15px;
     }
+    
+    .node-info-item {
+        white-space: normal;
+    }
 }
 
 /* 动画效果 */

+ 1 - 2
src/core/clashParser.js

@@ -49,8 +49,7 @@ class ClashParser {
         name: proxy.name,
         type: proxy.type,
         server: proxy.server,
-        port: parseInt(proxy.port),
-        group: proxy.group || 'default'
+        port: parseInt(proxy.port)
       };
 
       switch (proxy.type) {

+ 3 - 12
src/core/notifier.js

@@ -220,7 +220,6 @@ class TelegramNotifier {
       `*节点名称:* ${node.name}`,
       `*节点类型:* ${node.type}`,
       `*服务器:* ${node.server}:${node.port}`,
-      `*分组:* ${node.group || '默认'}`,
       `*连续失败次数:* ${node.failureCount}`,
       `*最后测试时间:* ${new Date().toLocaleString('zh-CN')}`
     ];
@@ -244,7 +243,6 @@ class TelegramNotifier {
       `*节点名称:* ${node.name}`,
       `*节点类型:* ${node.type}`,
       `*服务器:* ${node.server}:${node.port}`,
-      `*分组:* ${node.group || '默认'}`,
       `*恢复时间:* ${new Date().toLocaleString('zh-CN')}`
     ];
 
@@ -285,27 +283,20 @@ class TelegramNotifier {
       lines.push(`*平均速度:* ${summary.averageSpeed} Mbps`);
     }
 
-    // 按分组显示统计
-    if (summary.groupStats && Object.keys(summary.groupStats).length > 0) {
-      lines.push(`\n📈 *分组统计:*`);
-      Object.entries(summary.groupStats).forEach(([group, stats]) => {
-        const groupSuccessRate = stats.total > 0 ? Math.round((stats.online / stats.total) * 100) : 0;
-        lines.push(`• ${group}: ${stats.online}/${stats.total} (${groupSuccessRate}%)`);
-      });
-    }
+
 
     if (summary.bestNodes && summary.bestNodes.length > 0) {
       lines.push(`\n🏆 *最佳节点 (延迟排序):*`);
       summary.bestNodes.forEach((node, index) => {
         const medal = index === 0 ? '🥇' : index === 1 ? '🥈' : index === 2 ? '🥉' : '•';
-        lines.push(`${medal} ${node.name} - ${node.latency}ms (${node.group})`);
+        lines.push(`${medal} ${node.name} - ${node.latency}ms`);
       });
     }
 
     if (summary.failedNodes && summary.failedNodes.length > 0) {
       lines.push(`\n❌ *故障节点:*`);
       summary.failedNodes.forEach(node => {
-        lines.push(`• ${node.name} (${node.group})`);
+        lines.push(`• ${node.name}`);
       });
     }
 

+ 2 - 19
src/core/scheduler.js

@@ -209,27 +209,11 @@ class Scheduler {
         const node = nodes.find(n => n.id === result.nodeId);
         return {
           name: node ? node.name : 'Unknown',
-          latency: result.latency,
-          group: node ? node.group : 'Unknown'
+          latency: result.latency
         };
       });
 
-    // 按分组统计
-    const groupStats = {};
-    nodes.forEach(node => {
-      const group = node.group || '默认';
-      if (!groupStats[group]) {
-        groupStats[group] = { total: 0, online: 0, offline: 0 };
-      }
-      groupStats[group].total++;
-      
-      const result = testResults.find(r => r.nodeId === node.id);
-      if (result && result.isSuccess) {
-        groupStats[group].online++;
-      } else {
-        groupStats[group].offline++;
-      }
-    });
+
 
     const summary = {
       totalNodes,
@@ -240,7 +224,6 @@ class Scheduler {
       averageSpeed,
       failedNodes,
       bestNodes,
-      groupStats,
       testTime: new Date().toLocaleString('zh-CN')
     };