376 lines
8.2 KiB
Vue

<script setup lang="ts">
import { ref, onMounted } from "vue";
import * as echarts from "echarts";
const welcomeText = ref("欢迎使用智慧湿地管理平台");
// 统计数据
const statistics = ref({
species: {
total: 128,
today: 12,
trend: "+8%",
},
environment: {
normal: 22,
abnormal: 2,
trend: "normal",
},
patrol: {
total: 12,
completed: 8,
progress: "66%",
},
devices: {
total: 36,
online: 32,
rate: "88.9%",
},
});
// 初始化趋势图表
const initTrendChart = () => {
const chartDom = document.getElementById("trendChart");
if (!chartDom) return;
const myChart = echarts.init(chartDom);
const option = {
title: {
text: "近7天监测数据趋势",
left: "center",
top: 0,
textStyle: {
fontSize: 16,
fontWeight: 500,
},
},
tooltip: {
trigger: "axis",
},
legend: {
data: ["物种数量", "水质指数"],
top: 25,
},
grid: {
top: 70,
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
xAxis: {
type: "category",
boundaryGap: false,
data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
},
yAxis: {
type: "value",
},
series: [
{
name: "物种数量",
type: "line",
data: [120, 132, 101, 134, 90, 230, 210],
smooth: true,
},
{
name: "水质指数",
type: "line",
data: [220, 182, 191, 234, 290, 330, 310],
smooth: true,
},
],
};
myChart.setOption(option);
};
// 初始化分布图表
const initDistributionChart = () => {
const chartDom = document.getElementById("distributionChart");
if (!chartDom) return;
const myChart = echarts.init(chartDom);
const option = {
title: {
text: "物种分布统计",
left: "center",
top: 0,
textStyle: {
fontSize: 16,
fontWeight: 500,
},
},
tooltip: {
trigger: "item",
},
legend: {
orient: "vertical",
left: "left",
top: 25,
},
series: [
{
name: "物种分布",
type: "pie",
radius: "50%",
top: 60,
data: [
{ value: 1048, name: "鸟类" },
{ value: 735, name: "鱼类" },
{ value: 580, name: "两栖类" },
{ value: 484, name: "植物" },
{ value: 300, name: "其他" },
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 0.5)",
},
},
},
],
};
myChart.setOption(option);
};
// 最新动态
const activities = ref([
{
content: "发现新增鸟类物种:东方白鹳",
timestamp: "2024-03-20 10:30",
type: "success",
},
{
content: "B区水质监测点发现异常",
timestamp: "2024-03-20 09:15",
type: "warning",
},
{
content: "完成今日巡护任务",
timestamp: "2024-03-20 08:00",
type: "success",
},
]);
onMounted(() => {
initTrendChart();
initDistributionChart();
});
</script>
<template>
<div class="dashboard-container">
<div class="welcome-section">
<h2>{{ welcomeText }}</h2>
</div>
<!-- 统计卡片 -->
<el-row :gutter="20" class="mt-20">
<el-col :span="8">
<el-card
class="statistics-card"
shadow="hover"
@click="handleCardClick('/monitor/species')"
>
<template #header>
<div class="statistics-header">
<span>物种监测</span>
<el-tag size="small" type="success">{{ statistics.species.trend }}</el-tag>
</div>
</template>
<div class="statistics-content">
<div class="main-number">{{ statistics.species.total }}</div>
<div class="sub-info">
<span>今日新增</span>
<span class="highlight">{{ statistics.species.today }}</span>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card
class="statistics-card"
shadow="hover"
>
<template #header>
<div class="statistics-header">
<span>环境监测</span>
<el-tag
size="small"
type="warning"
v-if="statistics.environment.abnormal > 0"
>
{{ statistics.environment.abnormal }}个异常
</el-tag>
</div>
</template>
<div class="statistics-content">
<div class="main-number">{{ statistics.environment.normal }}</div>
<div class="sub-info">
<span>监测点位</span>
<span class="highlight">正常</span>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card
class="statistics-card"
shadow="hover"
@click="handleCardClick('/patrol/tasks')"
>
<template #header>
<div class="statistics-header">
<span>巡护任务</span>
<el-tag size="small" type="info">{{ statistics.patrol.progress }}</el-tag>
</div>
</template>
<div class="statistics-content">
<div class="main-number">{{ statistics.patrol.completed }}</div>
<div class="sub-info">
<span>已完成</span>
<span class="highlight">共{{ statistics.patrol.total }}个</span>
</div>
</div>
</el-card>
</el-col>
</el-row>
<!-- 图表区域 -->
<el-row :gutter="20" class="mt-20">
<el-col :span="16">
<el-card>
<div id="trendChart" style="height: 400px; padding-top: 10px"></div>
</el-card>
</el-col>
<el-col :span="8">
<el-card>
<div id="distributionChart" style="height: 400px; padding-top: 10px"></div>
</el-card>
</el-col>
</el-row>
<!-- 最新动态 -->
<el-row :gutter="20" class="mt-20">
<el-col :span="24">
<el-card>
<template #header>
<div class="card-header">
<span>最新动态</span>
</div>
</template>
<el-timeline>
<el-timeline-item
v-for="(activity, index) in activities"
:key="index"
:type="activity.type"
:timestamp="activity.timestamp"
>
{{ activity.content }}
</el-timeline-item>
</el-timeline>
</el-card>
</el-col>
</el-row>
</div>
</template>
<style lang="scss" scoped>
@import "../../styles/variables.scss";
.dashboard-container {
.welcome-card {
background: linear-gradient(
135deg,
$primary-color 0%,
lighten($primary-color, 20%) 100%
);
padding: 24px;
border-radius: 8px;
color: white;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
h2 {
margin: 0;
font-size: 24px;
font-weight: 500;
}
.welcome-subtitle {
margin: 8px 0 0;
opacity: 0.8;
}
}
.statistics-card {
transition: transform 0.3s;
cursor: pointer;
&:hover {
transform: translateY(-5px);
}
.statistics-header {
display: flex;
justify-content: space-between;
align-items: center;
span {
font-size: 16px;
font-weight: 500;
color: $text-primary;
}
}
.statistics-content {
padding: 20px 0;
.main-number {
font-size: 36px;
font-weight: 600;
color: $text-primary;
line-height: 1;
margin-bottom: 16px;
}
.sub-info {
display: flex;
justify-content: space-between;
align-items: center;
color: $text-secondary;
.highlight {
color: $primary-color;
font-weight: 500;
}
}
}
}
.mt-20 {
margin-top: 20px;
}
.card-header {
font-size: 16px;
font-weight: 500;
color: $text-primary;
}
:deep(.el-timeline-item__content) {
color: $text-regular;
}
:deep(.el-card) {
border: none;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
}
</style>