519 lines
11 KiB
Vue
519 lines
11 KiB
Vue
<template>
|
|
<div class="dashboard-container">
|
|
<!-- 顶部导航栏 -->
|
|
<el-header class="header">
|
|
<div class="logo">
|
|
<!-- <img src="@/assets/logo.png" alt="无人机管理系统" class="logo-img">-->
|
|
<h1 class="title">无人机管理系统</h1>
|
|
</div>
|
|
<div class="header-right">
|
|
<el-tooltip content="消息通知" placement="bottom">
|
|
<el-badge :value="12" class="notification-badge">
|
|
<el-icon :size="20">
|
|
<Bell />
|
|
</el-icon>
|
|
</el-badge>
|
|
</el-tooltip>
|
|
<el-dropdown class="user-dropdown">
|
|
<div class="user-info">
|
|
<el-avatar :size="36" src="@/assets/user-avatar.png" />
|
|
<span class="username">管理员</span>
|
|
<el-icon class="dropdown-icon">
|
|
<ArrowDown />
|
|
</el-icon>
|
|
</div>
|
|
<template #dropdown>
|
|
<el-dropdown-menu>
|
|
<el-dropdown-item>
|
|
<el-icon>
|
|
<User />
|
|
</el-icon>
|
|
个人中心
|
|
</el-dropdown-item>
|
|
<el-dropdown-item>
|
|
<el-icon>
|
|
<Setting />
|
|
</el-icon>
|
|
系统设置
|
|
</el-dropdown-item>
|
|
<el-dropdown-item divided>
|
|
<el-icon>
|
|
<SwitchButton />
|
|
</el-icon>
|
|
退出登录
|
|
</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</template>
|
|
</el-dropdown>
|
|
</div>
|
|
</el-header>
|
|
|
|
<!-- 主内容区 -->
|
|
<el-main class="main-content">
|
|
<!-- 状态卡片 -->
|
|
<div class="status-cards">
|
|
<el-row :gutter="20">
|
|
<el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
|
|
<el-card shadow="hover" class="status-card">
|
|
<div class="card-content">
|
|
<div class="card-icon bg-blue">
|
|
<el-icon :size="28">
|
|
<Collection />
|
|
</el-icon>
|
|
</div>
|
|
<div class="card-info">
|
|
<div class="card-title">无人机总数</div>
|
|
<div class="card-value">24</div>
|
|
<div class="card-trend">
|
|
<span class="trend-up">↑ 2.5%</span>
|
|
<span class="trend-text">较上月</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</el-col>
|
|
<el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
|
|
<el-card shadow="hover" class="status-card">
|
|
<div class="card-content">
|
|
<div class="card-icon bg-green">
|
|
<el-icon :size="28">
|
|
<Check />
|
|
</el-icon>
|
|
</div>
|
|
<div class="card-info">
|
|
<div class="card-title">可用无人机</div>
|
|
<div class="card-value">18</div>
|
|
<div class="card-trend">
|
|
<span class="trend-up">↑ 5.8%</span>
|
|
<span class="trend-text">较上周</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</el-col>
|
|
<el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
|
|
<el-card shadow="hover" class="status-card">
|
|
<div class="card-content">
|
|
<div class="card-icon bg-orange">
|
|
<el-icon :size="28">
|
|
<Warning />
|
|
</el-icon>
|
|
</div>
|
|
<div class="card-info">
|
|
<div class="card-title">任务中</div>
|
|
<div class="card-value">5</div>
|
|
<div class="card-trend">
|
|
<span class="trend-down">↓ 1.2%</span>
|
|
<span class="trend-text">较昨日</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</el-col>
|
|
<el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
|
|
<el-card shadow="hover" class="status-card">
|
|
<div class="card-content">
|
|
<div class="card-icon bg-purple">
|
|
<el-icon :size="28">
|
|
<Clock />
|
|
</el-icon>
|
|
</div>
|
|
<div class="card-info">
|
|
<div class="card-title">待处理任务</div>
|
|
<div class="card-value">8</div>
|
|
<div class="card-trend">
|
|
<span class="trend-up">↑ 3.1%</span>
|
|
<span class="trend-text">较昨日</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
|
|
<!-- 图表区域 -->
|
|
<div class="chart-area">
|
|
<el-row :gutter="20">
|
|
<el-col :span="16">
|
|
<el-card shadow="hover" class="chart-card">
|
|
<template #header>
|
|
<div class="card-header">
|
|
<span>无人机任务统计</span>
|
|
<el-select v-model="chartTimeRange" class="time-select" size="small">
|
|
<el-option label="本周" value="week" />
|
|
<el-option label="本月" value="month" />
|
|
<el-option label="本季度" value="quarter" />
|
|
</el-select>
|
|
</div>
|
|
</template>
|
|
<div class="chart-container">
|
|
<!-- 这里放置echarts图表 -->
|
|
<div class="mock-chart" style="height: 300px;">
|
|
<div class="mock-chart-placeholder">
|
|
<el-icon :size="48">
|
|
<DataLine />
|
|
</el-icon>
|
|
<p>任务统计图表</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</el-col>
|
|
<el-col :span="8">
|
|
<el-card shadow="hover" class="chart-card">
|
|
<template #header>
|
|
<div class="card-header">
|
|
<span>无人机状态分布</span>
|
|
</div>
|
|
</template>
|
|
<div class="chart-container">
|
|
<!-- 这里放置饼图 -->
|
|
<div class="mock-chart" style="height: 300px;">
|
|
<div class="mock-chart-placeholder">
|
|
<el-icon :size="48">
|
|
<PieChart />
|
|
</el-icon>
|
|
<p>状态分布图表</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
|
|
<!-- 最近任务列表 -->
|
|
<div class="task-list">
|
|
<el-card shadow="hover">
|
|
<template #header>
|
|
<div class="card-header">
|
|
<span>最近任务</span>
|
|
<el-button type="primary" size="small" :icon="Refresh" @click="refreshTasks">刷新</el-button>
|
|
</div>
|
|
</template>
|
|
<el-table :data="recentTasks" style="width: 100%" stripe>
|
|
<el-table-column prop="id" label="任务ID" width="100" />
|
|
<el-table-column prop="name" label="任务名称" />
|
|
<el-table-column prop="drone" label="无人机" width="120" />
|
|
<el-table-column prop="startTime" label="开始时间" width="180" />
|
|
<el-table-column prop="endTime" label="结束时间" width="180" />
|
|
<el-table-column prop="status" label="状态" width="120">
|
|
<template #default="{ row }">
|
|
<el-tag :type="getStatusTagType(row.status)" size="small">
|
|
{{ row.status }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="操作" width="120">
|
|
<template #default>
|
|
<el-button type="text" size="small">详情</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<div class="pagination">
|
|
<el-pagination
|
|
small
|
|
layout="prev, pager, next"
|
|
:total="50"
|
|
:page-size="5"
|
|
@current-change="handlePageChange"
|
|
/>
|
|
</div>
|
|
</el-card>
|
|
</div>
|
|
</el-main>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
import {
|
|
Bell,
|
|
ArrowDown,
|
|
User,
|
|
Setting,
|
|
SwitchButton,
|
|
Collection,
|
|
Check,
|
|
Warning,
|
|
Clock,
|
|
DataLine,
|
|
PieChart,
|
|
Refresh
|
|
} from '@element-plus/icons-vue'
|
|
|
|
// 图表时间范围选择
|
|
const chartTimeRange = ref('week')
|
|
|
|
// 最近任务数据
|
|
const recentTasks = ref([
|
|
{
|
|
id: 'T20230701',
|
|
name: '农田巡查-东部区域',
|
|
drone: 'DJI-001',
|
|
startTime: '2023-07-01 08:30',
|
|
endTime: '2023-07-01 11:45',
|
|
status: '已完成'
|
|
},
|
|
{
|
|
id: 'T20230702',
|
|
name: '电力线路检查',
|
|
drone: 'DJI-003',
|
|
startTime: '2023-07-02 09:00',
|
|
endTime: '2023-07-02 12:15',
|
|
status: '已完成'
|
|
},
|
|
{
|
|
id: 'T20230703',
|
|
name: '建筑工地监测',
|
|
drone: 'DJI-002',
|
|
startTime: '2023-07-03 10:30',
|
|
endTime: '2023-07-03 14:20',
|
|
status: '进行中'
|
|
},
|
|
{
|
|
id: 'T20230704',
|
|
name: '森林防火巡查',
|
|
drone: 'DJI-005',
|
|
startTime: '2023-07-04 13:00',
|
|
endTime: '2023-07-04 16:30',
|
|
status: '已计划'
|
|
},
|
|
{
|
|
id: 'T20230705',
|
|
name: '交通路况监测',
|
|
drone: 'DJI-004',
|
|
startTime: '2023-07-05 07:45',
|
|
endTime: '2023-07-05 10:15',
|
|
status: '已取消'
|
|
}
|
|
])
|
|
|
|
// 获取状态标签类型
|
|
const getStatusTagType = (status: string) => {
|
|
switch (status) {
|
|
case '已完成':
|
|
return 'success'
|
|
case '进行中':
|
|
return 'primary'
|
|
case '已计划':
|
|
return 'info'
|
|
case '已取消':
|
|
return 'danger'
|
|
default:
|
|
return 'warning'
|
|
}
|
|
}
|
|
|
|
// 刷新任务
|
|
const refreshTasks = () => {
|
|
console.log('刷新任务数据')
|
|
}
|
|
|
|
// 分页变化
|
|
const handlePageChange = (currentPage: number) => {
|
|
console.log('当前页:', currentPage)
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.dashboard-container {
|
|
height: 100vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background-color: #f5f7fa;
|
|
}
|
|
|
|
/* 头部样式 */
|
|
.header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
height: 60px;
|
|
padding: 0 20px;
|
|
background-color: #fff;
|
|
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
|
}
|
|
|
|
.logo {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.logo-img {
|
|
width: 32px;
|
|
height: 32px;
|
|
margin-right: 10px;
|
|
}
|
|
|
|
.title {
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
color: #333;
|
|
margin: 0;
|
|
}
|
|
|
|
.header-right {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.notification-badge {
|
|
margin-right: 20px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.user-dropdown {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.user-info {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.username {
|
|
margin: 0 8px 0 12px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.dropdown-icon {
|
|
font-size: 12px;
|
|
}
|
|
|
|
/* 主内容区样式 */
|
|
.main-content {
|
|
flex: 1;
|
|
padding: 20px;
|
|
overflow: auto;
|
|
}
|
|
|
|
/* 状态卡片样式 */
|
|
.status-cards {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.status-card {
|
|
margin-bottom: 20px;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.card-content {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.card-icon {
|
|
width: 56px;
|
|
height: 56px;
|
|
border-radius: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 16px;
|
|
}
|
|
|
|
.bg-blue {
|
|
background-color: #f0f7ff;
|
|
color: #409EFF;
|
|
}
|
|
|
|
.bg-green {
|
|
background-color: #f0f9eb;
|
|
color: #67C23A;
|
|
}
|
|
|
|
.bg-orange {
|
|
background-color: #fdf6ec;
|
|
color: #E6A23C;
|
|
}
|
|
|
|
.bg-purple {
|
|
background-color: #f9f0ff;
|
|
color: #8E44AD;
|
|
}
|
|
|
|
.card-info {
|
|
flex: 1;
|
|
}
|
|
|
|
.card-title {
|
|
font-size: 14px;
|
|
color: #909399;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.card-value {
|
|
font-size: 24px;
|
|
font-weight: bold;
|
|
color: #303133;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.card-trend {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.trend-up {
|
|
color: #67C23A;
|
|
margin-right: 4px;
|
|
}
|
|
|
|
.trend-down {
|
|
color: #F56C6C;
|
|
margin-right: 4px;
|
|
}
|
|
|
|
.trend-text {
|
|
color: #909399;
|
|
}
|
|
|
|
/* 图表区域样式 */
|
|
.chart-area {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.chart-card {
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.card-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.time-select {
|
|
width: 120px;
|
|
}
|
|
|
|
.chart-container {
|
|
padding: 10px;
|
|
}
|
|
|
|
.mock-chart {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background-color: #fafafa;
|
|
border-radius: 4px;
|
|
color: #909399;
|
|
}
|
|
|
|
.mock-chart-placeholder {
|
|
text-align: center;
|
|
}
|
|
|
|
/* 任务列表样式 */
|
|
.task-list {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.pagination {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
margin-top: 15px;
|
|
}
|
|
</style>
|