20251226:首页百度地图完全可用
This commit is contained in:
parent
bec58ecbf2
commit
9ebb0d0986
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
|
||||
@ -1,98 +1,211 @@
|
||||
<template>
|
||||
<div class="dashboard-editor-container">
|
||||
|
||||
<panel-group @handleSetLineChartData="handleSetLineChartData" />
|
||||
|
||||
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
|
||||
<line-chart :chart-data="lineChartData" />
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="32">
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<raddar-chart />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<pie-chart />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<bar-chart />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PanelGroup from './dashboard/PanelGroup'
|
||||
import LineChart from './dashboard/LineChart'
|
||||
import RaddarChart from './dashboard/RaddarChart'
|
||||
import PieChart from './dashboard/PieChart'
|
||||
import BarChart from './dashboard/BarChart'
|
||||
|
||||
const lineChartData = {
|
||||
newVisitis: {
|
||||
expectedData: [100, 120, 161, 134, 105, 160, 165],
|
||||
actualData: [120, 82, 91, 154, 162, 140, 145]
|
||||
},
|
||||
messages: {
|
||||
expectedData: [200, 192, 120, 144, 160, 130, 140],
|
||||
actualData: [180, 160, 151, 106, 145, 150, 130]
|
||||
},
|
||||
purchases: {
|
||||
expectedData: [80, 100, 121, 104, 105, 90, 100],
|
||||
actualData: [120, 90, 100, 138, 142, 130, 130]
|
||||
},
|
||||
shoppings: {
|
||||
expectedData: [130, 140, 141, 142, 145, 150, 160],
|
||||
actualData: [120, 82, 91, 154, 162, 140, 130]
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: {
|
||||
PanelGroup,
|
||||
LineChart,
|
||||
RaddarChart,
|
||||
PieChart,
|
||||
BarChart
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lineChartData: lineChartData.newVisitis
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>百度地图测试页面</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
|
||||
<style type="text/css">
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSetLineChartData(type) {
|
||||
this.lineChartData = lineChartData[type]
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
background-color: #fff;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#map-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.info {
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
background-color: #e3f2fd;
|
||||
border-radius: 5px;
|
||||
border-left: 4px solid #2196F3;
|
||||
}
|
||||
.info h3 {
|
||||
margin: 0 0 10px 0;
|
||||
color: #1976D2;
|
||||
}
|
||||
.info p {
|
||||
margin: 5px 0;
|
||||
color: #424242;
|
||||
}
|
||||
.status {
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.status.success {
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
}
|
||||
.status.error {
|
||||
background-color: #f44336;
|
||||
color: white;
|
||||
}
|
||||
.status.loading {
|
||||
background-color: #FF9800;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="info">
|
||||
<h3>百度地图测试页面</h3>
|
||||
<p>AK配置: <span id="ak-status" class="status loading">检查中...</span></p>
|
||||
<p>BMap状态: <span id="bmap-status" class="status loading">等待加载...</span></p>
|
||||
<p>地图容器: <span id="container-status" class="status loading">检查中...</span></p>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div id="map-container"></div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
// 从环境变量获取AK(这里需要手动设置,因为这是静态HTML文件)
|
||||
// 实际项目中应该从 process.env.VUE_APP_BAI_DU_AK 获取
|
||||
const AK = 's9mUXN9a7bKgVu6U6Z3bXhKSxtz97YPI'; // 请替换为您的AK
|
||||
|
||||
// 更新状态显示
|
||||
function updateStatus(elementId, text, className) {
|
||||
const element = document.getElementById(elementId);
|
||||
element.textContent = text;
|
||||
element.className = 'status ' + className;
|
||||
}
|
||||
|
||||
// 检查AK
|
||||
if (AK && AK !== 'your_baidu_map_ak_here') {
|
||||
updateStatus('ak-status', '已配置', 'success');
|
||||
} else {
|
||||
updateStatus('ak-status', '未配置', 'error');
|
||||
document.getElementById('map-container').innerHTML = '<div style="display:flex;align-items:center;justify-content:center;height:100%;color:#f44336;">请在代码中配置百度地图AK</div>';
|
||||
}
|
||||
|
||||
// 检查容器
|
||||
const container = document.getElementById('map-container');
|
||||
if (container) {
|
||||
updateStatus('container-status', '存在 (' + container.offsetWidth + 'x' + container.offsetHeight + ')', 'success');
|
||||
} else {
|
||||
updateStatus('container-status', '不存在', 'error');
|
||||
}
|
||||
|
||||
// 加载百度地图API
|
||||
console.log('[测试页面] 开始加载百度地图API...');
|
||||
console.log('[测试页面] AK:', AK);
|
||||
|
||||
// 使用callback方式加载
|
||||
window.onBMapCallback = function() {
|
||||
console.log('[测试页面] 百度地图API加载成功');
|
||||
updateStatus('bmap-status', '已加载', 'success');
|
||||
|
||||
if (typeof BMap === 'undefined') {
|
||||
console.error('[测试页面] BMap未定义');
|
||||
updateStatus('bmap-status', 'BMap未定义', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 创建地图实例
|
||||
var map = new BMap.Map("map-container");
|
||||
console.log('[测试页面] 地图实例创建成功');
|
||||
|
||||
// 创建中心点坐标(北京天安门)
|
||||
var point = new BMap.Point(116.404, 39.915);
|
||||
console.log('[测试页面] 中心点:', point);
|
||||
|
||||
// 初始化地图,设置中心点和缩放级别
|
||||
map.centerAndZoom(point, 15);
|
||||
console.log('[测试页面] 地图中心点和缩放级别已设置');
|
||||
|
||||
// 启用一些交互功能
|
||||
map.enableScrollWheelZoom(true);
|
||||
map.enableDoubleClickZoom();
|
||||
console.log('[测试页面] 地图交互功能已启用');
|
||||
|
||||
// 添加默认缩放平移控件
|
||||
map.addControl(new BMap.NavigationControl());
|
||||
console.log('[测试页面] 地图控件已添加');
|
||||
|
||||
// 添加标记点
|
||||
var marker = new BMap.Marker(point);
|
||||
map.addOverlay(marker);
|
||||
console.log('[测试页面] 标记点已添加');
|
||||
|
||||
// 添加信息窗口
|
||||
var infoWindow = new BMap.InfoWindow(
|
||||
'<div style="padding:10px;">' +
|
||||
'<h3 style="margin:0 0 10px 0;">天安门广场</h3>' +
|
||||
'<p style="margin:5px 0;">位于北京市中心,是世界上最大的城市广场之一。</p>' +
|
||||
'<p style="margin:5px 0;">坐标:116.404, 39.915</p>' +
|
||||
'</div>',
|
||||
{ width: 250, height: 150 }
|
||||
);
|
||||
|
||||
// 标记点点击事件
|
||||
marker.addEventListener("click", function() {
|
||||
map.openInfoWindow(infoWindow, point);
|
||||
});
|
||||
|
||||
console.log('[测试页面] 地图初始化完成');
|
||||
|
||||
// 检查地图是否正常显示
|
||||
setTimeout(function() {
|
||||
const mapContainer = map.getContainer();
|
||||
const tiles = mapContainer.querySelectorAll('img');
|
||||
console.log('[测试页面] 地图瓦片数量:', tiles.length);
|
||||
if (tiles.length > 0) {
|
||||
console.log('[测试页面] ✓ 地图瓦片已加载,地图应该正常显示');
|
||||
} else {
|
||||
console.warn('[测试页面] ⚠ 地图瓦片未加载,可能存在问题');
|
||||
}
|
||||
}, 2000);
|
||||
|
||||
} catch (error) {
|
||||
console.error('[测试页面] 地图初始化失败:', error);
|
||||
updateStatus('bmap-status', '初始化失败: ' + error.message, 'error');
|
||||
document.getElementById('map-container').innerHTML =
|
||||
'<div style="display:flex;align-items:center;justify-content:center;height:100%;color:#f44336;">' +
|
||||
'地图初始化失败: ' + error.message +
|
||||
'</div>';
|
||||
}
|
||||
};
|
||||
|
||||
// 如果AK已配置,加载百度地图API
|
||||
if (AK && AK !== 'your_baidu_map_ak_here') {
|
||||
const script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
const protocol = document.location.protocol === 'https:' ? 'https:' : 'http:';
|
||||
const apiUrl = protocol + '//api.map.baidu.com/api?v=2.0&ak=' + AK + '&callback=onBMapCallback';
|
||||
script.src = apiUrl;
|
||||
console.log('[测试页面] 正在加载:', apiUrl);
|
||||
|
||||
script.onerror = function(error) {
|
||||
console.error('[测试页面] 脚本加载失败:', error);
|
||||
updateStatus('bmap-status', '脚本加载失败', 'error');
|
||||
};
|
||||
|
||||
script.onload = function() {
|
||||
console.log('[测试页面] 脚本标签加载完成,等待回调...');
|
||||
};
|
||||
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dashboard-editor-container {
|
||||
padding: 32px;
|
||||
background-color: rgb(240, 242, 245);
|
||||
position: relative;
|
||||
|
||||
.chart-wrapper {
|
||||
background: #fff;
|
||||
padding: 16px 16px 0;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width:1024px) {
|
||||
.chart-wrapper {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user