2 changed files with 86 additions and 55 deletions
@ -0,0 +1,72 @@ |
|||||
|
<template> |
||||
|
<article class="device-card" :class="{ active, 'multi-selected': multiSelected }"> |
||||
|
<div class="device-select-checkbox" :title="`选择${dock.name}`" @click.stop> |
||||
|
<t-checkbox |
||||
|
:checked="multiSelected" |
||||
|
@change="(checked) => $emit('toggle-select', dock.id, checked)" |
||||
|
/> |
||||
|
</div> |
||||
|
<button class="device-card-main" @click="$emit('select', dock.id)"> |
||||
|
<span class="dock-glyph" :class="{ alarm: dock.statusClass === 'alarm', offline: dock.statusClass === 'offline' }"> |
||||
|
<svg><use href="#i-home" /></svg> |
||||
|
</span> |
||||
|
<span class="device-copy"> |
||||
|
<strong>{{ dock.name }}</strong> |
||||
|
<small>{{ dock.code }}</small> |
||||
|
</span> |
||||
|
<i class="status" :class="dock.statusClass">{{ dock.status }}</i> |
||||
|
</button> |
||||
|
|
||||
|
<button |
||||
|
v-for="drone in dock.children || []" |
||||
|
:key="drone.id" |
||||
|
class="bound-drone" |
||||
|
:class="{ |
||||
|
active: selectedDroneId === drone.id, |
||||
|
flying: drone.statusClass === 'mission', |
||||
|
offline: drone.statusClass === 'offline' |
||||
|
}" |
||||
|
@click="$emit('select', drone.id)" |
||||
|
> |
||||
|
<span class="tree-line"></span> |
||||
|
<svg><use href="#i-plane" /></svg> |
||||
|
<span><strong>{{ drone.name }}</strong><small>{{ droneSummary(drone) }}</small></span> |
||||
|
<i>{{ droneTag(drone) }}</i> |
||||
|
</button> |
||||
|
|
||||
|
<div v-if="dock.statusClass === 'alarm'" class="device-alert"> |
||||
|
<svg><use href="#i-alert" /></svg>检测到设备告警<span>{{ dock.updated }}</span> |
||||
|
</div> |
||||
|
<div v-else-if="dock.statusClass === 'offline'" class="device-alert muted"> |
||||
|
最后在线 {{ dock.updated }}<span>网络中断</span> |
||||
|
</div> |
||||
|
</article> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
const props = defineProps({ |
||||
|
dock: { type: Object, required: true }, |
||||
|
active: { type: Boolean, default: false }, |
||||
|
multiSelected: { type: Boolean, default: false }, |
||||
|
selectedDroneId: { type: String, default: null }, |
||||
|
altitudeOf: { type: Function, default: null } |
||||
|
}) |
||||
|
|
||||
|
defineEmits(['select', 'toggle-select']) |
||||
|
|
||||
|
function droneSummary(drone) { |
||||
|
if (drone.statusClass === 'mission') { |
||||
|
const alt = props.altitudeOf?.(drone.id) |
||||
|
if (alt != null) return `飞行中 · ${alt} m` |
||||
|
return '飞行中' |
||||
|
} |
||||
|
if (drone.statusClass === 'offline') return '设备离线' |
||||
|
return drone.battery && drone.battery !== '--' ? `已入巢 · 充电 ${drone.battery}` : '已入巢' |
||||
|
} |
||||
|
|
||||
|
function droneTag(drone) { |
||||
|
if (drone.statusClass === 'mission') return '飞行中' |
||||
|
if (drone.statusClass === 'offline') return '离线' |
||||
|
return '在巢' |
||||
|
} |
||||
|
</script> |
||||
Loading…
Reference in new issue