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

154 lines
4.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
import {
deviceView,
snapshot,
bridge,
accessLabel,
} from "../composables/bridge.js";
import AppIcon from "./AppIcon.vue";
import NetworkStatus from "./NetworkStatus.vue";
const channels = (d) =>
(snapshot.value.state.cameras || []).filter((c) =>
d.source === "camera"
? c.assetId === d.id
: c.recorderId === d.id || c.archiveRecorderId === d.id,
);
const editAttrs = (d) => ({
["data-" +
(d.source === "camera"
? "edit-asset"
: d.source === "recorder"
? "edit-recorder"
: "edit-device")]: d.id,
});
const monitored = (d) =>
/路由|网关|服务器/.test(d.deviceType) || /gl\.inet/i.test(d.brand || "");
</script>
<template>
<div id="asset-list">
<section
v-for="group in deviceView.groups"
:key="group.key"
class="device-group"
>
<h3 class="group-title">
{{ group.labels.join(" / ") || "全部设备" }}
<span class="count-pill">{{ group.items.length }}</span>
</h3>
<div class="device-card-grid">
<article
v-for="d in group.items"
:key="d.source + d.id"
class="card device-card"
>
<div class="card-body">
<div class="device-card-heading">
<div class="device-symbol">
<AppIcon
:name="
d.source === 'camera'
? 'camera'
: monitored(d)
? 'router'
: 'devices'
"
/>
</div>
<div class="flex-grow-1">
<span class="small text-secondary">{{ d.deviceType }}</span>
<h3>
<button
class="device-title"
@click="bridge().enterDevice(d.source, d.id)"
>
{{ d.name }}
</button>
</h3>
</div>
<button
v-if="snapshot.admin"
class="btn btn-sm btn-outline-secondary"
v-bind="editAttrs(d)"
>
编辑
</button>
</div>
<p class="device-location">
{{ bridge().location?.(d.siteId) || "区域待填写"
}}<template v-if="d.point"> · {{ d.point }}</template>
</p>
<dl class="compact-details">
<div>
<dt>品牌型号</dt>
<dd>
{{
[d.brand, d.model].filter(Boolean).join(" / ") || "未填写"
}}
</dd>
</div>
<div>
<dt>设备地址</dt>
<dd class="font-monospace">
{{ d.networkHosts.join(" / ") || "未填写" }}
</dd>
</div>
<div>
<dt>网络</dt>
<dd>{{ accessLabel(d.networkAccess) }}</dd>
</div>
<div>
<dt>所有人 / 负责人</dt>
<dd>
{{ d.ownerName || "待指定" }} /
{{ d.managerName || "待指定" }}
</dd>
</div>
<div v-if="d.source !== 'device'">
<dt>镜头通道</dt>
<dd>{{ channels(d).length }} 个已配置</dd>
</div>
</dl>
<div v-if="d.tags?.length" class="device-tags">
<span v-for="tag in d.tags" :key="tag">{{ tag }}</span>
</div>
<NetworkStatus
v-if="monitored(d)"
:device="d"
:active="
snapshot.page === 'objects' && deviceView.mode === 'cards'
"
/>
</div>
<div class="card-footer device-card-actions">
<button
class="btn btn-sm btn-outline-secondary"
@click="bridge().enterDevice(d.source, d.id, 'device')"
>
设备详情</button
><template v-if="d.source !== 'device'"
><button
v-if="snapshot.admin"
class="btn btn-sm btn-outline-secondary"
@click="bridge().enterDevice(d.source, d.id, 'cameras')"
>
配置镜头</button
><button
v-if="channels(d).length"
class="btn btn-sm btn-primary"
@click="bridge().enterDevice(d.source, d.id, 'live')"
>
实时画面
</button></template
>
</div>
</article>
</div>
</section>
<div v-if="!deviceView.devices.length" class="empty">
<AppIcon name="devices" />
<h3>当前范围没有设备</h3>
<p>调整筛选条件,或添加摄像机、路由器、灯等设备。</p>
</div>
</div>
</template>