|
|
本帖最后由 676220229 于 2026-6-20 23:51 编辑
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>OpenWrt 系统监控面板</title>
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
- <style>
- * {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- font-family: "Microsoft YaHei", sans-serif;
- }
- /* 彩色动态渐变背景 */
- body {
- min-height: 100vh;
- background: linear-gradient(-45deg, #0072ff, #00c6ff, #3a1c71, #d76d77);
- background-size: 400% 400%;
- animation: gradientBg 15s ease infinite;
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 40px 20px;
- }
- @keyframes gradientBg {
- 0% { background-position: 0% 50%; }
- 50% { background-position: 100% 50%; }
- 100% { background-position: 0% 50%; }
- }
- .container {
- width: 100%;
- max-width: 1200px;
- }
- .header-card {
- background: rgba(255, 255, 255, 0.15);
- backdrop-filter: blur(12px);
- border-radius: 20px;
- padding: 30px;
- text-align: center;
- color: #fff;
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
- margin-bottom: 30px;
- transition: all 0.3s ease;
- }
- .header-card:hover {
- transform: translateY(-5px);
- box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
- }
- #clock {
- font-size: 48px;
- font-weight: bold;
- margin: 10px 0;
- letter-spacing: 3px;
- }
- .grid-box {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
- gap: 24px;
- }
- .data-card {
- background: rgba(255, 255, 255, 0.15);
- backdrop-filter: blur(12px);
- border-radius: 20px;
- padding: 28px;
- color: #fff;
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
- transition: all 0.3s ease;
- }
- .data-card:hover {
- transform: translateY(-8px);
- box-shadow: 0 15px 45px rgba(0, 0, 0, 0.22);
- }
- .card-title {
- font-size: 16px;
- opacity: 0.9;
- margin-bottom: 16px;
- }
- .card-value {
- font-size: 36px;
- font-weight: 700;
- margin-bottom: 12px;
- }
- .chart-wrap {
- width: 100%;
- height: 160px;
- }
- .ip-text {
- word-break: break-all;
- font-size: 22px;
- }
- .speed-tag {
- display: inline-block;
- padding: 6px 14px;
- border-radius: 30px;
- background: rgba(255,255,255,0.2);
- margin-right: 10px;
- margin-top: 8px;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <!-- 顶部时钟卡片 -->
- <div class="header-card">
- <h1>OpenWrt 系统实时监控面板</h1>
- <div id="clock">00:00:00</div>
- <div id="date"></div>
- </div>
- <div class="grid-box">
- <!-- CPU使用率 -->
- <div class="data-card">
- <div class="card-title">💻 CPU 使用率</div>
- <div class="chart-wrap">
- <canvas id="cpuChart"></canvas>
- </div>
- <div class="card-value" id="cpuRate">0%</div>
- </div>
- <!-- 内存使用率 -->
- <div class="data-card">
- <div class="card-title">🧠 内存使用率</div>
- <div class="chart-wrap">
- <canvas id="memChart"></canvas>
- </div>
- <div class="card-value" id="memRate">0%</div>
- </div>
- <!-- 实时上下行网速 -->
- <div class="data-card">
- <div class="card-title">📶 实时网络速率</div>
- <div class="speed-tag">⬆ 上传:<span id="uploadSpeed">0 KB/s</span></div>
- <div class="speed-tag">⬇ 下载:<span id="downloadSpeed">0 KB/s</span></div>
- </div>
- <!-- 公网IP -->
- <div class="data-card">
- <div class="card-title">🌐 当前公网 IP</div>
- <div class="ip-text" id="publicIp">获取中...</div>
- </div>
- </div>
- </div>
- <script>
- // 1. 实时时钟
- function updateClock() {
- const now = new Date();
- const timeStr = now.toLocaleTimeString('zh-CN', {hour12: false});
- const dateStr = now.toLocaleDateString('zh-CN', {weekday:'long',year:'numeric',month:'long',day:'numeric'});
- document.getElementById('clock').innerText = timeStr;
- document.getElementById('date').innerText = dateStr;
- }
- setInterval(updateClock, 1000);
- updateClock();
- // 2. 初始化环形图表
- const cpuCtx = document.getElementById('cpuChart').getContext('2d');
- const memCtx = document.getElementById('memChart').getContext('2d');
- const cpuChart = new Chart(cpuCtx, {
- type: 'doughnut',
- data: {
- datasets: [{
- data: [0, 100],
- backgroundColor: ['#00c6ff', 'rgba(255,255,255,0.1)'],
- borderWidth: 0
- }]
- },
- options: { cutout: '75%', responsive: true, maintainAspectRatio: false, plugins: {legend: {display:false}} }
- });
- const memChart = new Chart(memCtx, {
- type: 'doughnut',
- data: {
- datasets: [{
- data: [0, 100],
- backgroundColor: ['#ff7675', 'rgba(255,255,255,0.1)'],
- borderWidth: 0
- }]
- },
- options: { cutout: '75%', responsive: true, maintainAspectRatio: false, plugins: {legend: {display:false}} }
- });
- // 3. 读取OpenWrt系统数据
- let lastRx = 0, lastTx = 0;
- const netDev = 'eth0'; // 改成你的WAN网卡,一般eth0/pppoe-wan
- async function getSystemData() {
- try {
- // CPU 负载
- const resCpu = await fetch('/proc/loadavg');
- const loadText = await resCpu.text();
- const cpuLoad = parseFloat(loadText.split(' ')[0]) * 100;
- const cpuPercent = Math.min(Math.round(cpuLoad), 100);
- cpuChart.data.datasets[0].data = [cpuPercent, 100 - cpuPercent];
- cpuChart.update();
- document.getElementById('cpuRate').innerText = cpuPercent + '%';
- // 内存
- const resMem = await fetch('/proc/meminfo');
- const memText = await resMem.text();
- const memTotal = parseInt(memText.match(/MemTotal:\s+(\d+)/)[1]);
- const memFree = parseInt(memText.match(/MemFree:\s+(\d+)/)[1]);
- const memUsed = memTotal - memFree;
- const memPercent = Math.round(memUsed / memTotal * 100);
- memChart.data.datasets[0].data = [memPercent, 100 - memPercent];
- memChart.update();
- document.getElementById('memRate').innerText = memPercent + '%';
- // 网卡流量计算网速
- const resNet = await fetch(`/proc/net/dev`);
- const netText = await resNet.text();
- const match = netText.match(new RegExp(`${netDev}:\\s*(\\d+)\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+(\\d+)`));
- if(match){
- const rx = parseInt(match[1]);
- const tx = parseInt(match[2]);
- if(lastRx !== 0){
- const down = ((rx - lastRx) / 1024).toFixed(2);
- const up = ((tx - lastTx) / 1024).toFixed(2);
- document.getElementById('downloadSpeed').innerText = `${down} KB/s`;
- document.getElementById('uploadSpeed').innerText = `${up} KB/s`;
- }
- lastRx = rx;
- lastTx = tx;
- }
- // 获取公网IP
- if(!document.getElementById('publicIp').innerText.includes('.')){
- const ipRes = await fetch('https://api.ipify.org');
- const pubIp = await ipRes.text();
- document.getElementById('publicIp').innerText = pubIp;
- }
- } catch (err) {
- console.log('数据读取异常:', err);
- }
- }
- // 每1秒刷新一次数据
- setInterval(getSystemData, 1000);
- getSystemData();
- </script>
- </body>
- </html>
复制代码
我用ai重写了openwrt的luci界面,大家看咋样,首页还需要显示哪些信息?对于家用来说,哪些信息足够用了?脱离原生 LuCI 布局,做独立 HTML 大屏首页,支持粒子背景、动态时钟、实时网速跑马灯、数据轮播动画、全屏毛玻璃,它有三种颜色,随背景可变。用的都是最基础的rgb色拼的没有用渲染。不浪费路由器的CPU。通过 AJAX 实时读取 OpenWrt 系统数据。
如如果大家喜欢,我就把源代码贴出来,自己打包成htm文件,用winscp上传到openwrt相应的位置。备份原有 index.html,将上面代码新建保存为 index.html,记住一定要备份,一定要备份。PPPoE 拨号改成:pppoe-wan
光猫桥接网口拨号:eth0、wan 根据自己网卡修改
请大家在应用之前建议先保存成HTML预览一遍,然后再用人工智能跑一遍,让他们嗯,提提意见。提提意见。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|