模拟数据变动
This commit is contained in:
		
							parent
							
								
									2da225162e
								
							
						
					
					
						commit
						a60301fba5
					
				| @ -11,17 +11,26 @@ import { getAssetsFile } from '@/utils'; | ||||
| // 您提供的耿马县GeoJSON数据 | ||||
| const gengmaGeoJSON = json; | ||||
| 
 | ||||
| const today = new Date(); | ||||
| const formattedDate = today | ||||
|   .toLocaleDateString('zh-CN', { | ||||
|     year: 'numeric', | ||||
|     month: 'numeric', | ||||
|     day: 'numeric', | ||||
|   }) | ||||
|   .replace(/\//g, '/'); // 确保分隔符是 / | ||||
| 
 | ||||
| // 模拟乡镇数据(根据图片中的地名) | ||||
| const towns = ref([ | ||||
|   { name: '孟定镇', coord: [99.01, 23.64], weather: '晴', temp: '28℃', icon: 'sunny' }, | ||||
|   { name: '勐简乡', coord: [99.24, 23.79], weather: '多云', temp: '26℃', icon: 'cloudy' }, | ||||
|   { name: '四排山乡', coord: [99.5, 23.38], weather: '小雨', temp: '24℃', icon: 'rainy' }, | ||||
|   { name: '大兴乡', coord: [99.8, 23.76], weather: '多云', temp: '25℃', icon: 'cloudy' }, | ||||
|   { name: '耿马镇', coord: [99.42, 23.66], weather: '多云', temp: '26℃', icon: 'cloudy' }, | ||||
|   { name: '贺派乡', coord: [99.21, 23.4], weather: '晴', temp: '27℃', icon: 'sunny' }, | ||||
|   { name: '芒洪乡', coord: [99.73, 23.59], weather: '阴', temp: '23℃', icon: 'overcast' }, | ||||
|   { name: '勐永镇', coord: [99.53, 23.99], weather: '小雨', temp: '22℃', icon: 'rainy' }, | ||||
|   { name: '勐撒镇', coord: [99.47, 23.85], weather: '晴', temp: '28℃', icon: 'sunny' }, | ||||
|   { id: 0, name: '孟定镇', coord: [99.01, 23.64], weather: '晴', temp: '28℃', icon: 'sunny' }, | ||||
|   { id: 1, name: '勐简乡', coord: [99.24, 23.79], weather: '多云', temp: '26℃', icon: 'cloudy' }, | ||||
|   { id: 2, name: '四排山乡', coord: [99.5, 23.38], weather: '小雨', temp: '24℃', icon: 'rainy' }, | ||||
|   { id: 3, name: '大兴乡', coord: [99.8, 23.76], weather: '多云', temp: '25℃', icon: 'cloudy' }, | ||||
|   { id: 4, name: '耿马镇', coord: [99.42, 23.66], weather: '多云', temp: '26℃', icon: 'cloudy' }, | ||||
|   { id: 5, name: '贺派乡', coord: [99.21, 23.4], weather: '晴', temp: '27℃', icon: 'sunny' }, | ||||
|   { id: 6, name: '芒洪乡', coord: [99.73, 23.59], weather: '阴', temp: '23℃', icon: 'overcast' }, | ||||
|   { id: 7, name: '勐永镇', coord: [99.53, 23.99], weather: '小雨', temp: '22℃', icon: 'rainy' }, | ||||
|   { id: 8, name: '勐撒镇', coord: [99.47, 23.85], weather: '晴', temp: '28℃', icon: 'sunny' }, | ||||
| ]); | ||||
| 
 | ||||
| const mapContainer = ref(null); | ||||
| @ -40,6 +49,11 @@ function getWeatherIconPath(iconType) { | ||||
|   let path = iconMap[iconType] ? iconMap[iconType] : 'images/smartFarm/sunny.png'; | ||||
|   return getAssetsFile(path); | ||||
| } | ||||
| const emit = defineEmits(['changeMap']); | ||||
| // 显示天气详情弹窗 | ||||
| const showWeatherDetail = (data) => { | ||||
|   emit('changeMap', { message: data }); | ||||
| }; | ||||
| 
 | ||||
| onMounted(() => { | ||||
|   // 添加防御性检查 | ||||
| @ -53,19 +67,13 @@ onMounted(() => { | ||||
|   chart.on('click', (params) => { | ||||
|     if (params.componentType === 'series') { | ||||
|       // 点击乡镇标记点 | ||||
|       console.log('点击乡镇:', params.name); | ||||
|       showWeatherDetail(params.data); | ||||
|       showWeatherDetail(params.name); | ||||
|     } else if (params.componentType === 'geo') { | ||||
|       // 点击地图区域 | ||||
|       console.log('点击地图区域:', params.name); | ||||
|       showWeatherDetail(params.name); | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   // 显示天气详情弹窗 | ||||
|   const showWeatherDetail = (data) => { | ||||
|     console.log(data); | ||||
|   }; | ||||
| 
 | ||||
|   // 注册地图 | ||||
|   echarts.registerMap('耿马县', gengmaGeoJSON); | ||||
| 
 | ||||
| @ -106,6 +114,7 @@ onMounted(() => { | ||||
|         coordinateSystem: 'geo', | ||||
|         symbolSize: 30, | ||||
|         data: towns.value.map((town) => ({ | ||||
|           id: town.id, | ||||
|           name: town.name, | ||||
|           value: [...town.coord, town.temp], | ||||
|           weather: town.weather, | ||||
| @ -165,9 +174,9 @@ onMounted(() => { | ||||
|     graphic: { | ||||
|       type: 'text', | ||||
|       left: 20, | ||||
|       bottom: 5, | ||||
|       bottom: 0, | ||||
|       style: { | ||||
|         text: '数据更新于: 2025.01.01 08:00:00', | ||||
|         text: '数据更新于: ' + formattedDate, | ||||
|         fill: '#666', | ||||
|         fontSize: 12, | ||||
|       }, | ||||
|  | ||||
| @ -26,10 +26,12 @@ const towns = ref([ | ||||
| 
 | ||||
| const mapContainer = ref(null); | ||||
| 
 | ||||
| // 获取天气图标路径 | ||||
| // function getWeatherIconPath(iconType) { | ||||
| //   return `/images/${iconType}.png`; // 使用绝对路径 | ||||
| // } | ||||
| const emit = defineEmits(['changeMap2']); | ||||
| // 显示天气详情弹窗 | ||||
| const showDustDetail = (data) => { | ||||
|   emit('changeMap2', { message: data }); | ||||
| }; | ||||
| 
 | ||||
| function getWeatherIconPath(iconType) { | ||||
|   const iconMap = { | ||||
|     sunny: 'images/smartFarm/sunny.png', | ||||
| @ -47,20 +49,12 @@ onMounted(() => { | ||||
|   // 添加点击事件监听 | ||||
|   chart.on('click', (params) => { | ||||
|     if (params.componentType === 'series') { | ||||
|       // 点击乡镇标记点 | ||||
|       console.log('点击乡镇:', params.name); | ||||
|       showWeatherDetail(params.data); | ||||
|       showDustDetail(params.name); | ||||
|     } else if (params.componentType === 'geo') { | ||||
|       // 点击地图区域 | ||||
|       console.log('点击地图区域:', params.name); | ||||
|       showDustDetail(params.name); | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   // 显示天气详情弹窗 | ||||
|   const showWeatherDetail = (data) => { | ||||
|     console.log(data); | ||||
|   }; | ||||
| 
 | ||||
|   // 注册地图 | ||||
|   echarts.registerMap('耿马县', gengmaGeoJSON); | ||||
| 
 | ||||
|  | ||||
| @ -6,12 +6,13 @@ | ||||
|           <el-card shadow="hover" style="border-radius: 16px"> | ||||
|             <el-row> | ||||
|               <el-col :span="10"> | ||||
|                 <map-comp style="height: 300px; width: 100%; border: 0"></map-comp> | ||||
|                 <map-comp style="height: 300px; width: 100%; border: 0" @change-map="changeMap"></map-comp> | ||||
|               </el-col> | ||||
|               <el-col :span="1"> </el-col> | ||||
|               <el-col :span="13"> | ||||
|                 <div class="location"> | ||||
|                   耿马县·孟定镇<img :src="getAssetsFile('images/smartFarm/location.png')" height="20" style="margin-left: 8px" alt="" /> | ||||
|                   耿马县·{{ currentPosition | ||||
|                   }}<img :src="getAssetsFile('images/smartFarm/location.png')" height="20" style="margin-left: 8px" alt="" /> | ||||
|                 </div> | ||||
|                 <div style="display: flex; justify-content: space-around"> | ||||
|                   <el-card v-for="(item, index) in weatherData" :key="index" :body-style="{ padding: 0 }" shadow="always" class="weatherCards"> | ||||
| @ -99,21 +100,21 @@ | ||||
|                       <img :src="getAssetsFile('images/smartFarm/光照传感器.png')" alt="" /> | ||||
|                       光照 | ||||
|                     </div> | ||||
|                     <div class="values">2000Lux</div> | ||||
|                     <div class="values">{{ dustData.light }}</div> | ||||
|                   </div> | ||||
|                   <div class="dustData"> | ||||
|                     <div> | ||||
|                       <img :src="getAssetsFile('images/smartFarm/排风.png')" alt="" /> | ||||
|                       排风 | ||||
|                     </div> | ||||
|                     <div class="values">15m³/h</div> | ||||
|                     <div class="values">{{ dustData.wind }}</div> | ||||
|                   </div> | ||||
|                   <div class="dustData"> | ||||
|                     <div> | ||||
|                       <img :src="getAssetsFile('images/smartFarm/蒸腾.png')" alt="" /> | ||||
|                       蒸腾 | ||||
|                     </div> | ||||
|                     <div class="values">2000Lux</div> | ||||
|                     <div class="values">{{ dustData.evapotranspiration }}</div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div style="display: flex"> | ||||
| @ -122,24 +123,24 @@ | ||||
|                       <img :src="getAssetsFile('images/smartFarm/土壤湿度.png')" alt="" /> | ||||
|                       湿度 | ||||
|                     </div> | ||||
|                     <div class="values">26%</div> | ||||
|                     <div class="values">34%</div> | ||||
|                     <div class="values">{{ dustData.wet.min }}</div> | ||||
|                     <div class="values">{{ dustData.wet.max }}</div> | ||||
|                   </div> | ||||
|                   <div class="dustData"> | ||||
|                     <div> | ||||
|                       <img :src="getAssetsFile('images/smartFarm/土壤温度.png')" alt="" /> | ||||
|                       温度 | ||||
|                     </div> | ||||
|                     <div class="values">32℃</div> | ||||
|                     <div class="values">28℃</div> | ||||
|                     <div class="values">{{ dustData.temp.min }}</div> | ||||
|                     <div class="values">{{ dustData.temp.max }}</div> | ||||
|                   </div> | ||||
|                   <div class="dustData"> | ||||
|                     <div> | ||||
|                       <img :src="getAssetsFile('images/smartFarm/空气.png')" alt="" /> | ||||
|                       空气 | ||||
|                     </div> | ||||
|                     <div class="values">300ppm</div> | ||||
|                     <div class="values">34%</div> | ||||
|                     <div class="values">{{ dustData.air.dirt }}</div> | ||||
|                     <div class="values">{{ dustData.air.wet }}</div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="report"> | ||||
| @ -155,7 +156,7 @@ | ||||
|                 </div> | ||||
|               </div> | ||||
|               <div style="width: 35%"> | ||||
|                 <map-simple style="height: 320px; width: 100%"></map-simple> | ||||
|                 <map-simple style="height: 320px; width: 100%" @change-map2="changeMap2"></map-simple> | ||||
|               </div> | ||||
|               <div style="width: 35%"> | ||||
|                 <div style="margin-top: 70px; display: flex; text-align: left"> | ||||
| @ -164,11 +165,11 @@ | ||||
|                     <el-row> | ||||
|                       <el-col :span="12"> | ||||
|                         <span style="font-size: 15px">输入</span> | ||||
|                         <span class="values">11</span> | ||||
|                         <span class="values">{{ dustData.pressure.input }}</span> | ||||
|                       </el-col> | ||||
|                       <el-col :span="12"> | ||||
|                         <span style="font-size: 15px">末端</span> | ||||
|                         <span class="values">2</span> | ||||
|                         <span class="values">{{ dustData.pressure.end }}</span> | ||||
|                       </el-col> | ||||
|                     </el-row> | ||||
|                   </el-col> | ||||
| @ -177,11 +178,11 @@ | ||||
|                     <el-row> | ||||
|                       <el-col :span="12"> | ||||
|                         <span style="font-size: 15px">灌溉</span> | ||||
|                         <span class="values">18℃</span> | ||||
|                         <span class="values">{{ dustData.flow.output }}</span> | ||||
|                       </el-col> | ||||
|                       <el-col :span="12"> | ||||
|                         <span style="font-size: 15px">回液</span> | ||||
|                         <span class="values">18℃</span> | ||||
|                         <span class="values">{{ dustData.flow.input }}</span> | ||||
|                       </el-col> | ||||
|                     </el-row> | ||||
|                   </el-col> | ||||
| @ -192,11 +193,11 @@ | ||||
|                     <el-row> | ||||
|                       <el-col :span="12"> | ||||
|                         <span style="font-size: 15px">PH</span> | ||||
|                         <span class="values">8</span> | ||||
|                         <span class="values">{{ dustData.fertilization.ph }}</span> | ||||
|                       </el-col> | ||||
|                       <el-col :span="12"> | ||||
|                         <span style="font-size: 15px">输入</span> | ||||
|                         <span class="values">18℃</span> | ||||
|                         <span class="values">{{ dustData.fertilization.output }}</span> | ||||
|                       </el-col> | ||||
|                     </el-row> | ||||
|                   </el-col> | ||||
| @ -293,13 +294,13 @@ | ||||
| </template> | ||||
| 
 | ||||
| <script setup> | ||||
| import { ref, onMounted } from 'vue'; | ||||
| import { ref } from 'vue'; | ||||
| import Common from './components/common.vue'; | ||||
| import * as echarts from 'echarts'; | ||||
| import MapComp from '@/views/smartFarm/components/mapComp.vue'; | ||||
| import { getAssetsFile } from '@/utils/index.js'; | ||||
| import MapSimple from '@/views/smartFarm/components/mapSimple.vue'; | ||||
| import ChartsFlow from '@/views/smartFarm/components/charts-flow.vue'; | ||||
| import Mock from 'mockjs'; | ||||
| 
 | ||||
| /* --------------- data --------------- */ | ||||
| // #region | ||||
| @ -336,6 +337,67 @@ const weatherData = ref([ | ||||
|   }, | ||||
| ]); | ||||
| 
 | ||||
| const dustData = ref({ | ||||
|   light: '2000Lux', // 光照强度 | ||||
|   wind: '15m³/h', // 排风量 | ||||
|   evapotranspiration: '2000Lux', // 蒸腾 | ||||
|   wet: { | ||||
|     min: '26%', | ||||
|     max: '34%', | ||||
|   }, | ||||
|   temp: { | ||||
|     min: '32℃', | ||||
|     max: '28℃', | ||||
|   }, | ||||
|   air: { | ||||
|     dirt: '300ppm', | ||||
|     wet: '34%', | ||||
|   }, | ||||
|   pressure: { | ||||
|     input: '11', | ||||
|     end: 2, | ||||
|   }, | ||||
|   flow: { | ||||
|     temp: '53', | ||||
|     input: '125', | ||||
|   }, | ||||
|   fertilization: { | ||||
|     ph: 8, | ||||
|     output: '18', | ||||
|   }, | ||||
| }); | ||||
| 
 | ||||
| // 定义合法的天气状态流转规则 | ||||
| const weatherStates = [ | ||||
|   { | ||||
|     type: 'sunny', | ||||
|     next: ['sunny', 'sunnyToCloudy'], // 晴天只能转晴天或晴转多云 | ||||
|     tempEffect: +0, // 温度影响 | ||||
|   }, | ||||
|   { | ||||
|     type: 'sunnyToCloudy', | ||||
|     next: ['thunderRain', 'rainy'], // 晴转多云后可能转雷雨或直接下雨 | ||||
|     tempEffect: +1, | ||||
|   }, | ||||
|   { | ||||
|     type: 'thunderRain', | ||||
|     next: ['rainy', 'windy'], // 雷雨后继续下雨或转大风 | ||||
|     tempEffect: -2, | ||||
|   }, | ||||
|   { | ||||
|     type: 'rainy', | ||||
|     next: ['rainy', 'windy'], // 雨天可能持续或转大风 | ||||
|     tempEffect: -3, | ||||
|   }, | ||||
|   { | ||||
|     type: 'windy', | ||||
|     next: ['sunny'], // 大风后转晴天 | ||||
|     tempEffect: -4, | ||||
|   }, | ||||
| ]; | ||||
| 
 | ||||
| const currentPosition = ref('孟定镇'); | ||||
| 
 | ||||
| const currentData = ref({ | ||||
|   temp: 18, // 当前温度 | ||||
|   PM2: 80, // 空气质量 μg/m³ | ||||
| @ -350,11 +412,141 @@ const currentData = ref({ | ||||
|   windSpeed: 1.5, // 风速 m/s | ||||
|   PH: 6.5, // 土壤酸碱度 | ||||
| }); | ||||
| // 基础环境数据模板 | ||||
| 
 | ||||
| // #endregion | ||||
| 
 | ||||
| /* --------------- methods --------------- */ | ||||
| // #region | ||||
| const changeMap = (params) => { | ||||
|   currentPosition.value = params.message; | ||||
|   const newWeatherData = generateSmartWeather(15, 6, 18); | ||||
|   weatherData.value = newWeatherData; | ||||
|   currentData.value = generateFarmData(18); | ||||
| }; | ||||
| 
 | ||||
| const changeMap2 = (params) => { | ||||
|   console.log(params.message); | ||||
|   dustData.value = Mock.mock({ | ||||
|     // 光照强度 (500-3000 Lux) | ||||
|     light: '@natural(500, 3000)' + 'Lux', | ||||
| 
 | ||||
|     // 排风量 (5-30 m³/h) | ||||
|     wind: '@natural(5, 30)' + 'm³/h', | ||||
| 
 | ||||
|     // 蒸腾量 (1-10 mm/day) | ||||
|     evapotranspiration: '@natural(1, 10)' + 'mm/day', | ||||
| 
 | ||||
|     // 湿度范围 (min:20-40%, max比min高5-15%) | ||||
|     wet: { | ||||
|       min: '@natural(20, 40)' + '%', | ||||
|       max: function () { | ||||
|         return parseInt(this.min) + Mock.mock('@natural(5, 15)') + '%'; | ||||
|       }, | ||||
|     }, | ||||
| 
 | ||||
|     // 温度范围 (min:15-25℃, max比min高5-15℃) | ||||
|     temp: { | ||||
|       min: '@natural(15, 25)' + '℃', | ||||
|       max: function () { | ||||
|         return parseInt(this.min) + Mock.mock('@natural(5, 15)') + '℃'; | ||||
|       }, | ||||
|     }, | ||||
| 
 | ||||
|     // 空气质量 | ||||
|     air: { | ||||
|       // 颗粒物浓度 (100-800 ppm) | ||||
|       dirt: '@natural(100, 800)' + 'ppm', | ||||
|       wet: '@natural(30, 60)%', // 先独立生成 | ||||
|     }, | ||||
| 
 | ||||
|     // 压力参数 | ||||
|     pressure: { | ||||
|       // 输入压力 (5-15 MPa) | ||||
|       input: '@natural(5, 15)', | ||||
|       // 末端压力衰减 (1-5) | ||||
|       end: '@natural(1, 5)', | ||||
|     }, | ||||
| 
 | ||||
|     // 流量参数 | ||||
|     flow: { | ||||
|       // 流体温度 (30-60 m²/h) | ||||
|       temp: '@natural(30, 60)', | ||||
|       // 输入流量 (50-200 m²/h) | ||||
|       input: '@natural(50, 200)', | ||||
|     }, | ||||
| 
 | ||||
|     // 施肥参数 | ||||
|     fertilization: { | ||||
|       // pH值 (5.0-8.5) | ||||
|       ph: '@float(5, 8.5, 1, 1)', | ||||
|       // 输出流量 (10-50 m²/h) | ||||
|       output: '@natural(10, 50)', | ||||
|     }, | ||||
|   }); | ||||
| }; | ||||
| // 生成智能天气数据 | ||||
| function generateSmartWeather(startTime, hours, baseTemp = 18) { | ||||
|   let currentWeather = 'sunny'; | ||||
|   const result = []; | ||||
| 
 | ||||
|   for (let i = 0; i < hours; i++) { | ||||
|     // 1. 获取当前天气状态对象 | ||||
|     const state = weatherStates.find((s) => s.type === currentWeather); | ||||
| 
 | ||||
|     // 2. 计算时间 (15:00 格式) | ||||
|     const time = `${startTime + i}:00`.padStart(5, '0'); | ||||
| 
 | ||||
|     // 3. 计算温度(基于基础温度+天气影响+随机波动) | ||||
|     const temp = baseTemp + state.tempEffect + Math.floor(Math.random() * 2); | ||||
| 
 | ||||
|     // 4. 记录数据 | ||||
|     result.push({ | ||||
|       weather: currentWeather, | ||||
|       time, | ||||
|       temp: Math.max(temp, -5), // 确保不低于-5度 | ||||
|     }); | ||||
| 
 | ||||
|     // 5. 智能切换下一个天气状态 | ||||
|     currentWeather = state.next[Math.floor(Math.random() * state.next.length)]; | ||||
|   } | ||||
| 
 | ||||
|   return result; | ||||
| } | ||||
| 
 | ||||
| const generateFarmData = (baseTemp = 18) => { | ||||
|   // 1. 先生成核心天气数据(基于之前方案) | ||||
|   const weather = Mock.mock({ | ||||
|     weather: '@pick(["sunny", "sunnyToCloudy", "thunderRain", "rainy", "windy"])', | ||||
|     wind: '@pick(["东南风", "西南风", "东北风", "西北风"])', | ||||
|     windSpeed: '@float(0.5, 5, 1, 1)', | ||||
|   }); | ||||
| 
 | ||||
|   // 2. 根据天气计算衍生数据 | ||||
|   const weatherImpact = { | ||||
|     sunny: { temp: +0, light: +200, wet: -10 }, | ||||
|     sunnyToCloudy: { temp: +1, light: -100, wet: +5 }, | ||||
|     thunderRain: { temp: -2, light: -300, wet: +20 }, | ||||
|     rainy: { temp: -3, light: -400, wet: +25 }, | ||||
|     windy: { temp: -4, light: +50, wet: -15 }, | ||||
|   }[weather.weather]; | ||||
| 
 | ||||
|   // 3. 生成完整数据集(带科学关联) | ||||
|   return { | ||||
|     temp: Mock.Random.float(baseTemp + weatherImpact.temp - 1, baseTemp + weatherImpact.temp + 1, 1, 1), | ||||
|     PM2: Mock.Random.integer(weather.weather === 'windy' ? 30 : 60, weather.weather === 'rainy' ? 90 : 120), | ||||
|     PM10: Mock.Random.integer(80, 150), | ||||
|     bugs: Mock.Random.integer(0, weather.wet > 70 ? 5 : 2), // 高湿度虫害增加 | ||||
|     dustTemp: Mock.Random.float(baseTemp - 3, baseTemp + 1, 1, 1), | ||||
|     wet: Mock.Random.integer(50 + weatherImpact.wet, 70 + weatherImpact.wet), | ||||
|     sick: Mock.Random.integer(0, weather.weather === 'thunderRain' ? 3 : 1), // 雷雨易引发病害 | ||||
|     dustWet: Mock.Random.integer(60, weather.weather === 'rainy' ? 85 : 75), | ||||
|     wind: weather.wind, | ||||
|     light: Mock.Random.integer(Math.max(200, 500 + weatherImpact.light), Math.min(1200, 800 + weatherImpact.light)), | ||||
|     windSpeed: weather.windSpeed, | ||||
|     PH: Mock.Random.float(6.0, 7.5, 1, 1), | ||||
|   }; | ||||
| }; | ||||
| // #endregion | ||||
| </script> | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user