diff --git a/vue/src/views/index.vue b/vue/src/views/index.vue
index a2e1e2a2..66e3126c 100644
--- a/vue/src/views/index.vue
+++ b/vue/src/views/index.vue
@@ -300,7 +300,7 @@ import CountTo from 'vue-count-to';
import { loadBMap } from '@/utils/map.js';
//安装的是echarts完整包,里面包含百度地图扩展,路径为 echarts/extension/bmap/bmap.js,将其引入
//ECharts的百度地图扩展,可以在百度地图上展现点图,线图,热力图等可视化
-require('echarts/extension/bmap/bmap');
+// 注意:bmap扩展需要在BMap加载后再引入
import { getServer } from '@/api/monitor/server';
import { listAllDeviceShort } from '@/api/iot/device';
import 'echarts-liquidfill';
@@ -316,10 +316,10 @@ function getCurrentDateAndWeek() {
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const date = `${year}-${month}-${day}`;
-
+
const weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
const week = weekDays[now.getDay()];
-
+
return { date, week };
}
@@ -331,10 +331,10 @@ export default {
data() {
// 获取当前日期和星期
const { date, week } = getCurrentDateAndWeek();
-
+
// 从localStorage读取保存的城市,如果没有则使用默认值
const savedCity = localStorage.getItem('weatherCity') || '北京市';
-
+
return {
//天气信息
weatherData: {
@@ -362,6 +362,8 @@ export default {
cityInput: '',
// 常用城市列表
commonCities: ['北京市', '上海市', '广州市', '深圳市', '杭州市', '南京市', '成都市', '武汉市', '西安市', '重庆市', '天津市', '苏州市', '郑州市', '长沙市', '东莞市', '佛山市', '宁波市', '无锡市', '青岛市', '大连市'],
+ // 天气刷新定时器
+ weatherTimer: null,
// mqtt状态数据
stats: {},
// mqtt统计信息
@@ -437,16 +439,27 @@ export default {
},
beforeDestroy() {
this.stopScroll();
+ // 清除天气刷新定时器
+ if (this.weatherTimer) {
+ clearInterval(this.weatherTimer);
+ this.weatherTimer = null;
+ }
},
created() {
this.init();
this.getAllDevice();
this.getNoticeList();
this.getDeviceStatistic();
- this.fetchWeather();
+ // 先尝试获取浏览器位置,然后获取天气
+ this.getLocationAndWeather();
this.getMqttStats();
this.statisticMqtt();
+
+ // 设置天气自动刷新(每30分钟刷新一次)
+ this.weatherTimer = setInterval(() => {
+ this.fetchWeather();
+ }, 30 * 60 * 1000); // 30分钟
},
methods: {
// 公告栏滚动
@@ -468,12 +481,12 @@ export default {
// 清空之前的数据
this.linechart.date = [];
this.linechart.counts = [];
-
+
// 按日期排序(从早到晚)
const sortedData = [...response.data].sort((a, b) => {
return new Date(a.datetime) - new Date(b.datetime);
});
-
+
sortedData.forEach((item) => {
this.linechart.date.push(item.datetime);
this.linechart.counts.push(item.user_count);
@@ -627,96 +640,297 @@ export default {
option && myChart.setOption(option);
},
- // 天气
+ // 获取浏览器位置并获取天气
+ async getLocationAndWeather() {
+ // 检查是否已有保存的城市(用户可能手动选择过)
+ const savedCity = localStorage.getItem('weatherCity');
+ if (savedCity && savedCity !== '北京市') {
+ // 如果已有保存的城市且不是默认值,直接使用
+ this.fetchWeather(savedCity);
+ return;
+ }
+
+ // 检查浏览器是否支持定位
+ if (!navigator.geolocation) {
+ // 不支持定位,使用默认城市
+ this.fetchWeather();
+ return;
+ }
+
+ // 尝试获取当前位置
+ navigator.geolocation.getCurrentPosition(
+ async (position) => {
+ const lat = position.coords.latitude;
+ const lon = position.coords.longitude;
+
+ try {
+ // 使用OpenStreetMap的逆地理编码获取城市名称
+ const response = await axios.get(`https://nominatim.openstreetmap.org/reverse`, {
+ params: {
+ lat: lat,
+ lon: lon,
+ format: 'json',
+ addressdetails: 1,
+ 'accept-language': 'zh-CN,zh'
+ },
+ timeout: 8000
+ });
+
+ if (response.data && response.data.address) {
+ const address = response.data.address;
+ // 优先使用城市,如果没有则使用区县、镇等
+ let cityName = address.city || address.town || address.village || address.county || address.district;
+
+ // 如果是中国,处理城市名称
+ if (address.country_code === 'cn') {
+ // 如果城市名不包含"市",添加"市"后缀
+ if (cityName && !cityName.endsWith('市') && !cityName.endsWith('县') && !cityName.endsWith('区')) {
+ cityName = cityName + '市';
+ }
+ // 特殊处理:如果是直辖市或特殊城市
+ if (address.state) {
+ const state = address.state;
+ if (state.includes('北京') || state.includes('上海') || state.includes('天津') || state.includes('重庆')) {
+ cityName = state.replace('市', '') + '市';
+ }
+ }
+ }
+
+ if (cityName) {
+ // 保存定位到的城市
+ localStorage.setItem('weatherCity', cityName);
+ this.weatherData.city = cityName;
+ // 获取该城市的天气
+ await this.fetchWeather(cityName);
+ return;
+ }
+ }
+ } catch (err) {
+ // 逆地理编码失败,使用默认城市
+ }
+
+ // 如果逆地理编码失败,使用默认城市
+ this.fetchWeather();
+ },
+ (error) => {
+ // 用户拒绝定位或定位失败,使用默认城市
+ this.fetchWeather();
+ },
+ {
+ timeout: 10000,
+ enableHighAccuracy: false,
+ maximumAge: 300000 // 5分钟内的缓存位置可以使用
+ }
+ );
+ },
+ // 天气 - 使用多个免费API,按优先级尝试
async fetchWeather(cityName) {
this.isLoading = true;
this.error = null;
- // 获取当前日期和星期作为默认值
const { date, week } = getCurrentDateAndWeek();
-
- // 使用传入的城市名或当前保存的城市
const city = cityName || this.weatherData.city;
-
- try {
- // 尝试使用城市参数调用API,如果API不支持则使用默认调用
- let apiUrl = 'https://api.vvhan.com/api/weather';
- // 某些天气API支持城市参数,这里尝试添加
- // 如果API不支持,可以尝试其他天气API或使用IP定位
- try {
- // 尝试带城市参数的API调用
- const response = await axios.get(apiUrl, {
- params: { city: city }
+
+ // 尝试多个免费天气API(按优先级)
+ const apis = [
+ // API 1: wttr.in - 完全免费,无需API key,支持中文城市
+ async () => {
+ const cityParam = encodeURIComponent(city);
+ const response = await axios.get(`https://wttr.in/${cityParam}?format=j1&lang=zh`, {
+ timeout: 8000
+ });
+ if (response.data && response.data.current_condition && response.data.current_condition[0]) {
+ const data = response.data.current_condition[0];
+ const today = response.data.weather[0];
+ return {
+ success: true,
+ city: city,
+ data: {
+ date: date,
+ week: week,
+ type: this.translateWeatherType(data.weatherDesc[0].value),
+ typeIcon: this.getTypeIcon(this.translateWeatherType(data.weatherDesc[0].value)),
+ low: today.mintempC + '°C',
+ high: today.maxtempC + '°C',
+ fengxiang: data.winddir16Point || '无风',
+ fengli: data.windspeedKmph + 'km/h',
+ },
+ air: {
+ aqi: data.humidity || 50,
+ aqi_level: 2,
+ aqi_name: '良',
+ },
+ tip: this.getWeatherTip(this.translateWeatherType(data.weatherDesc[0].value)),
+ };
+ }
+ throw new Error('wttr.in API返回数据格式错误');
+ },
+ // API 2: Open-Meteo - 完全免费开源(不需要User-Agent)
+ async () => {
+ // 使用简化的城市名进行地理编码
+ const cityName = city.replace(/市$/, ''); // 移除"市"字
+ const geoResponse = await axios.get(`https://nominatim.openstreetmap.org/search`, {
+ params: {
+ q: cityName + ', China',
+ format: 'json',
+ limit: 1
+ },
+ timeout: 8000
+ });
+
+ if (geoResponse.data && geoResponse.data.length > 0) {
+ const lat = parseFloat(geoResponse.data[0].lat);
+ const lon = parseFloat(geoResponse.data[0].lon);
+
+ const weatherResponse = await axios.get(`https://api.open-meteo.com/v1/forecast`, {
+ params: {
+ latitude: lat,
+ longitude: lon,
+ current: 'temperature_2m,weather_code,wind_speed_10m,wind_direction_10m',
+ daily: 'temperature_2m_max,temperature_2m_min,weather_code',
+ timezone: 'Asia/Shanghai',
+ forecast_days: 1
+ },
+ timeout: 8000
+ });
+
+ if (weatherResponse.data && weatherResponse.data.current) {
+ const current = weatherResponse.data.current;
+ const daily = weatherResponse.data.daily;
+ const weatherCode = this.translateWeatherCode(current.weather_code);
+
+ return {
+ success: true,
+ city: city,
+ data: {
+ date: date,
+ week: week,
+ type: weatherCode,
+ typeIcon: this.getTypeIcon(weatherCode),
+ low: Math.round(daily.temperature_2m_min[0]) + '°C',
+ high: Math.round(daily.temperature_2m_max[0]) + '°C',
+ fengxiang: this.getWindDirection(current.wind_direction_10m),
+ fengli: Math.round(current.wind_speed_10m * 3.6) + 'km/h',
+ },
+ air: {
+ aqi: 50,
+ aqi_level: 2,
+ aqi_name: '良',
+ },
+ tip: this.getWeatherTip(weatherCode),
+ };
+ }
+ }
+ throw new Error('Open-Meteo API失败');
+ },
+ // API 3: 备用方案
+ async () => {
+ const response = await axios.get('https://api.vvhan.com/api/weather', {
+ timeout: 8000
});
if (response.data && response.data.success) {
- this.updateWeatherData(response.data, date, week, city);
- return;
+ return {
+ success: true,
+ city: city,
+ data: {
+ date: response.data.data?.date || date,
+ week: response.data.data?.week || week,
+ type: response.data.data.type,
+ typeIcon: this.getTypeIcon(response.data.data.type),
+ low: response.data.data.low,
+ high: response.data.data.high,
+ fengxiang: response.data.data.fengxiang,
+ fengli: response.data.data.fengli,
+ },
+ air: response.data.air || {
+ aqi: 50,
+ aqi_level: 2,
+ aqi_name: '良',
+ },
+ tip: response.data.tip || this.getWeatherTip(response.data.data.type),
+ };
}
- } catch (e) {
- // 如果带参数的调用失败,尝试不带参数的调用
- console.log('带城市参数的API调用失败,尝试默认调用');
+ throw new Error('备用API失败');
}
-
- // 默认API调用(可能不支持城市参数,使用IP定位)
- const response = await axios.get(apiUrl);
- if (response.data && response.data.success) {
- // 如果API返回的城市与设置的城市不同,使用设置的城市名称
- const apiCity = response.data.city || city;
- this.updateWeatherData(response.data, date, week, city);
- } else {
- // API返回失败,使用当前日期更新
- this.weatherData.data.date = date;
- this.weatherData.data.week = week;
- this.weatherData.city = city; // 保持用户设置的城市
- this.error = '获取天气数据失败,请稍后重试。';
+ ];
+
+ // 按顺序尝试各个API
+ for (let i = 0; i < apis.length; i++) {
+ try {
+ const result = await apis[i]();
+ if (result && result.success) {
+ this.weatherData = result;
+ const background = this.getBackgroundColor(result.data.type);
+ document.documentElement.style.setProperty('--background-start', background.start);
+ document.documentElement.style.setProperty('--background-end', background.end);
+ this.isLoading = false;
+ return;
}
} catch (err) {
- console.error(err);
- // API调用失败,使用当前日期更新
+ if (i === apis.length - 1) {
+ // 所有API都失败
this.weatherData.data.date = date;
this.weatherData.data.week = week;
- this.weatherData.city = city; // 保持用户设置的城市
- this.error = '无法连接到天气服务,请检查网络或稍后再试。';
- } finally {
- this.isLoading = false;
+ this.weatherData.city = city;
+ this.error = '无法获取天气数据,请检查网络连接';
+ }
+ }
}
+
+ this.isLoading = false;
},
- // 更新天气数据
- updateWeatherData(responseData, date, week, city) {
- this.weatherData = {
- success: true,
- city: city, // 使用用户设置的城市
- data: {
- date: responseData.data?.date || date,
- week: responseData.data?.week || week,
- type: responseData.data.type,
- typeIcon: this.getTypeIcon(responseData.data.type),
- low: responseData.data.low,
- high: responseData.data.high,
- fengxiang: responseData.data.fengxiang,
- fengli: responseData.data.fengli,
- night: {
- type: responseData.data.night.type,
- fengxiang: responseData.data.night.fengxiang,
- fengli: responseData.data.night.fengli,
- },
- },
- air: {
- aqi: responseData.air.aqi,
- aqi_level: responseData.air.aqi_level,
- aqi_name: responseData.air.aqi_name,
- co: responseData.air.co,
- no2: responseData.air.no2,
- o3: responseData.air.o3,
- pm10: responseData.air.pm10,
- pm2_5: responseData.air.pm2_5,
- so2: responseData.air.so2,
- },
- tip: responseData.tip,
+ // 翻译天气类型(英文转中文)
+ translateWeatherType(englishType) {
+ const typeMap = {
+ 'Sunny': '晴',
+ 'Clear': '晴',
+ 'Partly cloudy': '多云',
+ 'Cloudy': '阴',
+ 'Overcast': '阴',
+ 'Mist': '雾',
+ 'Fog': '雾',
+ 'Light rain': '小雨',
+ 'Moderate rain': '中雨',
+ 'Heavy rain': '大雨',
+ 'Light snow': '小雪',
+ 'Moderate snow': '中雪',
+ 'Heavy snow': '大雪',
+ 'Thunderstorm': '雷阵雨',
+ 'Shower': '阵雨',
};
- // 动态设置背景颜色
- const background = this.getBackgroundColor(responseData.data.type);
- document.documentElement.style.setProperty('--background-start', background.start);
- document.documentElement.style.setProperty('--background-end', background.end);
+ return typeMap[englishType] || '晴';
+ },
+ // 翻译天气代码(WMO代码转中文)
+ translateWeatherCode(code) {
+ if (code === 0) return '晴';
+ if (code <= 3) return '多云';
+ if (code <= 49) return '雾';
+ if (code <= 59) return '小雨';
+ if (code <= 69) return '中雨';
+ if (code <= 79) return '大雨';
+ if (code <= 84) return '小雪';
+ if (code <= 86) return '中雪';
+ if (code <= 99) return '大雪';
+ return '晴';
+ },
+ // 获取风向
+ getWindDirection(degree) {
+ const directions = ['北', '东北', '东', '东南', '南', '西南', '西', '西北'];
+ const index = Math.round(degree / 45) % 8;
+ return directions[index] + '风';
+ },
+ // 获取天气提示
+ getWeatherTip(weatherType) {
+ const tips = {
+ '晴': '天气晴朗,适合出行~',
+ '多云': '云层较多,注意防晒~',
+ '阴': '天气阴沉,记得带伞~',
+ '小雨': '有小雨,记得带伞~',
+ '中雨': '有中雨,出门记得带伞~',
+ '大雨': '有大雨,建议减少外出~',
+ '雷阵雨': '有雷阵雨,注意安全~',
+ '雾': '有雾,注意交通安全~',
+ };
+ return tips[weatherType] || '天有点冷,注意保暖~';
},
// 打开城市选择对话框
openCityDialog() {
@@ -734,26 +948,26 @@ export default {
this.$message.warning('请输入城市名称');
return;
}
-
+
// 如果城市没有变化,直接关闭对话框
if (city === this.weatherData.city) {
this.showCityDialog = false;
return;
}
-
+
// 保存城市到localStorage
localStorage.setItem('weatherCity', city);
-
+
// 更新当前城市
this.weatherData.city = city;
-
+
// 关闭对话框
this.showCityDialog = false;
this.cityInput = '';
-
+
// 重新获取天气数据
this.fetchWeather(city);
-
+
this.$message.success(`已切换到 ${city} 的天气信息`);
},
getBackgroundColor(type) {
@@ -794,7 +1008,6 @@ export default {
return backgrounds[type] || { start: '#F5F9FF', end: '#FBFBFD' }; // 默认柔和的蓝白色背景
},
getTypeIcon(type) {
- console.log(type);
// 根据天气类型返回对应的图标路径
const icons = {
晴: require('../../src/assets/icons/qing.png'),
@@ -864,10 +1077,21 @@ export default {
loadMap() {
this.$nextTick(() => {
loadBMap().then(() => {
- this.getmap();
+ if (typeof BMap === 'undefined') {
+ this.$message.error('百度地图API未正确加载');
+ return;
+ }
+ // 确保bmap扩展已加载
+ try {
+ require('echarts/extension/bmap/bmap');
+ } catch (e) {
+ // 忽略扩展加载错误
+ }
+ setTimeout(() => {
+ this.getmap();
+ }, 500);
}).catch((error) => {
- console.error('百度地图加载失败:', error);
- this.$message.error('百度地图加载失败,请检查API Key配置。错误信息:' + error.message);
+ this.$message.error('百度地图加载失败,请检查API Key配置');
});
});
},
@@ -924,6 +1148,15 @@ export default {
/** 地图 */
getmap() {
+ if (typeof BMap === 'undefined') {
+ this.$message.error('百度地图API未正确加载,请刷新页面重试');
+ return;
+ }
+
+ if (!this.$refs.map) {
+ return;
+ }
+
var myChart = this.$echarts.init(this.$refs.map);
var option;
@@ -963,11 +1196,63 @@ export default {
}
return res;
};
+
+ // 计算地图中心点和缩放级别(根据设备位置)
+ let calculateMapCenter = (deviceList) => {
+ let validDevices = deviceList.filter(d => d.longitude && d.latitude &&
+ d.longitude > 0 && d.latitude > 0 &&
+ d.longitude < 180 && d.latitude < 90);
+
+ if (validDevices.length === 0) {
+ // 如果没有有效设备,使用中国中心点
+ return { center: [104, 35.5], zoom: 5 };
+ }
+
+ // 计算所有设备坐标的平均值作为中心点
+ let sumLng = 0, sumLat = 0;
+ validDevices.forEach(d => {
+ sumLng += parseFloat(d.longitude);
+ sumLat += parseFloat(d.latitude);
+ });
+
+ let centerLng = sumLng / validDevices.length;
+ let centerLat = sumLat / validDevices.length;
+
+ // 根据设备分布范围计算合适的缩放级别
+ let minLng = Math.min(...validDevices.map(d => parseFloat(d.longitude)));
+ let maxLng = Math.max(...validDevices.map(d => parseFloat(d.longitude)));
+ let minLat = Math.min(...validDevices.map(d => parseFloat(d.latitude)));
+ let maxLat = Math.max(...validDevices.map(d => parseFloat(d.latitude)));
+
+ let lngRange = maxLng - minLng;
+ let latRange = maxLat - minLat;
+ let maxRange = Math.max(lngRange, latRange);
+
+ // 根据范围计算缩放级别
+ let zoom = 5;
+ if (maxRange < 0.1) zoom = 12;
+ else if (maxRange < 0.5) zoom = 10;
+ else if (maxRange < 1) zoom = 8;
+ else if (maxRange < 5) zoom = 6;
+ else zoom = 5;
+
+ return { center: [centerLng, centerLat], zoom: zoom };
+ };
+
+ // 使用长沙作为默认中心点,如果有设备数据则使用计算的中心点
+ let mapConfig = { center: [112.867037, 28.11857], zoom: 12 };
+ if (this.deviceList && this.deviceList.length > 0) {
+ const calculated = calculateMapCenter(this.deviceList);
+ if (calculated.center && calculated.center[0] > 0) {
+ mapConfig = calculated;
+ }
+ }
+
option = {
title: {
text: this.$t('home.onlineDevice') + this.deviceList.filter((x) => x.status == 3).length + ')',
subtext: '岩安测控数据平台',
- sublink: 'https://iot.fastbee.cn', // todo 替换为延安测控的官网
+ sublink: 'https://yack.cc', // todo 替换为延安测控的官网
target: '_blank',
textStyle: {
color: '#333',
@@ -1017,125 +1302,15 @@ export default {
},
},
bmap: {
- center: [133, 38],
- zoom: 5,
+ center: mapConfig.center,
+ zoom: mapConfig.zoom,
roam: true,
- mapStyle: {
- styleJson: [
- {
- featureType: 'water',
- elementType: 'all',
- stylers: {
- color: '#a0cfff',
- },
- },
- {
- featureType: 'land',
- elementType: 'all',
- stylers: {
- color: '#fafafa', // #fffff8 淡黄色
- },
- },
- {
- featureType: 'railway',
- elementType: 'all',
- stylers: {
- visibility: 'off',
- },
- },
- {
- featureType: 'highway',
- elementType: 'all',
- stylers: {
- color: '#fdfdfd',
- },
- },
- {
- featureType: 'highway',
- elementType: 'labels',
- stylers: {
- visibility: 'off',
- },
- },
- {
- featureType: 'arterial',
- elementType: 'geometry',
- stylers: {
- color: '#fefefe',
- },
- },
- {
- featureType: 'arterial',
- elementType: 'geometry.fill',
- stylers: {
- color: '#fefefe',
- },
- },
- {
- featureType: 'poi',
- elementType: 'all',
- stylers: {
- visibility: 'off',
- },
- },
- {
- featureType: 'green',
- elementType: 'all',
- stylers: {
- visibility: 'off',
- },
- },
- {
- featureType: 'subway',
- elementType: 'all',
- stylers: {
- visibility: 'off',
- },
- },
- {
- featureType: 'manmade',
- elementType: 'all',
- stylers: {
- color: '#d1d1d1',
- },
- },
- {
- featureType: 'local',
- elementType: 'all',
- stylers: {
- color: '#d1d1d1',
- },
- },
- {
- featureType: 'arterial',
- elementType: 'labels',
- stylers: {
- visibility: 'off',
- },
- },
- {
- featureType: 'boundary',
- elementType: 'all',
- stylers: {
- color: '#999999',
- },
- },
- {
- featureType: 'building',
- elementType: 'all',
- stylers: {
- color: '#d1d1d1',
- },
- },
- {
- featureType: 'label',
- elementType: 'labels.text.fill',
- stylers: {
- color: '#999999',
- },
- },
- ],
- },
+ // 确保地图正确初始化
+ enableMapClick: true,
+ // 暂时不使用自定义样式,确保地图能正常显示
+ // mapStyle: {
+ // styleJson: [...]
+ // },
},
series: [
{
@@ -1190,7 +1365,58 @@ export default {
],
};
- option && myChart.setOption(option);
+ if (option) {
+ try {
+ // 检查容器尺寸
+ if (this.$refs.map) {
+ const mapElement = this.$refs.map;
+ if (mapElement.offsetWidth === 0 || mapElement.offsetHeight === 0) {
+ setTimeout(() => {
+ this.getmap();
+ }, 500);
+ return;
+ }
+ mapElement.style.width = mapElement.offsetWidth + 'px';
+ mapElement.style.height = mapElement.offsetHeight + 'px';
+ mapElement.style.display = 'block';
+ }
+
+ // 设置地图配置
+ myChart.setOption(option, true);
+
+ // 等待地图初始化后调整大小和刷新
+ setTimeout(() => {
+ myChart.resize();
+
+ const bmapModel = myChart.getModel().getComponent('bmap');
+ if (bmapModel && bmapModel.getBMap) {
+ const bmapInstance = bmapModel.getBMap();
+ if (bmapInstance) {
+ // 启用地图功能
+ bmapInstance.enableScrollWheelZoom(true);
+ bmapInstance.enableDoubleClickZoom(true);
+ bmapInstance.enableDragging(true);
+
+ // 设置中心点和缩放级别
+ const centerPoint = new BMap.Point(mapConfig.center[0], mapConfig.center[1]);
+ bmapInstance.setCenter(centerPoint);
+ bmapInstance.setZoom(mapConfig.zoom);
+
+ // 刷新地图确保瓦片加载
+ setTimeout(() => {
+ myChart.resize();
+ bmapInstance.reset();
+ bmapInstance.setCenter(centerPoint);
+ bmapInstance.setZoom(mapConfig.zoom);
+ myChart.resize();
+ }, 500);
+ }
+ }
+ }, 800);
+ } catch (error) {
+ this.$message.error('地图初始化失败: ' + error.message);
+ }
+ }
},
drawPieCpu() {
@@ -1302,15 +1528,12 @@ export default {
},
],
label: {
- normal: {
- formatter: (value) => {
- return (value.value * 100).toFixed(0) + '%';
- },
- textStyle: {
- fontSize: 20,
- color: '#333',
- },
+ formatter: (value) => {
+ return (value.value * 100).toFixed(0) + '%';
},
+ // ECharts 4.0+ 规范:textStyle属性直接放在label下
+ fontSize: 20,
+ color: '#333',
},
outline: {
show: true,
@@ -1401,15 +1624,12 @@ export default {
},
],
label: {
- normal: {
- formatter: (value) => {
- return (value.value * 100).toFixed(0) + '%';
- },
- textStyle: {
- fontSize: 20,
- color: '#333',
- },
+ formatter: (value) => {
+ return (value.value * 100).toFixed(0) + '%';
},
+ // ECharts 4.0+ 规范:textStyle属性直接放在label下
+ fontSize: 20,
+ color: '#333',
},
outline: {
show: true,
@@ -1506,15 +1726,12 @@ export default {
},
],
label: {
- normal: {
- formatter: (value) => {
- return (value.value * 100).toFixed(0) + '%';
- },
- textStyle: {
- fontSize: 20,
- color: '#333',
- },
+ formatter: (value) => {
+ return (value.value * 100).toFixed(0) + '%';
},
+ // ECharts 4.0+ 规范:textStyle属性直接放在label下
+ fontSize: 20,
+ color: '#333',
},
outline: {
show: true,
@@ -1680,16 +1897,13 @@ export default {
},
],
label: {
- normal: {
- formatter: (value) => {
- return (value.value * 100).toFixed(0) + '%';
- },
- position: ['53.3%', '40%'],
- textStyle: {
- fontSize: 21,
- color: '#233d7d',
- },
+ formatter: (value) => {
+ return (value.value * 100).toFixed(0) + '%';
},
+ position: ['53.3%', '40%'],
+ // ECharts 4.0+ 规范:textStyle属性直接放在label下
+ fontSize: 21,
+ color: '#233d7d',
},
outline: {
show: true,
@@ -1890,16 +2104,13 @@ export default {
},
],
label: {
- normal: {
- formatter: (value) => {
- return (value.value * 100).toFixed(0) + '%';
- },
- position: ['53.3%', '40%'],
- textStyle: {
- fontSize: 21,
- color: '#73545c',
- },
+ formatter: (value) => {
+ return (value.value * 100).toFixed(0) + '%';
},
+ position: ['53.3%', '40%'],
+ // ECharts 4.0+ 规范:textStyle属性直接放在label下
+ fontSize: 21,
+ color: '#73545c',
},
outline: {
show: true,
@@ -1977,35 +2188,31 @@ export default {
radius: '55%',
lineStyle: {
- normal: {
- width: 8,
- color: {
- type: 'linear',
- colorStops: [
- {
- offset: 0,
- color: '#A9F387', // 0% 处的颜色
- },
- {
- offset: 1,
- color: '#48D8BF', // 100% 处的颜色
- },
- ],
- globalCoord: false, // 缺省为 false
- },
- shadowColor: 'rgba(72,216,191, 0.3)',
- shadowBlur: 10,
- shadowOffsetY: 20,
+ width: 8,
+ color: {
+ type: 'linear',
+ colorStops: [
+ {
+ offset: 0,
+ color: '#A9F387', // 0% 处的颜色
+ },
+ {
+ offset: 1,
+ color: '#48D8BF', // 100% 处的颜色
+ },
+ ],
+ globalCoord: false, // 缺省为 false
},
+ shadowColor: 'rgba(72,216,191, 0.3)',
+ shadowBlur: 10,
+ shadowOffsetY: 20,
},
itemStyle: {
- normal: {
- color: 'rgba(72,216,191, 0.3)',
- borderWidth: 10,
- /*shadowColor: 'rgba(72,216,191, 0.3)',
- shadowBlur: 100,*/
- borderColor: '#A9F387',
- },
+ color: 'rgba(72,216,191, 0.3)',
+ borderWidth: 10,
+ /*shadowColor: 'rgba(72,216,191, 0.3)',
+ shadowBlur: 100,*/
+ borderColor: '#A9F387',
},
smooth: true,
},
@@ -2524,17 +2731,32 @@ $aqi-unhealthy-color: #f44336;
.map-container {
width: 100%;
- height: 500px; /* 减少高度 */
+ height: 500px;
position: relative;
border-radius: 15px;
- overflow: hidden;
+ overflow: hidden; /* 改为hidden,避免内容溢出 */
+ z-index: 10;
.map {
- width: 100%;
- height: 100%;
- /* 可根据需要添加地图相关样式 */
+ width: 100% !important;
+ height: 100% !important;
+ min-height: 500px;
+ position: relative;
+ z-index: 10;
+ background: transparent;
+ /* 确保地图容器有明确的尺寸 */
+ display: block;
}
}
+
+ /* 确保ECharts地图容器正确显示 */
+ .map :deep(.ec-extension-bmap) {
+ position: absolute !important;
+ width: 100% !important;
+ height: 100% !important;
+ z-index: 10 !important;
+ background-color: transparent !important;
+ }
}
/* 响应式设计 */
diff --git a/vue/src/views/index_v1.vue b/vue/src/views/index_v1.vue
index d2d2ec63..7d82d7ea 100644
--- a/vue/src/views/index_v1.vue
+++ b/vue/src/views/index_v1.vue
@@ -1,98 +1,211 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+