const activeLease = document.querySelector("#activeLease"); const pendingRequests = document.querySelector("#pendingRequests"); const pendingCount = document.querySelector("#pendingCount"); const revokeButton = document.querySelector("#revokeButton"); const message = document.querySelector("#message"); let snapshot = null; function escapeHtml(value) { const node = document.createElement("span"); node.textContent = String(value ?? ""); return node.innerHTML; } function showMessage(value, error = false) { message.textContent = value; message.style.color = error ? "#ff8797" : "#7fbbff"; } async function api(path, body) { const response = await fetch(path, { method: body ? "POST" : "GET", credentials: "same-origin", headers: body ? { "Content-Type": "application/json" } : {}, body: body ? JSON.stringify(body) : undefined, }); if (response.status === 401) { location.replace(`/login?next=${encodeURIComponent(location.pathname)}`); throw new Error("请先登录本机服务"); } const payload = await response.json(); if (!response.ok) throw new Error(payload.message || payload.error); return payload; } function render(data) { snapshot = data; pendingCount.textContent = String(data.pending.length); if (data.active) { const lease = data.active; activeLease.className = "lease-details"; activeLease.innerHTML = `
${escapeHtml(lease.label)}${escapeHtml(lease.client_id)}来源 ${escapeHtml(lease.client_address)} · 最近执行 ${escapeHtml(lease.last_activity_at)}
${Number(lease.idle_remaining_seconds)}s
`; revokeButton.hidden = false; revokeButton.dataset.clientId = lease.client_id; } else { activeLease.className = "empty"; activeLease.textContent = "当前无人获批使用真实台架。"; revokeButton.hidden = true; } if (!data.pending.length) { pendingRequests.className = "request-list empty"; pendingRequests.textContent = "暂时没有申请。"; return; } pendingRequests.className = "request-list"; pendingRequests.innerHTML = data.pending.map((request) => `
${escapeHtml(request.label)}${escapeHtml(request.client_id)}来源 ${escapeHtml(request.client_address)} · ${escapeHtml(request.requested_at)}
`).join(""); } async function refresh() { try { render(await api("/api/local/hardware-access")); document.querySelector("#clock").textContent = new Date().toLocaleTimeString("zh-CN", { hour12: false }); } catch (error) { showMessage(error.message, true); } } pendingRequests.addEventListener("click", async (event) => { const button = event.target.closest("button[data-action]"); if (!button) return; button.disabled = true; try { const action = button.dataset.action; render(await api(`/api/local/hardware-access/${action}`, { client_id: button.dataset.clientId })); showMessage(action === "approve" ? "已授予该终端真实台架使用权。" : "已拒绝该终端的申请。"); } catch (error) { showMessage(error.message, true); } finally { button.disabled = false; } }); revokeButton.addEventListener("click", async () => { revokeButton.disabled = true; try { render(await api("/api/local/hardware-access/revoke", { client_id: revokeButton.dataset.clientId })); showMessage("已停止该终端的真实台架使用权;再次使用必须重新申请。"); } catch (error) { showMessage(error.message, true); } finally { revokeButton.disabled = false; } }); refresh(); setInterval(refresh, 2000);