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

154 lines
4.9 KiB
Vue
Raw Normal View History

<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>