|
|
|
@ -20,10 +20,10 @@ |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="asset-workspace"> |
|
|
|
<div class="asset-tabs"> |
|
|
|
<button class="asset-tab" :class="{ active: tab === 'docks' }" @click="setTab('docks')">机巢设备<b>{{ devices.docks.length }}</b></button> |
|
|
|
<button class="asset-tab" :class="{ active: tab === 'drones' }" @click="setTab('drones')">无人机<b>{{ devices.drones.length }}</b></button> |
|
|
|
</div> |
|
|
|
<t-tabs v-model="tab" class="device-asset-tabs" @change="onTabChange"> |
|
|
|
<t-tab-panel value="docks" :label="docksTabLabel" :destroy-on-hide="false" /> |
|
|
|
<t-tab-panel value="drones" :label="dronesTabLabel" :destroy-on-hide="false" /> |
|
|
|
</t-tabs> |
|
|
|
|
|
|
|
<div class="asset-toolbar"> |
|
|
|
<div class="asset-search"> |
|
|
|
@ -39,83 +39,53 @@ |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="asset-table-wrap"> |
|
|
|
<table class="asset-table"> |
|
|
|
<thead> |
|
|
|
<tr v-if="tab === 'docks'"> |
|
|
|
<th style="width:18%">机巢设备</th> |
|
|
|
<th>状态</th> |
|
|
|
<th>绑定无人机</th> |
|
|
|
<th>控制模式</th> |
|
|
|
<th>设备位置</th> |
|
|
|
<th>软件版本</th> |
|
|
|
<th>最近上报</th> |
|
|
|
<th style="width:20%">操作</th> |
|
|
|
</tr> |
|
|
|
<tr v-else> |
|
|
|
<th style="width:18%">无人机</th> |
|
|
|
<th>状态</th> |
|
|
|
<th>所属机巢</th> |
|
|
|
<th>电量</th> |
|
|
|
<th>飞行模式</th> |
|
|
|
<th>当前任务</th> |
|
|
|
<th>最近上报</th> |
|
|
|
<th style="width:22%">操作</th> |
|
|
|
</tr> |
|
|
|
</thead> |
|
|
|
<tbody v-if="tab === 'docks'"> |
|
|
|
<tr v-for="d in filteredDocks" :key="d.id" @click="openDrawer(d.id)"> |
|
|
|
<td> |
|
|
|
<div class="asset-name-cell"> |
|
|
|
<span class="table-asset-icon"><svg><use href="#i-home" /></svg></span> |
|
|
|
<span><strong>{{ d.name }}</strong><small>{{ d.code }}</small></span> |
|
|
|
</div> |
|
|
|
</td> |
|
|
|
<td><span class="table-status" :class="d.statusClass"><i></i>{{ d.status }}</span></td> |
|
|
|
<td><span class="binding-cell" :class="{ unbound: d.bindingState === 'unbound' }"><svg><use href="#i-link" /></svg>{{ d.binding }}</span></td> |
|
|
|
<td>{{ d.mode }}</td> |
|
|
|
<td>{{ d.location }}</td> |
|
|
|
<td>{{ d.version }}</td> |
|
|
|
<td>{{ d.updated }}</td> |
|
|
|
<td> |
|
|
|
<div class="row-actions"> |
|
|
|
<t-button v-if="!isAdmin" variant="text" theme="primary" @click.stop="openFirmwareUpgrade(d.id)">固件升级</t-button> |
|
|
|
<t-button v-if="!isAdmin" variant="text" theme="primary" @click.stop="goControl(d.id)">远程控制</t-button> |
|
|
|
<t-button variant="text" theme="primary" @click.stop="goDetail(d.id)">详情</t-button> |
|
|
|
<t-button v-if="!isAdmin" variant="text" theme="danger" @click.stop="deleteDock(d)">删除</t-button> |
|
|
|
</div> |
|
|
|
</td> |
|
|
|
</tr> |
|
|
|
<tr v-if="!filteredDocks.length"><td class="table-empty" colspan="8">暂无符合条件的设备</td></tr> |
|
|
|
</tbody> |
|
|
|
<tbody v-else> |
|
|
|
<tr v-for="d in filteredDrones" :key="d.id" @click="openDrawer(d.id)"> |
|
|
|
<td> |
|
|
|
<t-table |
|
|
|
row-key="id" |
|
|
|
:data="tableData" |
|
|
|
:columns="tableColumns" |
|
|
|
empty="暂无符合条件的设备" |
|
|
|
hover |
|
|
|
@row-click="handleRowClick" |
|
|
|
> |
|
|
|
<template #name="{ row }"> |
|
|
|
<div class="asset-name-cell"> |
|
|
|
<span class="table-asset-icon drone"><svg><use href="#i-plane" /></svg></span> |
|
|
|
<span><strong>{{ d.name }}</strong><small>{{ d.code }}</small></span> |
|
|
|
<span class="table-asset-icon" :class="{ drone: tab === 'drones' }"> |
|
|
|
<svg><use :href="tab === 'drones' ? '#i-plane' : '#i-home'" /></svg> |
|
|
|
</span> |
|
|
|
<span><strong>{{ row.name }}</strong><small>{{ row.code }}</small></span> |
|
|
|
</div> |
|
|
|
</td> |
|
|
|
<td><span class="table-status" :class="d.statusClass"><i></i>{{ d.status }}</span></td> |
|
|
|
<td><span class="binding-cell"><svg><use href="#i-link" /></svg>{{ d.binding }}</span></td> |
|
|
|
<td>{{ d.battery }}</td> |
|
|
|
<td>{{ d.mode }}</td> |
|
|
|
<td>{{ d.mission }}</td> |
|
|
|
<td>{{ d.updated }}</td> |
|
|
|
<td> |
|
|
|
<div class="row-actions"> |
|
|
|
<t-button v-if="!isAdmin" variant="text" theme="primary" @click.stop="ui.toast('请选择航线后上传')">航线上传</t-button> |
|
|
|
<t-button v-if="!isAdmin" variant="text" theme="primary" @click.stop="goControl(d.id)">远程控制</t-button> |
|
|
|
<t-button variant="text" theme="primary" @click.stop="goDetail(d.id)">详情</t-button> |
|
|
|
</template> |
|
|
|
<template #status="{ row }"> |
|
|
|
<span class="table-status" :class="row.statusClass"><i></i>{{ row.status }}</span> |
|
|
|
</template> |
|
|
|
<template #binding="{ row }"> |
|
|
|
<span |
|
|
|
class="binding-cell" |
|
|
|
:class="{ unbound: tab === 'docks' && row.bindingState === 'unbound' }" |
|
|
|
> |
|
|
|
<svg><use href="#i-link" /></svg>{{ row.binding }} |
|
|
|
</span> |
|
|
|
</template> |
|
|
|
<template #actions="{ row }"> |
|
|
|
<div class="row-actions" @click.stop> |
|
|
|
<template v-if="tab === 'docks'"> |
|
|
|
<t-button v-if="!isAdmin" variant="text" theme="primary" @click="openFirmwareUpgrade(row.id)">固件升级</t-button> |
|
|
|
<t-button v-if="!isAdmin" variant="text" theme="primary" @click="goControl(row.id)">远程控制</t-button> |
|
|
|
<t-button variant="text" theme="primary" @click="goDetail(row.id)">详情</t-button> |
|
|
|
<t-button v-if="!isAdmin" variant="text" theme="danger" @click="deleteDock(row)">删除</t-button> |
|
|
|
</template> |
|
|
|
<template v-else> |
|
|
|
<t-button v-if="!isAdmin" variant="text" theme="primary" @click="ui.toast('请选择航线后上传')">航线上传</t-button> |
|
|
|
<t-button v-if="!isAdmin" variant="text" theme="primary" @click="goControl(row.id)">远程控制</t-button> |
|
|
|
<t-button variant="text" theme="primary" @click="goDetail(row.id)">详情</t-button> |
|
|
|
</template> |
|
|
|
</div> |
|
|
|
</td> |
|
|
|
</tr> |
|
|
|
<tr v-if="!filteredDrones.length"><td class="table-empty" colspan="8">暂无符合条件的设备</td></tr> |
|
|
|
</tbody> |
|
|
|
</table> |
|
|
|
</template> |
|
|
|
</t-table> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="table-footer"> |
|
|
|
<span>共 {{ tab === 'docks' ? filteredDocks.length : filteredDrones.length }} 条</span> |
|
|
|
<span>共 {{ tableData.length }} 条</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
@ -353,17 +323,48 @@ function matchesFilters(d) { |
|
|
|
const haystack = [d.name, d.code, d.sn, d.location, d.binding].filter(Boolean).join(' ').toLowerCase() |
|
|
|
return haystack.includes(q) |
|
|
|
} |
|
|
|
const docksTabLabel = computed(() => `机巢设备 ${devices.docks.length}`) |
|
|
|
const dronesTabLabel = computed(() => `无人机 ${devices.drones.length}`) |
|
|
|
|
|
|
|
const dockColumns = [ |
|
|
|
{ colKey: 'name', title: '机巢设备', width: '18%' }, |
|
|
|
{ colKey: 'status', title: '状态' }, |
|
|
|
{ colKey: 'binding', title: '绑定无人机' }, |
|
|
|
{ colKey: 'mode', title: '控制模式' }, |
|
|
|
{ colKey: 'location', title: '设备位置' }, |
|
|
|
{ colKey: 'version', title: '软件版本' }, |
|
|
|
{ colKey: 'updated', title: '最近上报' }, |
|
|
|
{ colKey: 'actions', title: '操作', width: '20%' } |
|
|
|
] |
|
|
|
|
|
|
|
const droneColumns = [ |
|
|
|
{ colKey: 'name', title: '无人机', width: '18%' }, |
|
|
|
{ colKey: 'status', title: '状态' }, |
|
|
|
{ colKey: 'binding', title: '所属机巢' }, |
|
|
|
{ colKey: 'battery', title: '电量' }, |
|
|
|
{ colKey: 'mode', title: '飞行模式' }, |
|
|
|
{ colKey: 'mission', title: '当前任务' }, |
|
|
|
{ colKey: 'updated', title: '最近上报' }, |
|
|
|
{ colKey: 'actions', title: '操作', width: '22%' } |
|
|
|
] |
|
|
|
|
|
|
|
const tableColumns = computed(() => (tab.value === 'docks' ? dockColumns : droneColumns)) |
|
|
|
const tableData = computed(() => (tab.value === 'docks' ? filteredDocks.value : filteredDrones.value)) |
|
|
|
|
|
|
|
|
|
|
|
const filteredDocks = computed(() => devices.docks.filter(matchesFilters)) |
|
|
|
|
|
|
|
const filteredDrones = computed(() => devices.drones.filter(matchesFilters)) |
|
|
|
|
|
|
|
function setTab(next) { |
|
|
|
tab.value = next |
|
|
|
function onTabChange() { |
|
|
|
resetFilters() |
|
|
|
drawerOpen.value = false |
|
|
|
} |
|
|
|
|
|
|
|
function handleRowClick({ row }) { |
|
|
|
openDrawer(row.id) |
|
|
|
} |
|
|
|
|
|
|
|
function resetFilters() { |
|
|
|
search.value = '' |
|
|
|
statusFilter.value = '' |
|
|
|
@ -557,6 +558,18 @@ async function doUpgrade() { |
|
|
|
.drawer-section-title :deep(.t-button) { |
|
|
|
font-size: 11px; |
|
|
|
} |
|
|
|
.device-asset-tabs :deep(.t-tabs__nav-container) { |
|
|
|
padding: 0 18px; |
|
|
|
} |
|
|
|
.device-asset-tabs :deep(.t-tabs__nav-wrap) { |
|
|
|
margin-left: 0; |
|
|
|
} |
|
|
|
.asset-table-wrap :deep(.t-table) { |
|
|
|
background: transparent; |
|
|
|
} |
|
|
|
.asset-table-wrap :deep(.t-table__body tr) { |
|
|
|
cursor: pointer; |
|
|
|
} |
|
|
|
</style> |
|
|
|
|
|
|
|
<style> |
|
|
|
|