Browse Source

feat: 设备管理页签与列表切换到 TDesign

main
xiaosi 3 weeks ago
parent
commit
2639f3bcb2
  1. 167
      src/views/DevicesView/DevicesView.vue

167
src/views/DevicesView/DevicesView.vue

@ -20,10 +20,10 @@
</div> </div>
<div class="asset-workspace"> <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-toolbar">
<div class="asset-search"> <div class="asset-search">
@ -39,83 +39,53 @@
</div> </div>
<div class="asset-table-wrap"> <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"> <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> </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> </div>
</td>
</tr>
<tr v-if="!filteredDrones.length"><td class="table-empty" colspan="8">暂无符合条件的设备</td></tr>
</tbody>
</table>
</template>
</t-table>
</div> </div>
<div class="table-footer"> <div class="table-footer">
<span> {{ tab === 'docks' ? filteredDocks.length : filteredDrones.length }} </span>
<span> {{ tableData.length }} </span>
</div> </div>
</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() const haystack = [d.name, d.code, d.sn, d.location, d.binding].filter(Boolean).join(' ').toLowerCase()
return haystack.includes(q) 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 filteredDocks = computed(() => devices.docks.filter(matchesFilters))
const filteredDrones = computed(() => devices.drones.filter(matchesFilters)) const filteredDrones = computed(() => devices.drones.filter(matchesFilters))
function setTab(next) {
tab.value = next
function onTabChange() {
resetFilters() resetFilters()
drawerOpen.value = false drawerOpen.value = false
} }
function handleRowClick({ row }) {
openDrawer(row.id)
}
function resetFilters() { function resetFilters() {
search.value = '' search.value = ''
statusFilter.value = '' statusFilter.value = ''
@ -557,6 +558,18 @@ async function doUpgrade() {
.drawer-section-title :deep(.t-button) { .drawer-section-title :deep(.t-button) {
font-size: 11px; 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>
<style> <style>

Loading…
Cancel
Save