refactor(ui): merge instances page into network dashboard
- Remove the redundant Instances page; its network detail and server connection sections now live in DashboardView below selectable instance cards - Redirect legacy /instances and /general routes to / - Add per-page subtitles to the header instead of a fixed caption - Widen content container to 1700px for large screens - Highlight online device count in green on the stats cards
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -19,8 +19,8 @@
|
||||
if (dark) document.documentElement.classList.add("dark");
|
||||
})();
|
||||
</script>
|
||||
<script type="module" crossorigin src="/assets/index-CU8fPWbk.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CqFhxcSz.css">
|
||||
<script type="module" crossorigin src="/assets/index-B15xAuUw.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-DI9vlWSX.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -79,7 +79,7 @@ onBeforeUnmount(() => window.removeEventListener("keydown", handleKeydown));
|
||||
|
||||
<div class="min-w-0">
|
||||
<h1 class="truncate text-lg font-bold text-slate-900 dark:text-white">{{ pageMeta.label }}</h1>
|
||||
<p class="hidden text-xs text-slate-400 sm:block">VNT 虚拟局域网管理</p>
|
||||
<p class="hidden text-xs text-slate-400 sm:block">{{ pageMeta.subtitle || "VNT 虚拟局域网管理" }}</p>
|
||||
</div>
|
||||
|
||||
<div class="ml-auto flex items-center gap-2">
|
||||
@@ -103,7 +103,7 @@ onBeforeUnmount(() => window.removeEventListener("keydown", handleKeydown));
|
||||
</header>
|
||||
|
||||
<main class="custom-scrollbar min-h-0 flex-1 overflow-x-hidden overflow-y-auto">
|
||||
<div class="mx-auto w-full max-w-7xl px-4 py-5 sm:px-5 lg:px-7 lg:py-6">
|
||||
<div class="mx-auto w-full max-w-[1700px] px-4 py-5 sm:px-5 lg:px-7 lg:py-6">
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition name="fade" mode="out-in"><component :is="Component" /></transition>
|
||||
</router-view>
|
||||
|
||||
@@ -3,43 +3,43 @@ export const navItems = [
|
||||
to: "/",
|
||||
label: "网络总览",
|
||||
shortLabel: "总览",
|
||||
subtitle: "组网状态与实例管理",
|
||||
icon: "M4 4h6v6H4V4Zm10 0h6v6h-6V4ZM4 14h6v6H4v-6Zm10 0h6v6h-6v-6Z",
|
||||
},
|
||||
{
|
||||
to: "/instances",
|
||||
label: "运行实例",
|
||||
shortLabel: "实例",
|
||||
icon: "M4 18V8m5 10V4m6 14v-7m5 7V6",
|
||||
},
|
||||
{
|
||||
to: "/peers",
|
||||
label: "在线设备",
|
||||
shortLabel: "设备",
|
||||
subtitle: "查看网络中的对端设备",
|
||||
icon: "M15 19a6 6 0 0 0-12 0m18 0a5 5 0 0 0-5-5m-7-3a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm8 0a3 3 0 1 0 0-6",
|
||||
},
|
||||
{
|
||||
to: "/routes",
|
||||
label: "路由表",
|
||||
shortLabel: "路由",
|
||||
subtitle: "虚拟网络路由信息",
|
||||
icon: "M6 8a2 2 0 1 0 0-4 2 2 0 0 0 0 4Zm12 12a2 2 0 1 0 0-4 2 2 0 0 0 0 4ZM8 6h6a4 4 0 0 1 4 4v2m-3-3 3 3 3-3M16 18h-6a4 4 0 0 1-4-4v-2",
|
||||
},
|
||||
{
|
||||
to: "/config",
|
||||
label: "组网配置",
|
||||
shortLabel: "配置",
|
||||
icon: "M12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Zm7.4-.5a1.7 1.7 0 0 0 .3 1.9l.1.1-2.8 2.8-.1-.1a1.7 1.7 0 0 0-1.9-.3A1.7 1.7 0 0 0 14 21v.2h-4V21a1.7 1.7 0 0 0-1-1.6 1.7 1.7 0 0 0-1.9.3l-.1.1L4.2 17l.1-.1a1.7 1.7 0 0 0 .3-1.9A1.7 1.7 0 0 0 3 14h-.2v-4H3a1.7 1.7 0 0 0 1.6-1 1.7 1.7 0 0 0-.3-1.9L4.2 7 7 4.2l.1.1A1.7 1.7 0 0 0 9 4.6 1.7 1.7 0 0 0 10 3v-.2h4V3a1.7 1.7 0 0 0 1 1.6 1.7 1.7 0 0 0 1.9-.3l.1-.1L19.8 7l-.1.1a1.7 1.7 0 0 0-.3 1.9 1.7 1.7 0 0 0 1.6 1h.2v4H21a1.7 1.7 0 0 0-1.6 1Z",
|
||||
subtitle: "管理组网配置文件",
|
||||
icon: "M12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Zm7.4-.5a1.7 1.7 0 0 0 .3 1.9l.1.1-2.8 2.8-.1-.1a1.7 1.7 0 0 0-1.9-.3A1.7 1.7 0 0 0 14 21v.2h-4V21a1.7 1.7 0 0 0-1-1.6 1.7 1.7 0 0 0-1.9.3l-.1.1L4.2 17l.1-.1a1.7 1.7 0 0 0 .3-1.9A1.7 1.7 0 0 0 3 14h-.2v-4H3a1.7 1.7 0 0 0 1.6-1 1.7 1.7 0 0 0-.3-1.9L4.2 7 7 4.2l.1.1A1.7 1.7 0 0 0 9 4.6 1.7 1.7 0 0 0 10 3v-.2h4V3a1.7 1.7 0 0 0 1 1.6 1.7 1.7 0 0 0 1.9-.3l.1-.1L19.8 7l-.1.1a1.7 1.7 0 0 0-.3 1.9 1.7 1.7 0 0 0 1.6 1h.2v4H21a1.7 1.7 0 0 0-1.6-1Z",
|
||||
},
|
||||
{
|
||||
to: "/web-access",
|
||||
label: "Web 访问",
|
||||
shortLabel: "Web",
|
||||
subtitle: "远程访问设置",
|
||||
desktopOnly: true,
|
||||
icon: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Zm0 0c2.2-2.5 3.3-5.5 3.3-9S14.2 5.5 12 3m0 18c-2.2-2.5-3.3-5.5-3.3-9S9.8 5.5 12 3M3.5 9h17m-17 6h17",
|
||||
icon: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Zm0 0c-2.2-2.5 3.3-5.5 3.3-9S14.2 5.5 12 3m0 18c-2.2-2.5-3.3-5.5-3.3-9S9.8 5.5 12 3M3.5 9h17m-17 6h17",
|
||||
},
|
||||
{
|
||||
to: "/about",
|
||||
label: "关于",
|
||||
shortLabel: "关于",
|
||||
subtitle: "版本与更新",
|
||||
icon: "M12 17v-6m0-4h.01M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { createRouter, createWebHashHistory } from "vue-router";
|
||||
import DashboardView from "../views/DashboardView.vue";
|
||||
import InstancesView from "../views/InstancesView.vue";
|
||||
import ConfigView from "../views/ConfigView.vue";
|
||||
import PeersView from "../views/PeersView.vue";
|
||||
import RoutesView from "../views/RoutesView.vue";
|
||||
@@ -9,9 +8,9 @@ import AboutView from "../views/AboutView.vue";
|
||||
|
||||
const routes = [
|
||||
{ path: "/", component: DashboardView },
|
||||
{ path: "/instances", component: InstancesView },
|
||||
// 兼容旧路由
|
||||
{ path: "/general", redirect: "/instances" },
|
||||
// 兼容旧路由:实例管理已并入网络总览
|
||||
{ path: "/instances", redirect: "/" },
|
||||
{ path: "/general", redirect: "/" },
|
||||
{ path: "/config", component: ConfigView },
|
||||
{ path: "/peers", component: PeersView },
|
||||
{ path: "/routes", component: RoutesView },
|
||||
|
||||
@@ -60,7 +60,10 @@ const statusSummary = computed(() => {
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="text-xs font-medium muted">在线设备</div>
|
||||
<div class="mt-2 text-2xl font-bold tabular-nums text-slate-900 dark:text-white">
|
||||
<div
|
||||
class="mt-2 text-2xl font-bold tabular-nums"
|
||||
:class="onlineDevices > 0 ? 'text-green-600 dark:text-green-400' : 'text-slate-900 dark:text-white'"
|
||||
>
|
||||
{{ onlineDevices }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -81,23 +84,144 @@ const statusSummary = computed(() => {
|
||||
<!-- 启动组网 -->
|
||||
<StartPanel />
|
||||
|
||||
<!-- 实例概览 -->
|
||||
<!-- 实例列表 -->
|
||||
<div>
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<h2 class="text-base font-bold text-slate-900 dark:text-white">实例概览</h2>
|
||||
<router-link
|
||||
to="/instances"
|
||||
class="text-sm font-medium text-indigo-600 hover:text-indigo-500 dark:text-indigo-400"
|
||||
>查看详情 →</router-link
|
||||
>
|
||||
<h2 class="text-base font-bold text-slate-900 dark:text-white">组网实例</h2>
|
||||
<span v-if="app.instanceList.length > 0" class="text-xs muted">点击卡片查看详情</span>
|
||||
</div>
|
||||
<EmptyState
|
||||
v-if="app.instanceList.length === 0"
|
||||
:text="app.configList.length === 0 ? '暂无配置,请先新建配置' : '暂无运行中的组网,请在上方选择配置启动'"
|
||||
/>
|
||||
<TransitionGroup v-else name="card-list" tag="div" class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<InstanceCard v-for="inst in app.instanceList" :key="inst.file_name" :inst="inst" />
|
||||
<InstanceCard v-for="inst in app.instanceList" :key="inst.file_name" :inst="inst" selectable />
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
|
||||
<!-- 选中实例详情 -->
|
||||
<template v-if="app.selectedInstance && app.selectedInfo">
|
||||
<div class="card">
|
||||
<h2 class="mb-4 text-lg font-bold text-slate-900 dark:text-white">
|
||||
网络详情
|
||||
<span class="ml-2 text-sm font-medium text-indigo-600 dark:text-indigo-400">{{
|
||||
app.selectedConfigName
|
||||
}}</span>
|
||||
</h2>
|
||||
<div class="grid grid-cols-1 gap-4 text-sm md:grid-cols-2">
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">虚拟 IP / 掩码</span>
|
||||
<span class="font-mono tabular-nums text-slate-900 dark:text-white"
|
||||
>{{ app.selectedInfo.ip || "-" }} / {{ app.selectedInfo.prefix_len || "-" }}</span
|
||||
>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">网关</span>
|
||||
<span class="font-mono text-slate-900 dark:text-white">{{ app.selectedInfo.gateway || "-" }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">网络编号</span>
|
||||
<span class="font-mono text-slate-900 dark:text-white">{{ app.selectedInfo.network_code || "-" }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">MTU</span>
|
||||
<span class="font-mono tabular-nums text-slate-900 dark:text-white">{{ app.selectedInfo.mtu || "" }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">NAT 类型</span>
|
||||
<span class="font-mono text-indigo-600 dark:text-indigo-400">{{
|
||||
app.selectedInfo.nat_type || "Unknown"
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">Public IPv6</span>
|
||||
<span
|
||||
class="max-w-[200px] truncate font-mono text-slate-900 dark:text-white"
|
||||
:title="app.selectedInfo.public_ipv6"
|
||||
>{{ app.selectedInfo.public_ipv6 || "-" }}</span
|
||||
>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">设备名称</span>
|
||||
<span class="text-slate-900 dark:text-white">{{ app.selectedInfo.name || "-" }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">设备 ID</span>
|
||||
<span
|
||||
class="max-w-[200px] truncate font-mono text-xs text-slate-500 dark:text-slate-400"
|
||||
:title="app.selectedInfo.device_id"
|
||||
>{{ app.selectedInfo.device_id || "-" }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 grid grid-cols-2 gap-3 md:grid-cols-4">
|
||||
<div
|
||||
v-for="feat in [
|
||||
{ key: 'encrypt', label: '加密' },
|
||||
{ key: 'compress', label: '压缩' },
|
||||
{ key: 'fec', label: 'FEC纠错' },
|
||||
{ key: 'rtx', label: 'QUIC传输' },
|
||||
]"
|
||||
:key="feat.key"
|
||||
class="flex items-center gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50"
|
||||
>
|
||||
<span
|
||||
class="h-2 w-2 rounded-full"
|
||||
:class="app.selectedInfo[feat.key] ? 'bg-green-500' : 'bg-slate-300 dark:bg-slate-600'"
|
||||
></span>
|
||||
<span class="text-sm text-slate-600 dark:text-slate-300">{{ feat.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<span class="mb-2 block text-sm muted">Public IPv4s</span>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<span
|
||||
v-for="pip in app.selectedInfo.public_ipv4s"
|
||||
:key="pip"
|
||||
class="rounded border border-slate-200 bg-slate-50 px-2 py-1 font-mono text-xs tabular-nums text-green-700 dark:border-slate-600 dark:bg-slate-800 dark:text-green-300"
|
||||
>{{ pip }}</span
|
||||
>
|
||||
<span
|
||||
v-if="!app.selectedInfo.public_ipv4s || app.selectedInfo.public_ipv4s.length === 0"
|
||||
class="text-xs text-slate-400"
|
||||
>无</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card p-0 overflow-hidden">
|
||||
<div class="border-b border-slate-200 px-6 py-4 dark:border-slate-700">
|
||||
<h2 class="text-lg font-bold text-slate-900 dark:text-white">服务器连接列表</h2>
|
||||
</div>
|
||||
<div class="custom-scrollbar max-h-[400px] overflow-x-auto">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>地址</th>
|
||||
<th>状态</th>
|
||||
<th>延迟</th>
|
||||
<th>版本</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(server, idx) in app.selectedInfo.server_info" :key="idx">
|
||||
<td class="font-mono">{{ server.server }}</td>
|
||||
<td>
|
||||
<span :class="server.connected ? 'badge-green' : 'badge-red'">
|
||||
{{ server.connected ? "已连接" : "未连接" }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="tabular-nums">{{ server.server_rtt ? server.server_rtt + " ms" : "-" }}</td>
|
||||
<td>{{ server.server_version || "-" }}</td>
|
||||
</tr>
|
||||
<tr v-if="!app.selectedInfo.server_info || app.selectedInfo.server_info.length === 0">
|
||||
<td colspan="4" class="text-center text-slate-400">暂无数据</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
<script setup>
|
||||
import { useAppStore } from "../stores/app";
|
||||
import StartPanel from "../components/StartPanel.vue";
|
||||
import InstanceCard from "../components/InstanceCard.vue";
|
||||
import EmptyState from "../components/EmptyState.vue";
|
||||
|
||||
const app = useAppStore();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="space-y-6">
|
||||
<!-- 页面标题 -->
|
||||
<div>
|
||||
<h1 class="page-title">实例</h1>
|
||||
<p class="page-subtitle">管理组网实例,点击卡片查看详情</p>
|
||||
</div>
|
||||
|
||||
<!-- 启动组网 -->
|
||||
<StartPanel />
|
||||
|
||||
<!-- 组网实例 -->
|
||||
<EmptyState v-if="app.instanceList.length === 0" text="暂无运行中的组网,请在上方选择配置启动" />
|
||||
<TransitionGroup v-else name="card-list" tag="div" class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<InstanceCard v-for="inst in app.instanceList" :key="inst.file_name" :inst="inst" selectable />
|
||||
</TransitionGroup>
|
||||
|
||||
<!-- 选中实例详情 -->
|
||||
<template v-if="app.selectedInstance && app.selectedInfo">
|
||||
<div class="card">
|
||||
<h2 class="mb-4 text-lg font-bold text-slate-900 dark:text-white">
|
||||
网络详情
|
||||
<span class="ml-2 text-sm font-medium text-indigo-600 dark:text-indigo-400">{{
|
||||
app.selectedConfigName
|
||||
}}</span>
|
||||
</h2>
|
||||
<div class="grid grid-cols-1 gap-4 text-sm md:grid-cols-2">
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">虚拟 IP / 掩码</span>
|
||||
<span class="font-mono tabular-nums text-slate-900 dark:text-white"
|
||||
>{{ app.selectedInfo.ip || "-" }} / {{ app.selectedInfo.prefix_len || "-" }}</span
|
||||
>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">网关</span>
|
||||
<span class="font-mono text-slate-900 dark:text-white">{{ app.selectedInfo.gateway || "-" }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">网络编号</span>
|
||||
<span class="font-mono text-slate-900 dark:text-white">{{ app.selectedInfo.network_code || "-" }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">MTU</span>
|
||||
<span class="font-mono tabular-nums text-slate-900 dark:text-white">{{ app.selectedInfo.mtu || "" }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">NAT 类型</span>
|
||||
<span class="font-mono text-indigo-600 dark:text-indigo-400">{{
|
||||
app.selectedInfo.nat_type || "Unknown"
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">Public IPv6</span>
|
||||
<span
|
||||
class="max-w-[200px] truncate font-mono text-slate-900 dark:text-white"
|
||||
:title="app.selectedInfo.public_ipv6"
|
||||
>{{ app.selectedInfo.public_ipv6 || "-" }}</span
|
||||
>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">设备名称</span>
|
||||
<span class="text-slate-900 dark:text-white">{{ app.selectedInfo.name || "-" }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between border-b border-slate-100 pb-2 dark:border-slate-700">
|
||||
<span class="muted">设备 ID</span>
|
||||
<span
|
||||
class="max-w-[200px] truncate font-mono text-xs text-slate-500 dark:text-slate-400"
|
||||
:title="app.selectedInfo.device_id"
|
||||
>{{ app.selectedInfo.device_id || "-" }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 grid grid-cols-2 gap-3 md:grid-cols-4">
|
||||
<div
|
||||
v-for="feat in [
|
||||
{ key: 'encrypt', label: '加密' },
|
||||
{ key: 'compress', label: '压缩' },
|
||||
{ key: 'fec', label: 'FEC纠错' },
|
||||
{ key: 'rtx', label: 'QUIC传输' },
|
||||
]"
|
||||
:key="feat.key"
|
||||
class="flex items-center gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50"
|
||||
>
|
||||
<span
|
||||
class="h-2 w-2 rounded-full"
|
||||
:class="app.selectedInfo[feat.key] ? 'bg-green-500' : 'bg-slate-300 dark:bg-slate-600'"
|
||||
></span>
|
||||
<span class="text-sm text-slate-600 dark:text-slate-300">{{ feat.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<span class="mb-2 block text-sm muted">Public IPv4s</span>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<span
|
||||
v-for="pip in app.selectedInfo.public_ipv4s"
|
||||
:key="pip"
|
||||
class="rounded border border-slate-200 bg-slate-50 px-2 py-1 font-mono text-xs tabular-nums text-green-700 dark:border-slate-600 dark:bg-slate-800 dark:text-green-300"
|
||||
>{{ pip }}</span
|
||||
>
|
||||
<span
|
||||
v-if="!app.selectedInfo.public_ipv4s || app.selectedInfo.public_ipv4s.length === 0"
|
||||
class="text-xs text-slate-400"
|
||||
>无</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card p-0 overflow-hidden">
|
||||
<div class="border-b border-slate-200 px-6 py-4 dark:border-slate-700">
|
||||
<h2 class="text-lg font-bold text-slate-900 dark:text-white">服务器连接列表</h2>
|
||||
</div>
|
||||
<div class="custom-scrollbar max-h-[400px] overflow-x-auto">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>地址</th>
|
||||
<th>状态</th>
|
||||
<th>延迟</th>
|
||||
<th>版本</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(server, idx) in app.selectedInfo.server_info" :key="idx">
|
||||
<td class="font-mono">{{ server.server }}</td>
|
||||
<td>
|
||||
<span :class="server.connected ? 'badge-green' : 'badge-red'">
|
||||
{{ server.connected ? "已连接" : "未连接" }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="tabular-nums">{{ server.server_rtt ? server.server_rtt + " ms" : "-" }}</td>
|
||||
<td>{{ server.server_version || "-" }}</td>
|
||||
</tr>
|
||||
<tr v-if="!app.selectedInfo.server_info || app.selectedInfo.server_info.length === 0">
|
||||
<td colspan="4" class="text-center text-slate-400">暂无数据</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user