UAV/src/pages/uav.vue
18796357645 5a255f7068 ADD
2025-07-17 10:13:33 +08:00

412 lines
9.3 KiB
Vue

<template>
<div class="drone-management">
<div class="header">
<h2>无人机管理</h2>
<div class="operation-buttons">
<el-button type="primary" @click="handleAdd">
<el-icon>
<Plus />
</el-icon>
添加无人机
</el-button>
<el-button type="danger" :disabled="!selectedIds.length" @click="handleBatchDelete">
<el-icon>
<Delete />
</el-icon>
批量删除
</el-button>
</div>
</div>
<div class="filter-container">
<el-input
v-model="listQuery.keyword"
placeholder="搜索无人机名称/型号"
style="width: 300px"
clearable
@keyup.enter="handleFilter"
>
<template #append>
<el-button :icon="Search" @click="handleFilter" />
</template>
</el-input>
<el-select
v-model="listQuery.status"
placeholder="状态筛选"
clearable
style="width: 120px; margin-left: 10px"
>
<el-option label="在线" value="online" />
<el-option label="离线" value="offline" />
<el-option label="维修中" value="maintenance" />
</el-select>
</div>
<el-table
v-loading="listLoading"
:data="droneList"
border
fit
highlight-current-row
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column prop="id" label="ID" width="80" align="center" />
<el-table-column prop="name" label="无人机名称" min-width="120" />
<el-table-column prop="model" label="型号" width="150" />
<el-table-column prop="sn" label="序列号" width="180" />
<el-table-column label="状态" width="100" align="center">
<template #default="{ row }">
<el-tag :type="statusType[row.status]">
{{ statusMap[row.status] }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="battery" label="电量" width="100" align="center">
<template #default="{ row }">
<el-progress
:percentage="row.battery"
:color="batteryColor(row.battery)"
:show-text="false"
:stroke-width="18"
/>
{{ row.battery }}%
</template>
</el-table-column>
<el-table-column prop="lastConnectTime" label="最后连接时间" width="180" />
<el-table-column label="操作" width="180" align="center" fixed="right">
<template #default="{ row }">
<el-button size="small" @click="handleEdit(row)">
<el-icon>
<Edit />
</el-icon>
</el-button>
<el-button size="small" type="danger" @click="handleDelete(row)">
<el-icon>
<Delete />
</el-icon>
</el-button>
<el-button size="small" type="warning" @click="handleControl(row)">
<el-icon>
<Connection />
</el-icon>
</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination-container">
<el-pagination
v-model:current-page="listQuery.page"
v-model:page-size="listQuery.limit"
:total="total"
:page-sizes="[10, 20, 30, 50]"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
<!-- 添加/编辑对话框 -->
<el-dialog
v-model="dialogVisible"
:title="dialogType === 'edit' ? '编辑无人机' : '添加无人机'"
width="600px"
>
<el-form
ref="droneForm"
:model="droneForm"
:rules="droneRules"
label-width="100px"
>
<el-form-item label="无人机名称" prop="name">
<el-input v-model="droneForm.name" placeholder="请输入无人机名称" />
</el-form-item>
<el-form-item label="无人机型号" prop="model">
<el-input v-model="droneForm.model" placeholder="请输入无人机型号" />
</el-form-item>
<el-form-item label="序列号" prop="sn">
<el-input v-model="droneForm.sn" placeholder="请输入序列号" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="droneForm.status" placeholder="请选择状态">
<el-option
v-for="item in statusOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmDrone">确认</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useRouter } from 'vue-router'
import {
Plus,
Delete,
Edit,
Search,
Connection
} from '@element-plus/icons-vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const router = useRouter()
// 状态映射
const statusMap = {
online: '在线',
offline: '离线',
maintenance: '维修中'
}
const statusType = {
online: 'success',
offline: 'danger',
maintenance: 'warning'
}
const statusOptions = [
{ value: 'online', label: '在线' },
{ value: 'offline', label: '离线' },
{ value: 'maintenance', label: '维修中' }
]
// 电池颜色
const batteryColor = (percentage) => {
if (percentage > 70) return '#67C23A'
if (percentage > 30) return '#E6A23C'
return '#F56C6C'
}
// 列表相关
const listLoading = ref(false)
const droneList = ref([])
const total = ref(0)
const selectedIds = ref([])
const listQuery = reactive({
page: 1,
limit: 10,
keyword: '',
status: ''
})
// 表单相关
const dialogVisible = ref(false)
const dialogType = ref('add')
const droneForm = reactive({
id: '',
name: '',
model: '',
sn: '',
status: 'online',
battery: 100
})
const droneRules = reactive({
name: [{ required: true, message: '请输入无人机名称', trigger: 'blur' }],
model: [{ required: true, message: '请输入无人机型号', trigger: 'blur' }],
sn: [{ required: true, message: '请输入序列号', trigger: 'blur' }],
status: [{ required: true, message: '请选择状态', trigger: 'change' }]
})
// 获取无人机列表
const fetchDrones = async () => {
listLoading.value = true
try {
// 这里替换为实际API调用
// const res = await getDroneList(listQuery)
// 模拟数据
setTimeout(() => {
droneList.value = [
{
id: 1,
name: '巡检无人机1号',
model: 'DJI Mavic 3',
sn: 'DJI123456789',
status: 'online',
battery: 85,
lastConnectTime: '2023-05-15 14:30:22'
},
{
id: 2,
name: '测绘无人机A',
model: 'DJI Phantom 4 RTK',
sn: 'DJI987654321',
status: 'offline',
battery: 25,
lastConnectTime: '2023-05-14 09:15:33'
},
{
id: 3,
name: '应急无人机',
model: 'DJI Matrice 300',
sn: 'DJI456789123',
status: 'maintenance',
battery: 0,
lastConnectTime: '2023-05-10 16:45:12'
}
].slice(
(listQuery.page - 1) * listQuery.limit,
listQuery.page * listQuery.limit
)
total.value = 3
listLoading.value = false
}, 500)
} catch (error) {
console.error(error)
listLoading.value = false
}
}
// 表格选择
const handleSelectionChange = (selection) => {
selectedIds.value = selection.map((item) => item.id)
}
// 筛选
const handleFilter = () => {
listQuery.page = 1
fetchDrones()
}
// 分页
const handleSizeChange = (val) => {
listQuery.limit = val
fetchDrones()
}
const handleCurrentChange = (val) => {
listQuery.page = val
fetchDrones()
}
// 添加无人机
const handleAdd = () => {
dialogType.value = 'add'
Object.assign(droneForm, {
id: '',
name: '',
model: '',
sn: '',
status: 'online',
battery: 100
})
dialogVisible.value = true
}
// 编辑无人机
const handleEdit = (row) => {
dialogType.value = 'edit'
Object.assign(droneForm, row)
dialogVisible.value = true
}
// 删除无人机
const handleDelete = (row) => {
ElMessageBox.confirm(`确认删除无人机 "${row.name}"?`, '警告', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
// 这里替换为实际API调用
// await deleteDrone(row.id)
ElMessage.success('删除成功')
fetchDrones()
})
.catch(() => {
})
}
// 批量删除
const handleBatchDelete = () => {
ElMessageBox.confirm(`确认删除选中的 ${selectedIds.value.length} 台无人机?`, '警告', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
// 这里替换为实际API调用
// await batchDeleteDrones(selectedIds.value)
ElMessage.success('删除成功')
selectedIds.value = []
fetchDrones()
})
.catch(() => {
})
}
// 控制无人机
const handleControl = (row) => {
ElMessage.info(`正在连接无人机 ${row.name}...`)
// 这里可以跳转到控制页面或打开控制对话框
router.push(`${row.id}`)
}
// 确认表单
const confirmDrone = () => {
// 这里替换为实际表单验证和API调用
ElMessage.success(
dialogType.value === 'add' ? '添加成功' : '更新成功'
)
dialogVisible.value = false
fetchDrones()
}
onMounted(() => {
fetchDrones()
})
</script>
<style scoped lang="scss">
.drone-management {
padding: 20px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.filter-container {
margin-bottom: 20px;
}
.pagination-container {
margin-top: 20px;
display: flex;
justify-content: flex-end;
}
.el-table {
margin-top: 20px;
}
.el-tag {
margin-right: 0;
}
.el-progress {
display: inline-block;
width: 80px;
margin-right: 10px;
vertical-align: middle;
}
</style>