feat: persist device offline lifecycle

This commit is contained in:
kyaring
2026-09-28 12:33:06 +08:00
parent bb6a446cad
commit d27cc47d8c
9 changed files with 314 additions and 82 deletions
+3 -1
View File
@@ -37,4 +37,6 @@ header strong{font-size:18px}header span{margin-left:12px;color:var(--text-muted
.p-val{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-weight:600;font-size:12px;color:var(--text-main);white-space:nowrap}
.badge-docker-text{padding:1px 6px;border-radius:4px;font-size:11px;font-weight:700}
.badge-docker-text.yes{background:rgba(34,197,94,.15);color:var(--dot-online);border:1px solid rgba(34,197,94,.3)}
.badge-docker-text.no{background:rgba(148,163,184,.15);color:var(--text-muted);border:1px solid var(--border)}
.badge-docker-text.no{background:rgba(148,163,184,.15);color:var(--text-muted);border:1px solid var(--border)}
.device-card.offline{opacity:.62;filter:saturate(.45)}
.device-card.offline .btn-revoke{opacity:1}
+3 -3
View File
@@ -38,7 +38,7 @@ async function loadDevices(){
const p = d.profile || {};
const role = p.role || "APPLICATION";
const isOnline = d.status === "online";
const statusText = isOnline ? "在线" : "离线";
const statusText = isOnline ? "在线" : "离线";\n const lastText = d.last_heartbeat ? new Date(d.last_heartbeat*1000).toLocaleString() : "";
const archOs = (d.arch || d.os) ? `${esc(d.arch||"")}/${esc(d.os||"")} · ` : "";
const cpuStr = p.cpu_cores ? `${p.cpu_cores}C · ${p.cpu_usage_percent ?? 0}%` : '-';
const loadStr = p.load_1m !== undefined ? p.load_1m.toFixed(2) : '-';
@@ -58,7 +58,7 @@ async function loadDevices(){
</div>
<button class="btn-revoke" onclick="removeDevice('${esc(d.name)}')">注销</button>
</div>
<div class="v1-row2">${archOs}${statusText}</div>
<div class="v1-row2">${archOs}${statusText}${isOnline ? "" : (lastText ? " · 最后活跃: "+lastText : "")}</div>
</div>
<div class="profile-grid">
<div class="p-item"><span class="p-label">CPU</span><span class="p-val">${cpuStr}</span></div>
@@ -72,7 +72,7 @@ async function loadDevices(){
`;
}).join("");
$("#device").innerHTML=ds.map(d=>'<option>'+esc(d.name)+'</option>').join("");
$("#device").innerHTML=ds.map(d=>`<option value="${esc(d.name)}" ${d.status==="offline" ? "disabled" : ""}>${esc(d.name)}${d.status==="offline" ? " [离线]" : ""}</option>`).join("");
}
async function loadAudits(){