update all

This commit is contained in:
cppla 2024-08-17 17:31:40 +08:00
parent 705a957606
commit b3adc6b782
11 changed files with 603 additions and 271 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,48 +1,168 @@
body { background: #212e36 url('../img/dark.png'); color: #dcdcdc; } body {
.navbar { min-height: 40px; } background: #212e36 url('../img/dark.png') repeat;
.navbar-brand { color: #FFF !important; padding: 10px; font-size: 20px; } color: #dcdcdc;
.dropdown .dropdown-toggle { padding-bottom: 10px; padding-top: 10px; } font-size: 15px;
.dropdown-menu > li > a { color: #FFF !important; background-color: #222222 !important; } padding-top: 70px;
.dropdown-menu > li > a:hover { color: #FFF !important; background: #000 !important; } padding-bottom: 30px;
.dropdown-menu { background: #222 !important; background-color: #222222 !important; } }
.navbar-inverse .navbar-inner { background-color:#1B1B1B; background-image:-moz-linear-gradient(top, #222222, #111111); background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); background-image:-webkit-linear-gradient(top, #222222, #111111); background-image:-o-linear-gradient(top, #222222, #111111); background-image:linear-gradient(to bottom, #212e36, #212e36); background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); border-color: #252525; }
.content { background: #212e36; padding: 20px; border-radius: 5px; border: 1px #212e36 solid; -webkit-box-shadow: 0 0px 0px rgba(0, 0, 0, 0); -moz-box-shadow: 0 0px 0px rgba(0, 0, 0, 0); box-shadow: 0 0px 0px rgba(0, 0, 0, 0); margin-bottom: 20px; } .navbar {
.table { background: #363b40; margin-bottom: 0; border-collapse: collapse; border-radius: 3px; } min-height: 40px;
.table th { text-align: center; } background-color: #1B1B1B;
.table-striped tbody > tr.even > td, .table-striped tbody > tr.even > th { background-color: #212e36; } }
.table-striped tbody > tr.odd > td, .table-striped tbody > tr.odd > th { background-color: #212e36; }
.table td { text-align: center; border-color: #2F2F2F; } .navbar-brand {
.progress { margin-bottom: 0; background: #363b40; } color: #FFF !important;
.table-hover > tbody > tr:hover > td { background: #414141; } padding: 10px;
tr.even.expandRow > :hover { background: #212e36 !important; } font-size: 20px;
tr.odd.expandRow > :hover { background: #212e36 !important; } }
.expandRow > td { padding: 0 !important; border-top: 0px !important; }
#month_traffic { min-width: 85px; max-width: 95px;} .dropdown .dropdown-toggle {
#network { min-width: 138px; } padding-bottom: 10px;
#cpu, #ram, #hdd { min-width: 45px; max-width: 90px; } padding-top: 10px;
#ping { max-width: 115px; } }
.dropdown-menu > li > a {
color: #FFF !important;
background-color: #222222 !important;
}
.dropdown-menu > li > a:hover {
color: #FFF !important;
background: #000 !important;
}
.dropdown-menu {
background: #222 !important;
background-color: #222222 !important;
}
.navbar-inverse .navbar-inner {
background-color: #1B1B1B;
background-image: linear-gradient(to bottom, #212e36, #212e36);
background-repeat: repeat-x;
border-color: #252525;
}
.content {
background: #212e36;
padding: 20px;
border-radius: 5px;
border: 1px solid #212e36;
box-shadow: 0 0px 0px rgba(0, 0, 0, 0);
margin-bottom: 20px;
}
.table {
background-color: #212e36 !important;
margin-bottom: 0;
border-collapse: collapse;
border-radius: 3px;
width: 100%;
}
.table th, .table td {
background-color: #212e36 !important;
color: #dcdcdc !important;
text-align: center;
padding: 8px;
}
.table-striped tbody tr:nth-child(even) {
background-color: #212e36;
}
.table-striped tbody tr:nth-child(odd) {
background-color: #212e36;
}
.progress {
margin-bottom: 0;
background: #363b40;
}
.progress-bar {
overflow: visible;
}
.table-hover tbody tr:hover td {
background: #414141;
}
tr.even.expandRow:hover {
background: #212e36 !important;
}
tr.odd.expandRow:hover {
background: #212e36 !important;
}
.expandRow td {
padding: 0 !important;
border-top: 0 !important;
}
#month_traffic {
width: 130px;
}
#network {
width: 138px;
}
#cpu, #ram, #hdd {
width: 90px;
}
#ping {
width: 115px;
}
@media only screen and (max-width: 1200px) { @media only screen and (max-width: 1200px) {
#type { display:none; visibility:hidden; } #type, #location, #uptime, #ping {
#location, tr td:nth-child(5) { display:none; visibility:hidden; } display: none;
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; } visibility: hidden;
#ping, tr td:nth-child(13) { display:none; visibility:hidden; } }
} }
@media only screen and (max-width: 720px) { @media only screen and (max-width: 720px) {
body { font-size: 10px; } body {
.content { padding: 0; } font-size: 10px;
#type { display:none; visibility:hidden; } }
#location, tr td:nth-child(5) { display:none; visibility:hidden; } .content {
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; } padding: 0;
#ping, tr td:nth-child(13) { display:none; visibility:hidden; } }
#cpu, #ram, #hdd {
width: 50px;
}
#month_traffic, #type, #location, #uptime, #ping {
display: none;
visibility: hidden;
}
} }
@media only screen and (max-width: 620px) { @media only screen and (max-width: 620px) {
body { font-size: 10px; } body {
.content { padding: 0; } font-size: 10px;
#month_traffic { display:none; visibility:hidden; } }
#type { display:none; visibility:hidden; } .content {
#location, tr td:nth-child(5) { display:none; visibility:hidden; } padding: 0;
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; } }
#traffic, tr td:nth-child(9) { display:none; visibility:hidden; } #cpu, #ram, #hdd {
#ping, tr td:nth-child(13) { display:none; visibility:hidden; } width: 50px;
}
#month_traffic, #type, #location, #uptime, #traffic, #ping {
display: none;
visibility: hidden;
}
} }
.navbar-nav .nav-link {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
line-height: 1.5;
}
.navbar-nav .dropdown-toggle::after {
vertical-align: 0.15em;
}

@ -1,45 +1,149 @@
body { background: #ebebeb url('../img/light.png'); } body {
.navbar { min-height: 40px; } background: #ebebeb url('../img/light.png') repeat;
.navbar-brand { color: #fff; padding: 10px; font-size: 20px; } font-size: 15px;
.dropdown .dropdown-toggle { padding-bottom: 10px; padding-top: 10px; } padding-top: 70px;
.navbar-inverse .navbar-brand { color: #fff; padding: 10px; font-size: 20px; } padding-bottom: 30px;
.content { background: #ffffff; padding: 20px; border-radius: 5px; border: 1px #cecece solid; -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, .1); -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, .1); box-shadow: 0 1px 10px rgba(0, 0, 0, .1); margin-bottom: 20px; } }
.table { background: #ffffff; margin-bottom: 0; border-collapse: collapse; border-radius: 3px; }
.table th, .table td { text-align: center; } .navbar {
.table-striped tbody > tr.even > td, .table-striped tbody > tr.even > th { background-color: #F9F9F9; } min-height: 40px;
.table-striped tbody > tr.odd > td, .table-striped tbody > tr.odd > th { background-color: #FFF; } background-color: #333;
.progress { margin-bottom: 0; } }
.progress-bar { color: #000; }
.table-hover > tbody > tr:hover > td { background: #E6E6E6; } .navbar-brand {
tr.even.expandRow > :hover { background: #F9F9F9 !important; } color: #fff;
tr.odd.expandRow > :hover { background: #FFF !important; } padding: 10px;
.expandRow > td { padding: 0 !important; border-top: 0px !important; } font-size: 20px;
#month_traffic { min-width: 85px; max-width: 95px;} }
#network { width: 138px; }
#cpu, #ram, #hdd { min-width: 45px; max-width: 90px; } .dropdown .dropdown-toggle {
#ping { max-width: 115px; } padding-bottom: 10px;
padding-top: 10px;
}
.navbar-inverse .navbar-brand {
color: #fff;
padding: 10px;
font-size: 20px;
}
.content {
background: #ffffff;
padding: 20px;
border-radius: 5px;
border: 1px solid #cecece;
box-shadow: 0 1px 10px rgba(0, 0, 0, .1);
margin-bottom: 20px;
}
.table {
background: #ffffff;
margin-bottom: 0;
border-collapse: collapse;
border-radius: 3px;
width: 100%;
}
.table th, .table td {
text-align: center;
padding: 8px;
}
.table-striped tbody tr:nth-child(even) {
background-color: #F9F9F9;
}
.table-striped tbody tr:nth-child(odd) {
background-color: #FFF;
}
.progress {
margin-bottom: 0;
}
.progress-bar {
color: #000;
overflow: visible;
}
.table-hover tbody tr:hover td {
background: #E6E6E6;
}
tr.even.expandRow:hover {
background: #F9F9F9 !important;
}
tr.odd.expandRow:hover {
background: #FFF !important;
}
.expandRow td {
padding: 0 !important;
border-top: 0 !important;
}
#month_traffic {
width: 130px;
}
#network {
width: 138px;
}
#cpu, #ram, #hdd {
width: 90px;
}
#ping {
width: 115px;
}
@media only screen and (max-width: 1200px) { @media only screen and (max-width: 1200px) {
#type { display:none; visibility:hidden; } #type, #location, #uptime, #ping {
#location, tr td:nth-child(5) { display:none; visibility:hidden; } display: none;
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; } visibility: hidden;
#ping, tr td:nth-child(13) { display:none; visibility:hidden; } }
} }
@media only screen and (max-width: 720px) { @media only screen and (max-width: 720px) {
body { font-size: 10px; } body {
.content { padding: 0; } font-size: 10px;
#type { display:none; visibility:hidden; } }
#location, tr td:nth-child(5) { display:none; visibility:hidden; } .content {
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; } padding: 0;
#ping, tr td:nth-child(13) { display:none; visibility:hidden; } }
#cpu, #ram, #hdd {
width: 50px;
}
#month_traffic, #type, #location, #uptime, #ping {
display: none;
visibility: hidden;
}
} }
@media only screen and (max-width: 620px) { @media only screen and (max-width: 620px) {
body { font-size: 10px; } body {
.content { padding: 0; } font-size: 10px;
#month_traffic { display:none; visibility:hidden; } }
#type { display:none; visibility:hidden; } .content {
#location, tr td:nth-child(5) { display:none; visibility:hidden; } padding: 0;
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; } }
#traffic, tr td:nth-child(9) { display:none; visibility:hidden; } #cpu, #ram, #hdd {
#ping, tr td:nth-child(13) { display:none; visibility:hidden; } width: 50px;
}
#month_traffic, #type, #location, #uptime, #traffic, #ping {
display: none;
visibility: hidden;
}
}
.navbar-nav .nav-link {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
line-height: 1.5;
}
.navbar-nav .dropdown-toggle::after {
vertical-align: 0.15em;
} }

@ -4,41 +4,35 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="云监控,ServerStatus中文版,ServerStatus,ServerStatus cppla"> <meta name="description" content="云监控,ServerStatus中文版,ServerStatus,ServerStatus cppla">
<meta name="author" content="ServerStatus"> <meta name="author" content="ServerStatus Theme by AI">
<title>云监控</title> <title>云监控</title>
<link rel="stylesheet" href="css/bootstrap.min.css"> <link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/bootstrap-theme.min.css">
<link rel="stylesheet" href="css/light.css" title="light"> <link rel="stylesheet" href="css/light.css" title="light">
<link rel="stylesheet" href="css/dark.css" title="dark"> <link rel="stylesheet" href="css/dark.css" title="dark">
<style>
body {
padding-top: 70px;
padding-bottom: 30px;
}
</style>
</head> </head>
<body> <body>
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation"> <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top" role="navigation">
<div class="container"> <div class="container">
<div class="navbar-header"> <a class="navbar-brand" href="#">云监控</a>
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="sr-only">Toggle navigation</span> <span class="navbar-toggler-icon"></span>
<span class="icon-bar"></span> </button>
<span class="icon-bar"></span> <div class="collapse navbar-collapse" id="navbarNav">
<span class="icon-bar"></span> <ul class="navbar-nav">
</button> <li class="nav-item">
<a class="navbar-brand" href="#">云监控</a> <a class="nav-link" href="#server" data-bs-toggle="tab">首页</a>
</div> </li>
<div class="navbar-collapse collapse"> <li class="nav-item">
<ul class="nav navbar-nav"> <a class="nav-link" href="#monitor" data-bs-toggle="tab">服务</a>
<li><a href="#server" data-toggle="tab">首页</a></li> </li>
<li><a href="#monitor" data-toggle="tab">服务</a></li> <li class="nav-item dropdown">
<li> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<a href="#" data-toggle="dropdown">风格 <b class="caret"></b></a> 风格
<ul class="dropdown-menu"> </a>
<li><a href="#" onclick="setActiveStyleSheet('dark', true)">黑夜</a></li> <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a href="#" onclick="setActiveStyleSheet('light', true)">白天</a></li> <li><a class="dropdown-item" href="#" onclick="setActiveStyleSheet('dark', true)">黑夜</a></li>
<li><a href="/index3.html">简洁</a></li> <li><a class="dropdown-item" href="#" onclick="setActiveStyleSheet('light', true)">白天</a></li>
<li><a class="dropdown-item" href="/index3.html">简洁</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -58,9 +52,9 @@
</div> </div>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane fade in active" id="server"> <div class="tab-pane fade show active" id="server">
<!--主机--> <!--主机-->
<table class="table table-striped table-condensed table-hover"> <table class="table table-striped table-hover">
<thead> <thead>
<tr> <tr>
<th id="online_status" style="text-align: center;">🔗协议</th> <th id="online_status" style="text-align: center;">🔗协议</th>
@ -85,7 +79,7 @@
</div> </div>
<div class="tab-pane fade" id="monitor"> <div class="tab-pane fade" id="monitor">
<!--服务--> <!--服务-->
<table class="table table-striped table-condensed table-hover"> <table class="table table-striped table-hover">
<thead> <thead>
<tr> <tr>
<th id="monitor_status" style="text-align: center;">🔗协议</th> <th id="monitor_status" style="text-align: center;">🔗协议</th>
@ -111,8 +105,7 @@
</p> </p>
</footer> </footer>
<script src="js/jquery.min.js"></script> <script src="js/bootstrap.bundle.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/serverstatus.js"></script> <script src="js/serverstatus.js"></script>
</body> </body>
</html> </html>

7
web/js/bootstrap.bundle.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -19,163 +19,272 @@ function bytesToSize(bytes, precision, si = false) {
} }
function uptime() { function uptime() {
$.getJSON("json/stats.json", function(result) { fetch("json/stats.json")
$("#loading-notice").remove(); .then(response => {
if (result.reload) setTimeout(location.reload, 1000); if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
result.servers.forEach((server, i) => {
let TableRow = $("#servers tr#r" + i);
let MableRow = $("#monitors tr#r" + i);
let ExpandRow = $("#servers #rt" + i);
let hack = i % 2 ? "odd" : "even";
if (!TableRow.length) {
$("#servers").append(
`<tr id="r${i}" data-toggle="collapse" data-target="#rt${i}" class="accordion-toggle ${hack}">
<td id="online_status"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td>
<td id="month_traffic"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td>
<td id="name">加载中</td>
<td id="type">加载中</td>
<td id="location">加载中</td>
<td id="uptime">加载中</td>
<td id="load">加载中</td>
<td id="network">加载中</td>
<td id="traffic">加载中</td>
<td id="cpu"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td>
<td id="memory"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td>
<td id="hdd"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td>
<td id="ping"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td>
</tr>
<tr class="expandRow ${hack}"><td colspan="16"><div class="accordian-body collapse" id="rt${i}">
<div id="expand_mem">加载中</div>
<div id="expand_hdd">加载中</div>
<div id="expand_tupd">加载中</div>
<div id="expand_ping">加载中</div>
</div></td></tr>`
);
TableRow = $("#servers tr#r" + i);
ExpandRow = $("#servers #rt" + i);
server_status[i] = true;
} }
return response.json();
})
.then(result => {
document.getElementById("loading-notice")?.remove();
if (result.reload) setTimeout(location.reload, 1000);
if (!MableRow.length) { result.servers.forEach((server, i) => {
$("#monitors").append( let TableRow = document.querySelector(`#servers tr#r${i}`);
`<tr id="r${i}" data-target="#rt${i}" class="accordion-toggle ${hack}"> let MableRow = document.querySelector(`#monitors tr#r${i}`);
<td id="monitor_status"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td> let ExpandRow = document.querySelector(`#servers #rt${i}`);
<td id="monitor_node">加载中</td> let hack = i % 2 ? "odd" : "even";
<td id="monitor_location">加载中</td>
<td id="monitor_text">加载中</td>
</tr>`
);
MableRow = $("#monitors tr#r" + i);
}
if (error) { if (!TableRow) {
TableRow.attr("data-target", "#rt" + i); document.getElementById("servers").insertAdjacentHTML(
MableRow.attr("data-target", "#rt" + i); "beforeend",
server_status[i] = true; `<tr id="r${i}" data-bs-toggle="collapse" data-bs-target="#rt${i}" class="accordion-toggle ${hack}">
} <td id="online_status"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td>
<td id="month_traffic"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td>
const statusClass = server.online4 || server.online6 ? "progress-bar progress-bar-success" : "progress-bar progress-bar-danger"; <td id="name">加载中</td>
const statusText = server.online4 && server.online6 ? "双栈" : server.online4 ? "IPv4" : server.online6 ? "IPv6" : "关闭"; <td id="type">加载中</td>
<td id="location">加载中</td>
TableRow.find("#online_status .progress-bar").attr("class", statusClass).html(`<small>${statusText}</small>`); <td id="uptime">加载中</td>
MableRow.find("#monitor_status .progress-bar").attr("class", statusClass).html(`<small>${statusText}</small>`); <td id="load">加载中</td>
<td id="network">加载中</td>
TableRow.find("#name").html(server.name); <td id="traffic">加载中</td>
MableRow.find("#monitor_node").html(server.name); <td id="cpu"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td>
TableRow.find("#type").html(server.type); <td id="memory"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td>
TableRow.find("#location").html(server.location); <td id="hdd"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td>
MableRow.find("#monitor_location").html(server.location); <td id="ping"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td>
</tr>
if (!server.online4 && !server.online6) { <tr class="expandRow ${hack}"><td colspan="16"><div class="accordian-body collapse" id="rt${i}">
if (server_status[i]) { <div id="expand_mem">加载中</div>
TableRow.find("#uptime").html(""); <div id="expand_hdd">加载中</div>
TableRow.find("#load").html(""); <div id="expand_tupd">加载中</div>
TableRow.find("#network").html(""); <div id="expand_ping">加载中</div>
TableRow.find("#traffic").html(""); </div></td></tr>`
TableRow.find("#month_traffic .progress-bar").attr("class", "progress-bar progress-bar-warning").html("<small>关闭</small>"); );
TableRow.find("#cpu .progress-bar").attr("class", "progress-bar progress-bar-danger").css("width", "100%").html("<small>关闭</small>"); TableRow = document.querySelector(`#servers tr#r${i}`);
TableRow.find("#memory .progress-bar").attr("class", "progress-bar progress-bar-danger").css("width", "100%").html("<small>关闭</small>"); ExpandRow = document.querySelector(`#servers #rt${i}`);
TableRow.find("#hdd .progress-bar").attr("class", "progress-bar progress-bar-danger").css("width", "100%").html("<small>关闭</small>");
TableRow.find("#ping .progress-bar").attr("class", "progress-bar progress-bar-danger").css("width", "100%").html("<small>关闭</small>");
MableRow.find("#monitor_text").html("-");
if (ExpandRow.hasClass("in")) ExpandRow.collapse("hide");
TableRow.attr("data-target", "");
MableRow.attr("data-target", "");
server_status[i] = false;
}
} else {
if (!server_status[i]) {
TableRow.attr("data-target", "#rt" + i);
MableRow.attr("data-target", "#rt" + i);
server_status[i] = true; server_status[i] = true;
} }
const trafficdiff_in = server.network_in - server.last_network_in; if (!MableRow) {
const trafficdiff_out = server.network_out - server.last_network_out; document.getElementById("monitors").insertAdjacentHTML(
const monthtraffic = `${bytesToSize(trafficdiff_in, 1, true)} | ${bytesToSize(trafficdiff_out, 1, true)}`; "beforeend",
TableRow.find("#month_traffic .progress-bar").attr("class", "progress-bar progress-bar-success").html(`<small>${monthtraffic}</small>`); `<tr id="r${i}" data-bs-target="#rt${i}" class="accordion-toggle ${hack}">
<td id="monitor_status"><div class="progress"><div style="width: 100%;" class="progress-bar progress-bar-warning"><small>加载中</small></div></div></td>
<td id="monitor_node">加载中</td>
<td id="monitor_location">加载中</td>
<td id="monitor_text">加载中</td>
</tr>`
);
MableRow = document.querySelector(`#monitors tr#r${i}`);
}
TableRow.find("#uptime").html(server.uptime); if (error) {
TableRow.find("#load").html(server.load_1 == -1 ? "" : server.load_1.toFixed(2)); TableRow.setAttribute("data-bs-target", `#rt${i}`);
MableRow.setAttribute("data-bs-target", `#rt${i}`);
server_status[i] = true;
}
const netstr = `${bytesToSize(server.network_rx, 1, true)} | ${bytesToSize(server.network_tx, 1, true)}`; const statusClass = server.online4 || server.online6 ? "progress-bar progress-bar-success" : "progress-bar progress-bar-danger";
TableRow.find("#network").html(netstr); const statusText = server.online4 && server.online6 ? "双栈" : server.online4 ? "IPv4" : server.online6 ? "IPv6" : "关闭";
const trafficstr = `${bytesToSize(server.network_in, 1, true)} | ${bytesToSize(server.network_out, 1, true)}`; if (TableRow) {
TableRow.find("#traffic").html(trafficstr); const onlineStatusBar = TableRow.querySelector("#online_status .progress-bar");
if (onlineStatusBar) {
onlineStatusBar.setAttribute("class", statusClass);
onlineStatusBar.innerHTML = `<small>${statusText}</small>`;
}
}
const cpuClass = server.cpu >= 90 ? "progress-bar progress-bar-danger" : server.cpu >= 80 ? "progress-bar progress-bar-warning" : "progress-bar progress-bar-success"; if (MableRow) {
TableRow.find("#cpu .progress-bar").attr("class", cpuClass).css("width", `${server.cpu}%`).html(`${server.cpu}%`); const monitorStatusBar = MableRow.querySelector("#monitor_status .progress-bar");
if (monitorStatusBar) {
monitorStatusBar.setAttribute("class", statusClass);
monitorStatusBar.innerHTML = `<small>${statusText}</small>`;
}
}
const Mem = ((server.memory_used / server.memory_total) * 100).toFixed(0); if (TableRow) {
const memClass = Mem >= 90 ? "progress-bar progress-bar-danger" : Mem >= 80 ? "progress-bar progress-bar-warning" : "progress-bar progress-bar-success"; TableRow.querySelector("#name").innerHTML = server.name;
TableRow.find("#memory .progress-bar").attr("class", memClass).css("width", `${Mem}%`).html(`${Mem}%`); TableRow.querySelector("#type").innerHTML = server.type;
ExpandRow.find("#expand_mem").html(`内存|虚存: ${bytesToSize(server.memory_used * 1024, 1)} / ${bytesToSize(server.memory_total * 1024, 1)} | ${bytesToSize(server.swap_used * 1024, 0)} / ${bytesToSize(server.swap_total * 1024, 0)}`); TableRow.querySelector("#location").innerHTML = server.location;
}
const HDD = ((server.hdd_used / server.hdd_total) * 100).toFixed(0); if (MableRow) {
const hddClass = HDD >= 90 ? "progress-bar progress-bar-danger" : HDD >= 80 ? "progress-bar progress-bar-warning" : "progress-bar progress-bar-success"; MableRow.querySelector("#monitor_node").innerHTML = server.name;
TableRow.find("#hdd .progress-bar").attr("class", hddClass).css("width", `${HDD}%`).html(`${HDD}%`); MableRow.querySelector("#monitor_location").innerHTML = server.location;
const io = `${bytesToSize(server.io_read, 0, true)} / ${bytesToSize(server.io_write, 0, true)}`; }
ExpandRow.find("#expand_hdd").html(`硬盘|读写: ${bytesToSize(server.hdd_used * 1024 * 1024, 2)} / ${bytesToSize(server.hdd_total * 1024 * 1024, 2)} | ${io}`);
ExpandRow.find("#expand_tupd").html(`TCP/UDP/进/线: ${server.tcp_count} / ${server.udp_count} / ${server.process_count} / ${server.thread_count}`); if (!server.online4 && !server.online6) {
if (server_status[i]) {
if (TableRow) {
TableRow.querySelector("#uptime").innerHTML = "";
TableRow.querySelector("#load").innerHTML = "";
TableRow.querySelector("#network").innerHTML = "";
TableRow.querySelector("#traffic").innerHTML = "";
const monthTrafficBar = TableRow.querySelector("#month_traffic .progress-bar");
if (monthTrafficBar) {
monthTrafficBar.setAttribute("class", "progress-bar progress-bar-warning");
monthTrafficBar.innerHTML = "<small>关闭</small>";
}
const cpuBar = TableRow.querySelector("#cpu .progress-bar");
if (cpuBar) {
cpuBar.setAttribute("class", "progress-bar progress-bar-danger");
cpuBar.style.width = "100%";
cpuBar.innerHTML = "<small>关闭</small>";
}
const memoryBar = TableRow.querySelector("#memory .progress-bar");
if (memoryBar) {
memoryBar.setAttribute("class", "progress-bar progress-bar-danger");
memoryBar.style.width = "100%";
memoryBar.innerHTML = "<small>关闭</small>";
}
const hddBar = TableRow.querySelector("#hdd .progress-bar");
if (hddBar) {
hddBar.setAttribute("class", "progress-bar progress-bar-danger");
hddBar.style.width = "100%";
hddBar.innerHTML = "<small>关闭</small>";
}
const pingBar = TableRow.querySelector("#ping .progress-bar");
if (pingBar) {
pingBar.setAttribute("class", "progress-bar progress-bar-danger");
pingBar.style.width = "100%";
pingBar.innerHTML = "<small>关闭</small>";
}
}
if (MableRow) {
MableRow.querySelector("#monitor_text").innerHTML = "-";
}
if (ExpandRow && ExpandRow.classList.contains("show")) ExpandRow.classList.remove("show");
if (TableRow) TableRow.setAttribute("data-bs-target", "");
if (MableRow) MableRow.setAttribute("data-bs-target", "");
server_status[i] = false;
}
} else {
if (!server_status[i]) {
if (TableRow) TableRow.setAttribute("data-bs-target", `#rt${i}`);
if (MableRow) MableRow.setAttribute("data-bs-target", `#rt${i}`);
server_status[i] = true;
}
const PING_10010 = server.ping_10010.toFixed(0); const trafficdiff_in = server.network_in - server.last_network_in;
const PING_189 = server.ping_189.toFixed(0); const trafficdiff_out = server.network_out - server.last_network_out;
const PING_10086 = server.ping_10086.toFixed(0); const monthtraffic = `${bytesToSize(trafficdiff_in, 1, true)} | ${bytesToSize(trafficdiff_out, 1, true)}`;
const pingClass = PING_10010 >= 20 || PING_189 >= 20 || PING_10086 >= 20 ? "progress-bar progress-bar-danger" : PING_10010 >= 10 || PING_189 >= 10 || PING_10086 >= 10 ? "progress-bar progress-bar-warning" : "progress-bar progress-bar-success"; if (TableRow) {
TableRow.find("#ping .progress-bar").attr("class", pingClass).html(`${PING_10010}%💻${PING_189}%💻${PING_10086}%`); const monthTrafficBar = TableRow.querySelector("#month_traffic .progress-bar");
ExpandRow.find("#expand_ping").html(`CU/CT/CM: ${server.time_10010}ms (${PING_10010}%) / ${server.time_189}ms (${PING_189}%) / ${server.time_10086}ms (${PING_10086}%)`); if (monthTrafficBar) {
monthTrafficBar.setAttribute("class", "progress-bar progress-bar-success");
monthTrafficBar.innerHTML = `<small>${monthtraffic}</small>`;
}
}
MableRow.find("#monitor_text").html(server.custom); if (TableRow) TableRow.querySelector("#uptime").innerHTML = server.uptime;
} if (TableRow) TableRow.querySelector("#load").innerHTML = server.load_1 == -1 ? "" : server.load_1.toFixed(2);
});
d = new Date(result.updated * 1000); const netstr = `${bytesToSize(server.network_rx, 1, true)} | ${bytesToSize(server.network_tx, 1, true)}`;
error = 0; if (TableRow) TableRow.querySelector("#network").innerHTML = netstr;
}).fail(function() {
if (!error) { const trafficstr = `${bytesToSize(server.network_in, 1, true)} | ${bytesToSize(server.network_out, 1, true)}`;
$("#servers > tr.accordion-toggle").each(function(i) { if (TableRow) TableRow.querySelector("#traffic").innerHTML = trafficstr;
const TableRow = $("#servers tr#r" + i);
const MableRow = $("#monitors tr#r" + i); const cpuClass = server.cpu >= 90 ? "progress-bar progress-bar-danger" : server.cpu >= 80 ? "progress-bar progress-bar-warning" : "progress-bar progress-bar-success";
const ExpandRow = $("#servers #rt" + i); if (TableRow) {
TableRow.find(".progress-bar").attr("class", "progress-bar progress-bar-error").html("<small>错误</small>"); const cpuBar = TableRow.querySelector("#cpu .progress-bar");
MableRow.find(".progress-bar").attr("class", "progress-bar progress-bar-error").html("<small>错误</small>"); if (cpuBar) {
if (ExpandRow.hasClass("in")) ExpandRow.collapse("hide"); cpuBar.setAttribute("class", cpuClass);
TableRow.attr("data-target", ""); cpuBar.style.width = `${server.cpu}%`;
MableRow.attr("data-target", ""); cpuBar.innerHTML = `${server.cpu}%`;
server_status[i] = false; }
}
const Mem = ((server.memory_used / server.memory_total) * 100).toFixed(0);
const memClass = Mem >= 90 ? "progress-bar progress-bar-danger" : Mem >= 80 ? "progress-bar progress-bar-warning" : "progress-bar progress-bar-success";
if (TableRow) {
const memoryBar = TableRow.querySelector("#memory .progress-bar");
if (memoryBar) {
memoryBar.setAttribute("class", memClass);
memoryBar.style.width = `${Mem}%`;
memoryBar.innerHTML = `${Mem}%`;
}
}
if (ExpandRow) ExpandRow.querySelector("#expand_mem").innerHTML = `内存|虚存: ${bytesToSize(server.memory_used * 1024, 1)} / ${bytesToSize(server.memory_total * 1024, 1)} | ${bytesToSize(server.swap_used * 1024, 0)} / ${bytesToSize(server.swap_total * 1024, 0)}`;
const HDD = ((server.hdd_used / server.hdd_total) * 100).toFixed(0);
const hddClass = HDD >= 90 ? "progress-bar progress-bar-danger" : HDD >= 80 ? "progress-bar progress-bar-warning" : "progress-bar progress-bar-success";
if (TableRow) {
const hddBar = TableRow.querySelector("#hdd .progress-bar");
if (hddBar) {
hddBar.setAttribute("class", hddClass);
hddBar.style.width = `${HDD}%`;
hddBar.innerHTML = `${HDD}%`;
}
}
const io = `${bytesToSize(server.io_read, 0, true)} / ${bytesToSize(server.io_write, 0, true)}`;
if (ExpandRow) ExpandRow.querySelector("#expand_hdd").innerHTML = `硬盘|读写: ${bytesToSize(server.hdd_used * 1024 * 1024, 2)} / ${bytesToSize(server.hdd_total * 1024 * 1024, 2)} | ${io}`;
if (ExpandRow) ExpandRow.querySelector("#expand_tupd").innerHTML = `TCP/UDP/进/线: ${server.tcp_count} / ${server.udp_count} / ${server.process_count} / ${server.thread_count}`;
const PING_10010 = server.ping_10010.toFixed(0);
const PING_189 = server.ping_189.toFixed(0);
const PING_10086 = server.ping_10086.toFixed(0);
const pingClass = PING_10010 >= 20 || PING_189 >= 20 || PING_10086 >= 20 ? "progress-bar progress-bar-danger" : PING_10010 >= 10 || PING_189 >= 10 || PING_10086 >= 10 ? "progress-bar progress-bar-warning" : "progress-bar progress-bar-success";
if (TableRow) {
const pingBar = TableRow.querySelector("#ping .progress-bar");
if (pingBar) {
pingBar.setAttribute("class", pingClass);
pingBar.innerHTML = `${PING_10010}%💻${PING_189}%💻${PING_10086}%`;
}
}
if (ExpandRow) ExpandRow.querySelector("#expand_ping").innerHTML = `CU/CT/CM: ${server.time_10010}ms (${PING_10010}%) / ${server.time_189}ms (${PING_189}%) / ${server.time_10086}ms (${PING_10086}%)`;
if (MableRow) MableRow.querySelector("#monitor_text").innerHTML = server.custom;
}
}); });
}
error = 1; d = new Date(result.updated * 1000);
$("#updated").html("更新错误."); error = 0;
}); })
.catch(error => {
console.error("Fetch error: ", error);
if (!error) {
document.querySelectorAll("#servers > tr.accordion-toggle").forEach((TableRow, i) => {
const MableRow = document.querySelector(`#monitors tr#r${i}`);
const ExpandRow = document.querySelector(`#servers #rt${i}`);
if (TableRow && MableRow) {
TableRow.querySelectorAll(".progress-bar").forEach(bar => {
if (bar) {
bar.setAttribute("class", "progress-bar progress-bar-error");
bar.innerHTML = "<small>错误</small>";
}
});
MableRow.querySelectorAll(".progress-bar").forEach(bar => {
if (bar) {
bar.setAttribute("class", "progress-bar progress-bar-error");
bar.innerHTML = "<small>错误</small>";
}
});
if (ExpandRow && ExpandRow.classList.contains("show")) {
ExpandRow.classList.remove("show");
}
TableRow.setAttribute("data-bs-target", "");
MableRow.setAttribute("data-bs-target", "");
server_status[i] = false;
} else {
console.error(`TableRow or MableRow is undefined for index ${i}`);
}
});
}
error = 1;
document.getElementById("updated").innerHTML = "更新错误.";
});
} }
function updateTime() { function updateTime() {
if (!error) $("#updated").html("最后更新: " + timeSince(d)); if (!error) document.getElementById("updated").innerHTML = "最后更新: " + timeSince(d);
} }
uptime(); uptime();
@ -223,4 +332,20 @@ window.onload = function() {
setActiveStyleSheet(mediaQueryListDark.matches ? 'dark' : 'light'); setActiveStyleSheet(mediaQueryListDark.matches ? 'dark' : 'light');
mediaQueryListDark.addEventListener("change", handleChange); mediaQueryListDark.addEventListener("change", handleChange);
} }
// 处理标签页切换
const tabs = document.querySelectorAll('.nav-link');
tabs.forEach(tab => {
tab.addEventListener('click', function(event) {
if (this.id === 'navbarDropdown') {
return; // 阻止“风格”标签的默认行为
}
event.preventDefault();
const target = this.getAttribute('href');
document.querySelectorAll('.tab-pane').forEach(pane => pane.classList.remove('show', 'active'));
document.querySelector(target).classList.add('show', 'active');
tabs.forEach(t => t.classList.remove('active'));
this.classList.add('active');
});
});
} }