import Link from "next/link"; import { requireCloudViewer } from "../../cloud-auth"; import { DashboardShell, PageHeading, StatusPill, formatDate } from "../../components/Shells"; import { getDashboardSnapshot, getOrCreateAccount } from "@/db/repository"; import { HostRevokeButton } from "./HostRevokeButton"; import { PairingCancelButton } from "./PairingCancelButton"; import { getConnectionCopy } from "../connection-copy"; import { deriveControlPlaneContact } from "@/db/device-control-plane"; export const dynamic = "force-dynamic"; function lifecycleLabel(value: string) { return value === "active" ? "已启用" : value === "deactivated" ? "已撤销" : value; } function slotLabel(value: string) { return value === "active" ? "占用中" : value === "released" ? "已释放" : value; } export default async function HostsPage() { const viewer = await requireCloudViewer("/dashboard/hosts"); const account = await getOrCreateAccount(viewer); const snapshot = await getDashboardSnapshot(account); const connection = getConnectionCopy(snapshot.connection.state); return (
添加主机} />
权益来源{snapshot.entitlement.mode === "public_beta" ? "公开公测" : snapshot.entitlement.mode === "grant" ? "闭测邀请" : "无"}
启用{snapshot.entitlement.activeSlots}
配对占位{snapshot.entitlement.reservedSlots}
可用{snapshot.entitlement.unlimited ? "不按槽位限额" : snapshot.entitlement.availableSlots}
已认领

持久主机记录

{connection.label}

{connection.detail} {connection.nextStep}

“控制面签到”只表示设备令牌最近通过了 Cloud 授权;是否在线仍以共享 Relay 的实时连接为准。

{snapshot.hosts.length ? (
{snapshot.hosts.map((host) => { const contact = deriveControlPlaneContact(host.control_plane_last_seen_at); return (
{host.os === "windows" ? "W" : "L"}
{host.name}{host.id}
槽位{slotLabel(host.slot_state)}
Daemon / 控制面 {host.daemon_version || "版本待上报"} {host.control_plane_last_seen_at ? formatDate(host.control_plane_last_seen_at, true) : "等待首次 Relay 授权"}
{host.lifecycle === "active" ? contact.label : lifecycleLabel(host.lifecycle)} {host.lifecycle === "active" && } {host.lifecycle === "deactivated" && 重新配对}
); })}
) : (

没有真实主机记录

这是正确的空状态。控制平面不会为示意图制造一台“在线”主机。

创建第一个配对请求
)}
恢复与重装

先分清身份文件还在不在

identity.json 还在

恢复原主机记录

撤销旧令牌后创建新配对码,保留 identity.json、删除旧 config.json,并使用最新版 daemon 重新注册。daemon 会签名证明仍持有原私钥;Cloud 复用原主机 ID 并签发新令牌。

身份文件已丢失

建立新的主机记录

先撤销旧记录,再创建新配对码。新安装会生成新身份和新主机 ID;旧记录保留为已撤销审计历史,不会静默换绑。

一次性

等待认领的配对请求

{snapshot.pairings.length ? (
{snapshot.pairings.map((pairing) => (
{pairing.requested_name}{pairing.os.toUpperCase()} · {pairing.id}
等待 daemon过期:{formatDate(pairing.expires_at, true)}
))}
) : (
没有等待中的配对请求。
)}
); }