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;
align-items: center;
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 {
@ -773,6 +784,12 @@
.weather-param-value {
font-size: 8px;
}
#measureStatus{
display: flex;
justify-content: center;
padding: 6px 0px;
}
}
</style>
@ -830,9 +847,11 @@
<div class="map-card">
<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">
<h3 class="weather-card-title">Windy 天气预测 :) </h3>
<h3 class="weather-card-title">
Windy 天气预测 :)
</h3>
<button class="weather-close-btn" onclick="closeWeatherCard()">×</button>
</div>
<div id="weatherDeviceInfo" class="weather-device-info">
@ -924,7 +943,7 @@
</div>
</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-item">
<label class="switch-label">
@ -1577,7 +1596,7 @@
function onMapTypeChange() {
var mapType = document.getElementById('mapTypeSelectNew').value;
if(mapType.startsWith('google_') && [[${role}]] != "SUPER_ADMIN") {
if(mapType.startsWith('google_') && /*[[${role}]]*/ 'USER' != "SUPER_ADMIN") {
layer.msg('拒绝使用');
document.getElementById('mapTypeSelectNew').value = 'tianditu_terrain_hybrid';
mapType = 'tianditu_terrain_hybrid';
@ -1912,6 +1931,9 @@
// 默认显示所有设备
document.getElementById('warningFilter').value = 'all';
showAll();
// 初始化天气卡片拖动功能
initWeatherCardDrag();
});
function queryDevices(status_type) {
@ -2180,7 +2202,6 @@
function deactivateMeasure() {
measureActive = false;
// 隐藏测量状态指示器
document.getElementById('measureStatus').style.display = 'none';
@ -2250,6 +2271,12 @@
document.getElementById('mapFunctionsMenu').classList.remove('show');
}
function toggleWeatherForecast() {
var role = /*[[${role}]]*/ 'USER';
if (role !== 'SUPER_ADMIN') {
layer.msg('您没有权限使用此功能');
return;
}
weatherEnabled = document.getElementById('enableWeatherSwitch').checked;
if (weatherEnabled) {
layer.msg(
@ -2290,15 +2317,18 @@
anim: 2
});
}
// 显示天气预测卡片
function showWeatherForecast(deviceInfo) {
currentWeatherDevice = deviceInfo;
currentForecastIndex = 0;
weatherData = null;
var role = /*[[${role}]]*/ 'USER';
if (role !== 'SUPER_ADMIN') {
return;
}
if (!weatherEnabled) {
// 如果天气预测未启用,显示提示信息
layer.msg(
'天气预测功能未启用,请在地图功能菜单中开启',
{time: 2000}
@ -2311,6 +2341,8 @@
'坐标: ' + deviceInfo.latitude.toFixed(4) + ', ' + deviceInfo.longitude.toFixed(4);
document.getElementById('weatherForecastCard').style.display = 'block';
initWeatherCardDrag();
document.getElementById('weatherForecastContent').innerHTML =
'<div class="weather-loading">' +
@ -2363,8 +2395,7 @@
var date = new Date(timestamp);
timeDisplay.textContent = formatDateTime(date);
}
// 获取天气数据
function fetchWeatherData(lat, lon) {
var requestBody = {
"lat": parseFloat(lat.toFixed(2)),
@ -2412,7 +2443,7 @@
if (weatherData['temp-surface'] && weatherData['temp-surface'][i] !== null) {
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'] &&
@ -2421,30 +2452,30 @@
var windV = weatherData['wind_v-surface'][i];
var windSpeed = Math.sqrt(windU * windU + windV * windV).toFixed(1);
var windDir = getWindDirection(windU, windV);
forecastHtml += createWeatherParam('💨', '风速', windSpeed + ' m/s');
forecastHtml += createWeatherParam('🧭', '风向', windDir);
forecastHtml += createWeatherParam('风速', windSpeed + ' m/s');
forecastHtml += createWeatherParam('风向', windDir);
}
if (weatherData['past3hprecip-surface'] && weatherData['past3hprecip-surface'][i] !== null) {
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) {
var humidity = weatherData['rh-surface'][i].toFixed(0);
forecastHtml += createWeatherParam('💧', '湿度', humidity + '%');
forecastHtml += createWeatherParam('湿度', humidity + '%');
}
// 气压
if (weatherData['pressure-surface'] && weatherData['pressure-surface'][i] !== null) {
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) {
var gust = weatherData['gust-surface'][i].toFixed(1);
forecastHtml += createWeatherParam('💨', '阵风', gust + ' m/s');
forecastHtml += createWeatherParam('阵风', gust + ' m/s');
}
forecastHtml += '</div></div>';
@ -2459,9 +2490,8 @@
'</div>';
}
function createWeatherParam(icon, label, value) {
function createWeatherParam(label, value) {
return '<div class="weather-param">' +
'<span class="weather-param-icon">' + icon + '</span>' +
'<span class="weather-param-label">' + label + '</span>' +
'<span class="weather-param-value">' + value + '</span>' +
'</div>';
@ -2484,6 +2514,179 @@
var index = Math.round(angle / 45) % 8;
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>
</body>