feat: 优化页面效果
This commit is contained in:
parent
d694ea8835
commit
0d88e161d9
@ -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>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user