import { getRequestOrigin } from "@/lib/request-origin"; import { buildNodeHy2Config } from "@/lib/subscription"; import { buildNodeAuthUrl, buildTrafficStatsUrl, listNodes } from "@/lib/store"; import { createNodeAction, deleteNodeAction, updateNodeAction } from "./actions"; function getNodePills(node: { enabled: number; last_error_message: string | null; }) { return [ { label: node.enabled ? "已启用" : "已禁用", className: `status-pill ${node.enabled ? "status-pill--ok" : "status-pill--off"}`, }, node.last_error_message ? { label: "同步异常", className: "status-pill status-pill--danger" } : { label: "同步正常", className: "status-pill status-pill--sage" }, ]; } export default async function NodesPage() { const [nodes, origin] = await Promise.all([listNodes(), getRequestOrigin()]); return (
NODES

节点管理

统一维护 hy2 节点监听参数、鉴权 URL、trafficStats 接入和客户端导出配置。

URL 自动推导 Secret 自动生成
节点总数 {nodes.length}
启用中 {nodes.filter((node) => node.enabled).length}

新增节点

{nodes.map((node) => { const authUrl = buildNodeAuthUrl(node.slug, node.auth_token, origin); const suggestedTrafficStatsUrl = buildTrafficStatsUrl( node.server_host, node.traffic_stats_listen, ); return (

{node.name}

/{node.slug}

{getNodePills(node).map((pill) => ( {pill.label} ))}

最近同步 {node.last_sync_ok_at ?? "无"} / 错误{" "} {node.last_error_at ?? "无"}

hy2 监听 {node.hy2_listen}
对外地址 {node.server_host}:{node.server_port}
trafficStats {node.traffic_stats_url}
节点接入说明

hy2 HTTP 鉴权 URL 必须独立配置到本节点。面板通过路径识别节点来源,不依赖请求体。

{buildNodeHy2Config(node, origin)}
                

面板轮询地址:{node.traffic_stats_url}

自动推导地址:{suggestedTrafficStatsUrl}

鉴权 URL:{authUrl}

下载 hy2 config.yaml {node.last_error_message ? (

{node.last_error_message}

) : null}
); })}
); }