mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-05 18:44:03 +08:00
🌴 Sync 2026-03-05 23:51:42
This commit is contained in:
1 parent
97c049ed0a
commit
0acff03804
14253 files changed
+3893239
No files matched your search
@@ -0,0 +1,181 @@
|
||||
<fieldset class="cbi-section">
|
||||
<legend><%:Status%></legend>
|
||||
|
||||
<div style="display:flex; gap:8px; align-items:center; flex-wrap:wrap;">
|
||||
<div id="iperf3_status">-</div>
|
||||
|
||||
<button class="btn cbi-button cbi-button-apply" id="btn_start" type="button"><%:Start%></button>
|
||||
<button class="btn cbi-button cbi-button-reset" id="btn_stop" type="button"><%:Stop%></button>
|
||||
<button class="btn cbi-button cbi-button-action" id="btn_restart" type="button"><%:Restart%></button>
|
||||
|
||||
<span id="iperf3_busy" style="display:none; color:#999;">...</span>
|
||||
</div>
|
||||
|
||||
<div id="iperf3_list" style="margin-top:8px;"></div>
|
||||
</fieldset>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
(function () {
|
||||
var token = '<%=token%>';
|
||||
|
||||
function esc(s) {
|
||||
if (s === null || s === undefined) return '';
|
||||
return String(s).replace(/[&<>"']/g, function (c) {
|
||||
return ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]);
|
||||
});
|
||||
}
|
||||
|
||||
function setBusy(b) {
|
||||
document.getElementById('iperf3_busy').style.display = b ? '' : 'none';
|
||||
document.getElementById('btn_start').disabled = b;
|
||||
document.getElementById('btn_stop').disabled = b;
|
||||
document.getElementById('btn_restart').disabled = b;
|
||||
}
|
||||
|
||||
function badge(text, color) {
|
||||
return '<span style="color:' + color + '">' + text + '</span>';
|
||||
}
|
||||
|
||||
function stateBadge(it) {
|
||||
// 新字段优先:it.state;旧字段兼容:it.running
|
||||
var st = it.state;
|
||||
|
||||
if (!st) {
|
||||
if (it.enable === false || it.enable === "0") st = "disabled";
|
||||
else st = it.running ? "running" : "stopped";
|
||||
}
|
||||
|
||||
if (st === "running") return badge('<%:Running%>', 'green');
|
||||
if (st === "delay") return badge('<%:Delay%>', '#d67f00');
|
||||
if (st === "conflict") return badge('<%:Conflict%>', 'red');
|
||||
if (st === "disabled") return badge('<%:Disabled%>', '#999');
|
||||
return badge('<%:Stopped%>', '#999');
|
||||
}
|
||||
|
||||
function overallBadge(data) {
|
||||
// controller 返回 data.running=true 表示至少一个 running
|
||||
// 如果没有 running,但存在 delay/conflict,也给更准确的总体状态
|
||||
if (data && data.running) {
|
||||
return badge('<%:Running%>', 'green');
|
||||
}
|
||||
|
||||
var hasDelay = false, hasConflict = false;
|
||||
if (data && data.servers && data.servers.length) {
|
||||
for (var i = 0; i < data.servers.length; i++) {
|
||||
var st = data.servers[i].state;
|
||||
if (st === "delay") hasDelay = true;
|
||||
else if (st === "conflict") hasConflict = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasConflict) return badge('<%:Conflict%>', 'red');
|
||||
if (hasDelay) return badge('<%:Delay%>', '#d67f00');
|
||||
return badge('<%:Not running%>', 'red');
|
||||
}
|
||||
|
||||
function translateDetail(detail) {
|
||||
// detail 来自 controller 的英文字符串,这里做映射为可翻译字符串
|
||||
// 未命中映射时,直接原样显示
|
||||
var map = {
|
||||
"disabled in config": "<%:disabled in config%>",
|
||||
"delay pending (sleep)": "<%:delay pending (sleep)%>",
|
||||
"listening and iperf3 process found": "<%:listening and iperf3 process found%>",
|
||||
"port is listening but not iperf3 (occupied)": "<%:port is listening but not iperf3 (occupied)%>",
|
||||
"not listening": "<%:not listening%>"
|
||||
};
|
||||
return map[detail] || detail || "";
|
||||
}
|
||||
|
||||
function renderStatus(data) {
|
||||
var s = document.getElementById('iperf3_status');
|
||||
s.innerHTML = overallBadge(data);
|
||||
|
||||
var list = document.getElementById('iperf3_list');
|
||||
var html = '';
|
||||
|
||||
if (data && data.servers && data.servers.length) {
|
||||
html += '<ul>';
|
||||
|
||||
for (var i = 0; i < data.servers.length; i++) {
|
||||
var it = data.servers[i];
|
||||
|
||||
var port = esc(it.port);
|
||||
var en = (it.enable !== false) && (it.enable !== "0");
|
||||
|
||||
// 旧字段 pid 兼容
|
||||
var pidInfo = '';
|
||||
if (it.pid) {
|
||||
pidInfo = ' <span style="color:#999"><%:PID%> ' + esc(it.pid) + '</span>';
|
||||
}
|
||||
|
||||
// 监听信息(新字段 listen)
|
||||
var listenInfo = '';
|
||||
if (typeof it.listen === "boolean") {
|
||||
listenInfo = it.listen
|
||||
? ' <span style="color:#999">[<%:LISTEN%>]</span>'
|
||||
: ' <span style="color:#999">[<%:NO LISTEN%>]</span>';
|
||||
}
|
||||
|
||||
// detail(来自 controller)
|
||||
var dt = translateDetail(it.detail);
|
||||
var detail = dt ? (' <span style="color:#999">(' + esc(dt) + ')</span>') : '';
|
||||
|
||||
html += '<li>'
|
||||
+ '<%:Port%> ' + port + ' : '
|
||||
+ stateBadge(it)
|
||||
+ pidInfo
|
||||
+ listenInfo
|
||||
+ detail
|
||||
+ (en ? '' : ' <span style="color:#999">(<%:disabled%>)</span>')
|
||||
+ '</li>';
|
||||
}
|
||||
|
||||
html += '</ul>';
|
||||
|
||||
// 状态说明(简短)
|
||||
html += '<div style="margin-top:6px; color:#999;">'
|
||||
+ '<span><%:Delay%></span>: <%:starting after configured delay%> '
|
||||
+ '<span><%:Conflict%></span>: <%:port is occupied%>'
|
||||
+ '</div>';
|
||||
}
|
||||
|
||||
list.innerHTML = html;
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
XHR.get('<%=luci.dispatcher.build_url("admin/services/iperf3-server/status")%>', null,
|
||||
function (x, data) { renderStatus(data || {}); }
|
||||
);
|
||||
}
|
||||
|
||||
function doAction(url, confirmText) {
|
||||
if (confirmText && !window.confirm(confirmText)) return;
|
||||
|
||||
setBusy(true);
|
||||
XHR.post(url, { token: token }, function (x, data) {
|
||||
setBusy(false);
|
||||
refresh();
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('btn_start').addEventListener('click', function () {
|
||||
doAction('<%=luci.dispatcher.build_url("admin/services/iperf3-server/start")%>', '<%:Start iPerf3 servers?%>');
|
||||
});
|
||||
document.getElementById('btn_stop').addEventListener('click', function () {
|
||||
doAction('<%=luci.dispatcher.build_url("admin/services/iperf3-server/stop")%>', '<%:Stop iPerf3 servers?%>');
|
||||
});
|
||||
document.getElementById('btn_restart').addEventListener('click', function () {
|
||||
doAction('<%=luci.dispatcher.build_url("admin/services/iperf3-server/restart")%>', '<%:Restart iPerf3 servers?%>');
|
||||
});
|
||||
|
||||
// 轮询刷新
|
||||
XHR.poll(2, '<%=luci.dispatcher.build_url("admin/services/iperf3-server/status")%>', null,
|
||||
function (x, data) { renderStatus(data || {}); }
|
||||
);
|
||||
|
||||
// 首次刷新
|
||||
refresh();
|
||||
})();
|
||||
//]]>
|
||||
</script>
|
||||
Reference in new issue
Block a user