feat: 优化页面效果

This commit is contained in:
yarnom 2025-07-04 17:44:11 +08:00
parent d694ea8835
commit 0d88e161d9

View File

@ -570,6 +570,17 @@
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 12px; margin-bottom: 12px;
cursor: move;
padding: 10px 20px;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 8px 8px 0 0;
transition: background-color 0.2s ease;
margin: -16px -16px 12px -16px;
user-select: none;
}
.weather-card-header:hover {
background-color: rgba(26, 160, 148, 0.05);
} }
.weather-card-title { .weather-card-title {
@ -773,6 +784,12 @@
.weather-param-value { .weather-param-value {
font-size: 8px; font-size: 8px;
} }
#measureStatus{
display: flex;
justify-content: center;
padding: 6px 0px;
}
} }
</style> </style>
@ -830,9 +847,11 @@
<div class="map-card"> <div class="map-card">
<div id="map-container"> <div id="map-container">
<div id="weatherForecastCard" class="weather-forecast-card" style="display: none;"> <div id="weatherForecastCard" class="weather-forecast-card" style="display: none;" th:if="${role=='SUPER_ADMIN'}">
<div class="weather-card-header"> <div class="weather-card-header">
<h3 class="weather-card-title">Windy 天气预测 :) </h3> <h3 class="weather-card-title">
Windy 天气预测 :)
</h3>
<button class="weather-close-btn" onclick="closeWeatherCard()">×</button> <button class="weather-close-btn" onclick="closeWeatherCard()">×</button>
</div> </div>
<div id="weatherDeviceInfo" class="weather-device-info"> <div id="weatherDeviceInfo" class="weather-device-info">
@ -924,7 +943,7 @@
</div> </div>
</div> </div>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<div class="dropdown-group"> <div class="dropdown-group" th:if="${role=='SUPER_ADMIN'}">
<div class="dropdown-group-title">Windy 天气预测</div> <div class="dropdown-group-title">Windy 天气预测</div>
<div class="dropdown-item"> <div class="dropdown-item">
<label class="switch-label"> <label class="switch-label">
@ -1577,7 +1596,7 @@
function onMapTypeChange() { function onMapTypeChange() {
var mapType = document.getElementById('mapTypeSelectNew').value; var mapType = document.getElementById('mapTypeSelectNew').value;
if(mapType.startsWith('google_') && [[${role}]] != "SUPER_ADMIN") { if(mapType.startsWith('google_') && /*[[${role}]]*/ 'USER' != "SUPER_ADMIN") {
layer.msg('拒绝使用'); layer.msg('拒绝使用');
document.getElementById('mapTypeSelectNew').value = 'tianditu_terrain_hybrid'; document.getElementById('mapTypeSelectNew').value = 'tianditu_terrain_hybrid';
mapType = 'tianditu_terrain_hybrid'; mapType = 'tianditu_terrain_hybrid';
@ -1912,6 +1931,9 @@
// 默认显示所有设备 // 默认显示所有设备
document.getElementById('warningFilter').value = 'all'; document.getElementById('warningFilter').value = 'all';
showAll(); showAll();
// 初始化天气卡片拖动功能
initWeatherCardDrag();
}); });
function queryDevices(status_type) { function queryDevices(status_type) {
@ -2180,7 +2202,6 @@
function deactivateMeasure() { function deactivateMeasure() {
measureActive = false; measureActive = false;
// 隐藏测量状态指示器 // 隐藏测量状态指示器
document.getElementById('measureStatus').style.display = 'none'; document.getElementById('measureStatus').style.display = 'none';
@ -2250,6 +2271,12 @@
document.getElementById('mapFunctionsMenu').classList.remove('show'); document.getElementById('mapFunctionsMenu').classList.remove('show');
} }
function toggleWeatherForecast() { function toggleWeatherForecast() {
var role = /*[[${role}]]*/ 'USER';
if (role !== 'SUPER_ADMIN') {
layer.msg('您没有权限使用此功能');
return;
}
weatherEnabled = document.getElementById('enableWeatherSwitch').checked; weatherEnabled = document.getElementById('enableWeatherSwitch').checked;
if (weatherEnabled) { if (weatherEnabled) {
layer.msg( layer.msg(
@ -2290,15 +2317,18 @@
anim: 2 anim: 2
}); });
} }
// 显示天气预测卡片
function showWeatherForecast(deviceInfo) { function showWeatherForecast(deviceInfo) {
currentWeatherDevice = deviceInfo; currentWeatherDevice = deviceInfo;
currentForecastIndex = 0; currentForecastIndex = 0;
weatherData = null; weatherData = null;
var role = /*[[${role}]]*/ 'USER';
if (role !== 'SUPER_ADMIN') {
return;
}
if (!weatherEnabled) { if (!weatherEnabled) {
// 如果天气预测未启用,显示提示信息
layer.msg( layer.msg(
'天气预测功能未启用,请在地图功能菜单中开启', '天气预测功能未启用,请在地图功能菜单中开启',
{time: 2000} {time: 2000}
@ -2311,6 +2341,8 @@
'坐标: ' + deviceInfo.latitude.toFixed(4) + ', ' + deviceInfo.longitude.toFixed(4); '坐标: ' + deviceInfo.latitude.toFixed(4) + ', ' + deviceInfo.longitude.toFixed(4);
document.getElementById('weatherForecastCard').style.display = 'block'; document.getElementById('weatherForecastCard').style.display = 'block';
initWeatherCardDrag();
document.getElementById('weatherForecastContent').innerHTML = document.getElementById('weatherForecastContent').innerHTML =
'<div class="weather-loading">' + '<div class="weather-loading">' +
@ -2363,8 +2395,7 @@
var date = new Date(timestamp); var date = new Date(timestamp);
timeDisplay.textContent = formatDateTime(date); timeDisplay.textContent = formatDateTime(date);
} }
// 获取天气数据
function fetchWeatherData(lat, lon) { function fetchWeatherData(lat, lon) {
var requestBody = { var requestBody = {
"lat": parseFloat(lat.toFixed(2)), "lat": parseFloat(lat.toFixed(2)),
@ -2412,7 +2443,7 @@
if (weatherData['temp-surface'] && weatherData['temp-surface'][i] !== null) { if (weatherData['temp-surface'] && weatherData['temp-surface'][i] !== null) {
var temp = (weatherData['temp-surface'][i] - 273.15).toFixed(1); // 转换为摄氏度 var temp = (weatherData['temp-surface'][i] - 273.15).toFixed(1); // 转换为摄氏度
forecastHtml += createWeatherParam('🌡️', '温度', temp + '°C'); forecastHtml += createWeatherParam('温度', temp + '°C');
} }
if (weatherData['wind_u-surface'] && weatherData['wind_v-surface'] && if (weatherData['wind_u-surface'] && weatherData['wind_v-surface'] &&
@ -2421,30 +2452,30 @@
var windV = weatherData['wind_v-surface'][i]; var windV = weatherData['wind_v-surface'][i];
var windSpeed = Math.sqrt(windU * windU + windV * windV).toFixed(1); var windSpeed = Math.sqrt(windU * windU + windV * windV).toFixed(1);
var windDir = getWindDirection(windU, windV); var windDir = getWindDirection(windU, windV);
forecastHtml += createWeatherParam('💨', '风速', windSpeed + ' m/s'); forecastHtml += createWeatherParam('风速', windSpeed + ' m/s');
forecastHtml += createWeatherParam('🧭', '风向', windDir); forecastHtml += createWeatherParam('风向', windDir);
} }
if (weatherData['past3hprecip-surface'] && weatherData['past3hprecip-surface'][i] !== null) { if (weatherData['past3hprecip-surface'] && weatherData['past3hprecip-surface'][i] !== null) {
var precip = weatherData['past3hprecip-surface'][i].toFixed(1); var precip = weatherData['past3hprecip-surface'][i].toFixed(1);
forecastHtml += createWeatherParam('🌧️', '降水', precip + ' mm'); forecastHtml += createWeatherParam('降水', precip + ' mm');
} }
if (weatherData['rh-surface'] && weatherData['rh-surface'][i] !== null) { if (weatherData['rh-surface'] && weatherData['rh-surface'][i] !== null) {
var humidity = weatherData['rh-surface'][i].toFixed(0); var humidity = weatherData['rh-surface'][i].toFixed(0);
forecastHtml += createWeatherParam('💧', '湿度', humidity + '%'); forecastHtml += createWeatherParam('湿度', humidity + '%');
} }
// 气压 // 气压
if (weatherData['pressure-surface'] && weatherData['pressure-surface'][i] !== null) { if (weatherData['pressure-surface'] && weatherData['pressure-surface'][i] !== null) {
var pressure = (weatherData['pressure-surface'][i] / 100).toFixed(0); // 转换为百帕 var pressure = (weatherData['pressure-surface'][i] / 100).toFixed(0); // 转换为百帕
forecastHtml += createWeatherParam('📊', '气压', pressure + ' hPa'); forecastHtml += createWeatherParam('气压', pressure + ' hPa');
} }
// 阵风 // 阵风
if (weatherData['gust-surface'] && weatherData['gust-surface'][i] !== null) { if (weatherData['gust-surface'] && weatherData['gust-surface'][i] !== null) {
var gust = weatherData['gust-surface'][i].toFixed(1); var gust = weatherData['gust-surface'][i].toFixed(1);
forecastHtml += createWeatherParam('💨', '阵风', gust + ' m/s'); forecastHtml += createWeatherParam('阵风', gust + ' m/s');
} }
forecastHtml += '</div></div>'; forecastHtml += '</div></div>';
@ -2459,9 +2490,8 @@
'</div>'; '</div>';
} }
function createWeatherParam(icon, label, value) { function createWeatherParam(label, value) {
return '<div class="weather-param">' + return '<div class="weather-param">' +
'<span class="weather-param-icon">' + icon + '</span>' +
'<span class="weather-param-label">' + label + '</span>' + '<span class="weather-param-label">' + label + '</span>' +
'<span class="weather-param-value">' + value + '</span>' + '<span class="weather-param-value">' + value + '</span>' +
'</div>'; '</div>';
@ -2484,6 +2514,179 @@
var index = Math.round(angle / 45) % 8; var index = Math.round(angle / 45) % 8;
return directions[index]; return directions[index];
} }
function initWeatherCardDrag() {
var weatherCard = document.getElementById('weatherForecastCard');
if (!weatherCard) return;
var isDragging = false;
var startX, startY;
var startLeft, startTop;
var originalStyles = {
top: '55%',
right: '20px',
left: 'auto',
transform: 'translateY(-50%)'
};
var cardHeader = weatherCard.querySelector('.weather-card-header');
cardHeader.addEventListener('dblclick', function() {
// 重置
weatherCard.style.top = originalStyles.top;
weatherCard.style.right = originalStyles.right;
weatherCard.style.left = originalStyles.left;
weatherCard.style.transform = originalStyles.transform;
});
var cardHeader = weatherCard.querySelector('.weather-card-header');
cardHeader.addEventListener('mousedown', function(e) {
if (e.target.tagName === 'BUTTON' ||
e.target.classList.contains('weather-nav-btn') ||
e.target.classList.contains('weather-close-btn')) {
return;
}
e.preventDefault();
startX = e.clientX;
startY = e.clientY;
var rect = weatherCard.getBoundingClientRect();
startLeft = rect.left;
startTop = rect.top;
// 准备拖动
isDragging = true;
// 设置为绝对定位(如果还不是)
if (getComputedStyle(weatherCard).position !== 'absolute') {
weatherCard.style.position = 'absolute';
weatherCard.style.top = rect.top + 'px';
weatherCard.style.left = rect.left + 'px';
weatherCard.style.right = 'auto';
weatherCard.style.transform = 'none';
}
weatherCard.style.opacity = '0.9';
weatherCard.style.boxShadow = '0 12px 48px rgba(0, 0, 0, 0.25)';
weatherCard.style.zIndex = '1200';
document.body.style.userSelect = 'none';
});
// 鼠标移动事件
document.addEventListener('mousemove', function(e) {
if (!isDragging) return;
// 计算移动距离
var dx = e.clientX - startX;
var dy = e.clientY - startY;
// 计算新位置
var newLeft = startLeft + dx;
var newTop = startTop + dy;
// 限制在视口内
var maxX = window.innerWidth - weatherCard.offsetWidth;
var maxY = window.innerHeight - weatherCard.offsetHeight;
newLeft = Math.max(0, Math.min(newLeft, maxX));
newTop = Math.max(0, Math.min(newTop, maxY));
// 应用新位置
weatherCard.style.left = newLeft + 'px';
weatherCard.style.top = newTop + 'px';
});
// 鼠标释放事件
document.addEventListener('mouseup', function() {
if (!isDragging) return;
isDragging = false;
weatherCard.style.opacity = '1';
weatherCard.style.boxShadow = '0 8px 32px rgba(0, 0, 0, 0.15)';
document.body.style.userSelect = '';
});
cardHeader.addEventListener('touchstart', function(e) {
if (e.target.tagName === 'BUTTON' ||
e.target.classList.contains('weather-nav-btn') ||
e.target.classList.contains('weather-close-btn')) {
return;
}
e.preventDefault();
var touch = e.touches[0];
startX = touch.clientX;
startY = touch.clientY;
// 获取当前卡片位置
var rect = weatherCard.getBoundingClientRect();
startLeft = rect.left;
startTop = rect.top;
// 准备拖动
isDragging = true;
// 设置为绝对定位(如果还不是)
if (getComputedStyle(weatherCard).position !== 'absolute') {
weatherCard.style.position = 'absolute';
weatherCard.style.top = rect.top + 'px';
weatherCard.style.left = rect.left + 'px';
weatherCard.style.right = 'auto';
weatherCard.style.transform = 'none';
}
// 添加活动样式
weatherCard.style.opacity = '0.9';
weatherCard.style.boxShadow = '0 12px 48px rgba(0, 0, 0, 0.25)';
// 在拖动过程中临时禁用文本选择
document.body.style.userSelect = 'none';
});
document.addEventListener('touchmove', function(e) {
if (!isDragging) return;
e.preventDefault(); // 防止页面滚动
var touch = e.touches[0];
// 计算移动距离
var dx = touch.clientX - startX;
var dy = touch.clientY - startY;
// 计算新位置
var newLeft = startLeft + dx;
var newTop = startTop + dy;
// 限制在视口内
var maxX = window.innerWidth - weatherCard.offsetWidth;
var maxY = window.innerHeight - weatherCard.offsetHeight;
newLeft = Math.max(0, Math.min(newLeft, maxX));
newTop = Math.max(0, Math.min(newTop, maxY));
// 应用新位置
weatherCard.style.left = newLeft + 'px';
weatherCard.style.top = newTop + 'px';
});
document.addEventListener('touchend', function() {
if (!isDragging) return;
isDragging = false;
weatherCard.style.opacity = '1';
weatherCard.style.boxShadow = '0 8px 32px rgba(0, 0, 0, 0.15)';
// 恢复文本选择功能
document.body.style.userSelect = '';
});
}
</script> </script>
</body> </body>