Files
ucvl-home-vision/frontend/src/components/NetworkMap.vue
T

118 lines
4.0 KiB
Vue
Raw Normal View History

<script setup>
import { computed } from "vue";
import {
deviceView,
snapshot,
bridge,
accessLabel,
} from "../composables/bridge.js";
import AppIcon from "./AppIcon.vue";
import NetworkStatus from "./NetworkStatus.vue";
const home = computed(() =>
(snapshot.value.state.households || []).find(
(h) => h.id === snapshot.value.state.familyId,
),
);
</script>
<template>
<div id="device-topology" hidden>
<section class="panel network-map">
<div class="network-platform">
<AppIcon name="network" />
<div>
<h3>{{ home?.name || "当前场所" }}</h3>
<p>{{ deviceView.devices.length }} 台设备 · 随设备档案自动更新</p>
</div>
</div>
<p class="description">
连线来自已确认的上级设备关系。上级未填写时单独列出;不代表已自动发现所有交换机或布线。
</p>
<div class="topology-nodes">
<article
v-for="row in deviceView.rows"
:key="row.device.id"
class="network-node card"
:class="{ nested: row.depth > 0 }"
:style="{ '--depth': Math.min(row.depth, 5) }"
>
<div class="card-body">
<div class="device-card-heading">
<AppIcon
:name="row.device.source === 'camera' ? 'camera' : 'router'"
/>
<div class="flex-grow-1">
<span class="small text-secondary"
>{{ row.device.deviceType }} ·
{{ accessLabel(row.device.networkAccess) }}</span
>
<h3>
<button
class="device-title"
@click="
bridge().enterDevice(row.device.source, row.device.id)
"
>
{{ row.device.name }}
</button>
</h3>
</div>
<button
class="btn btn-sm btn-outline-secondary"
@click="
bridge().enterDevice(
row.device.source,
row.device.id,
'device',
)
"
>
详情 →
</button>
</div>
<p class="device-location">
{{ bridge().location?.(row.device.siteId) || "未指定区域" }}
<template v-if="row.device.point">
· {{ row.device.point }}</template
>
</p>
<div class="network-facts">
<span
>IP
<b>{{
row.device.networkHosts.join(" / ") || "待填写"
}}</b></span
><span v-if="row.device.tailscaleHost"
>Tailscale <b>{{ row.device.tailscaleHost }}</b></span
><span v-if="row.device.networkCidr"
>网段 <b>{{ row.device.networkCidr }}</b></span
><span
>上级 <b>{{ row.parentName || "待确认 / 直接接入" }}</b></span
><span
>连接
<b>{{
{ wired: "网线", wifi: "Wi-Fi" }[row.device.connectionType] ||
"待确认"
}}</b></span
><span v-if="row.via.length"
>取流经录像机 <b>{{ row.via.join("、") }}</b></span
><span v-if="row.archiveVia.length"
>录像归档 <b>{{ row.archiveVia.join("、") }}</b></span
>
</div>
<NetworkStatus
v-if="/路由|网关|服务器/.test(row.device.deviceType)"
:device="row.device"
:active="
snapshot.page === 'objects' && deviceView.mode === 'topology'
"
/>
</div>
</article>
<p v-if="!deviceView.rows.length" class="empty">
当前范围尚未登记设备。
</p>
</div>
</section>
</div>
</template>