298 lines
8.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<common>
<template #main>
<div>
<devices :title="'环境监测设备'" :devices="devices"></devices>
</div>
<div style="margin-top: 10px; display: flex; justify-content: space-between">
<div style="display: flex; justify-content: space-between; margin-top: 10px; width: 100%">
<el-card style="width: 60%; margin-right: 20px; border-radius: 16px">
<div style="display: flex; justify-content: space-between">
<div style="font-size: 16px; font-weight: bold; text-align: left">实时环境监测</div>
<div>
<div>当前设备状态</div>
<div>
<div class="dot"></div>
<span>正常</span>
</div>
</div>
<div style="color: #999999; line-height: 25px">
当前设备
<el-select
v-model="currentDevice"
placeholder="Select"
size="small"
style="width: 160px; margin-left: 10px"
@change="changeDevice($event)"
>
<el-option v-for="item in devices" :key="item.value" :label="item.detail" :value="item.id" />
</el-select>
</div>
</div>
<div class="envData">
<div class="dt">
<div class="values">{{ monitorData.co2 }}</div>
<div class="points">空气温度</div>
</div>
<div class="dt">
<div class="values">{{ monitorData.humidity }}</div>
<div class="points">空气湿度</div>
</div>
<div class="dt">
<div class="values">{{ monitorData.rainfall }}</div>
<div class="points">降水量</div>
</div>
<div class="dt">
<div class="values">{{ monitorData.wind }}</div>
<div class="points">风向</div>
</div>
<div class="dt">
<div class="values">{{ monitorData.pm25 }}</div>
<div class="points">PM2.5</div>
</div>
<div class="dt">
<div class="values">{{ monitorData.light }}</div>
<div class="points">光照强度</div>
</div>
<div class="dt">
<div class="values">{{ monitorData.co2 }}</div>
<div class="points">二氧化碳浓度</div>
</div>
<div class="dt">
<div class="values">{{ monitorData.windSpeed }}</div>
<div class="points">风速</div>
</div>
</div>
<div class="notices">
<div v-for="(item, index) in notices" :key="index">
<img :src="getAssetsFile('images/smartFarm/bell.png')" alt="" style="height: 20px; margin-right: 5px" />
<span style="font-size: 14px">{{ item.title }}</span>
</div>
</div>
</el-card>
<DataDisplay :title="'环境分析报告'" :data="rightData" style="flex: 1"></DataDisplay>
</div>
</div>
</template>
</common>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue';
import Devices from '@/views/smartFarm/components/devices.vue';
import Common from '@/views/smartFarm/components/common.vue';
import { getAssetsFile } from '@/utils/index.js';
import DataDisplay from '@/views/smartFarm/components/dataDisplay.vue';
import Mock from 'mockjs';
/* --------------- data --------------- */
// #region
const devices = ref([
{
name: 'A-001',
icon: 'temp',
detail: 'A区-监控设备1',
status: '1',
id: 0,
},
{
name: 'A-004',
icon: 'soilSensor',
detail: 'A区-监控设备4',
status: '-1',
id: 3,
},
{
name: 'A-005',
icon: 'anemometer',
detail: 'A区-监控设备5',
status: '1',
id: 4,
},
{
name: 'B-001',
icon: 'rainGauge',
detail: 'B区-监控设备1',
status: '1',
id: 6,
},
{
name: 'B-003',
icon: 'waterLoggingSensor',
detail: 'B区-监控设备3',
status: '1',
id: 8,
},
{
name: 'B-004',
icon: 'PM2.5',
detail: 'B区-监控设备4',
status: '1',
id: 9,
},
{
name: 'B-006',
icon: 'light',
detail: 'B区-监控设备6',
status: '1',
id: 11,
},
]);
const currentDevice = ref(0);
const notices = ref([
{
title: '2025年1月2日预计将会有特大暴雨请提前做好防护措施',
content: '',
},
{
title: '2025年1月1日预计将会有大雨请提前做好防护措施',
content: '',
},
]);
let monitorData = ref({});
let rightData = ref([]);
const changeDevice = (id) => {
currentDevice.value = id;
monitorData.value = getMockData()[0];
rightData.value = getMockData()[1];
};
// 生成模拟数据
const getMockData = () => {
// 左侧环境监测数据
const leftData = Mock.mock({
co2: () => randomRange(200, 800, 0) + 'ppm', // CO₂浓度300~800ppm
temperature: () => randomRange(-10, 40, 1) + '℃', // 温度(-10~40℃
humidity: () => randomRange(10, 100, 0) + '%', // 湿度10%~100%
wind: '@pick(["东南风", "西南风", "东北风", "西北风"])',
rainfall: () => randomRange(0, 200, 1) + 'mm', // 降水量0~200mm1位小数
pm25: () => randomRange(0, 300, 0) + 'μg/m³', // PM2.50~300μg/m³整数
light: () => randomRange(100, 1000, 0) + 'Lux', // 光照强度100~1000Lux整数
windSpeed: () => randomRange(0, 10, 1) + 'm/s', // 风速0~10m/s1位小数
});
// 右侧环境分析报告数据
const rightData = Mock.mock({
'list|6': [
{
// 基础字段
'title|+1': ['酸碱度(pH)', '养分含量', '重金属含量', '水温', '水浑浊度', '盐分含量'],
'status|1': ['0', '1'],
'unit|+1': ['pH值', '%', 'mg/kg', '℃', 'NTU', 'dS/m'],
// 动态生成异常文本
statusText: function () {
const statusMap = {
'酸碱度(pH)':
this.status === '0' ? `酸碱度${Mock.mock('@float(4.0, 9.0, 1, 1)')}${Mock.mock('@pick(["酸性过强","碱性过强"])')}` : '正常',
养分含量: this.status === '0' ? `${Mock.mock('@pick(["N","P","K","Ca","Mg"])')}元素含量不足` : '正常',
重金属含量: this.status === '0' ? `${Mock.mock('@pick(["镉","铅","砷","汞"])')}超标(${Mock.mock('@float(1, 5, 1, 1)')}mg/kg)` : '正常',
水温: this.status === '0' ? `${Mock.mock('@integer(10, 40)')}℃(${Mock.mock('@pick(["低温胁迫","高温胁迫"])')}` : '正常',
水浑浊度: this.status === '0' ? `浊度${Mock.mock('@integer(10, 50)')}NTU` : '正常',
盐分含量: this.status === '0' ? `盐分${Mock.mock('@float(2, 5, 1, 1)')}dS/m` : '正常',
};
return statusMap[this.title];
},
},
],
});
return [leftData, rightData.list];
};
// 自定义随机范围函数
const randomRange = (min, max, fixed = 0) => {
return Mock.Random.float(min, max, fixed).toFixed(fixed);
};
onMounted(() => {
changeDevice(0);
});
// #endregion
/* --------------- methods --------------- */
// #region
const chooseIcon = (type) => {
switch (type) {
case 'light':
return '分光器.png';
case 'float':
return '悬浮物.png';
case 'O2':
return '水质溶解氧.png';
case 'elect':
return '水质电导率.png';
case 'dust':
return '浊度.png';
case 'temp':
return '温度.png';
case 'ph':
return '酸碱度.png';
}
};
// #endregion
</script>
<style lang="scss" scoped>
.dot {
height: 10px;
width: 10px;
display: inline-block;
border-radius: 90px;
background-color: #25bf82;
}
.plantStatus {
display: flex;
justify-content: space-between;
font-size: 14px;
margin: 7px 0;
.leftKey {
color: #000000;
}
.rightValue {
color: #25bf82;
}
.errorValue {
color: #fe4066;
}
}
.notices {
div {
margin: 10px 0;
}
text-align: left;
}
.envData {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
margin-top: 20px;
.dt {
width: 25%;
text-align: left;
margin-bottom: 20px;
.values {
color: #25bf82;
font-size: 20px;
font-weight: bold;
}
.points {
color: #999999;
font-size: 14px;
}
}
}
.plantStatus {
display: flex;
justify-content: space-between;
font-size: 14px;
margin: 10px 0;
.leftKey {
color: #000000;
}
.rightValue {
color: #25bf82;
}
}
</style>