diff --git a/sec-beidou/src/main/resources/templates/page/device_overview.html b/sec-beidou/src/main/resources/templates/page/device_overview.html index 127fd788..60b07f20 100644 --- a/sec-beidou/src/main/resources/templates/page/device_overview.html +++ b/sec-beidou/src/main/resources/templates/page/device_overview.html @@ -367,6 +367,17 @@ font-size: 10px; padding: 2px 4px; } + + /* 移动端下拉菜单适配 */ + .dropdown-menu { + min-width: 180px; + max-width: 95vw; + } + + .dropdown-item { + padding: 8px 12px; + font-size: 12px; + } } .ol-tooltip { @@ -386,6 +397,124 @@ color: #222; border: 1px solid #ffcc33; } + + /* 下拉菜单样式 */ + .dropdown-container { + position: relative; + display: inline-block; + } + + .dropdown-toggle { + cursor: pointer; + display: flex; + align-items: center; + } + + .dropdown-toggle::after { + content: ''; + display: inline-block; + margin-left: 6px; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + vertical-align: middle; + } + + .dropdown-menu { + display: none; + position: absolute; + top: 100%; + left: 0; + z-index: 1100; + min-width: 200px; + padding: 8px 0; + margin-top: 2px; + background: white; + border-radius: 6px; + box-shadow: 0 3px 12px rgba(0,0,0,0.15); + border: 1px solid rgba(0,0,0,0.1); + } + + .dropdown-menu.show { + display: block; + } + + .dropdown-group { + padding: 0 8px; + } + + .dropdown-group-title { + font-size: 12px; + color: #666; + padding: 6px 8px; + font-weight: 500; + } + + .dropdown-item { + padding: 6px 12px; + cursor: pointer; + font-size: 13px; + color: #333; + border-radius: 4px; + margin: 2px 0; + } + + .dropdown-item:hover { + background: rgba(26, 160, 148, 0.1); + } + + .dropdown-divider { + height: 1px; + background: #e9ecef; + margin: 8px 0; + } + + /* 开关样式 */ + .switch-label { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + cursor: pointer; + } + + .switch-label input { + opacity: 0; + width: 0; + height: 0; + position: absolute; + } + + .switch-slider { + position: relative; + display: inline-block; + width: 36px; + height: 18px; + background-color: #ccc; + border-radius: 18px; + transition: .4s; + flex-shrink: 0; + } + + .switch-slider:before { + position: absolute; + content: ""; + height: 14px; + width: 14px; + left: 2px; + bottom: 2px; + background-color: white; + border-radius: 50%; + transition: .4s; + } + + input:checked + .switch-slider { + background-color: #1aa094; + } + + input:checked + .switch-slider:before { + transform: translateX(18px); + } @@ -477,24 +606,38 @@
- -
- - - -
-
- - - +
@@ -924,6 +1067,14 @@ addDeviceMarkers(); myLocation(); startLocationUpdates(); + + // 设置默认显示模式 + showDeviceId = true; + showCluster = true; + + // 确保开关状态与默认值一致 + document.getElementById('showDeviceIdSwitch').checked = showDeviceId; + document.getElementById('showClusterSwitch').checked = showCluster; } function switchMapType(mapType) { @@ -1029,52 +1180,17 @@ var deviceId = document.getElementById('deviceSearchNew').value.trim(); if (!deviceId) { - currentSearchedDevice = null; - vectorSource.clear(); - - for (var i = 0; i < allFeatures.length; i++) { - vectorSource.addFeature(allFeatures[i]); - } - - var filterValue = document.getElementById('warningFilter').value; - if (filterValue === 'warning1') { - hideGreen(); - hideRed(); - } else if (filterValue === 'warning2') { - hideGreen(); - hideOrange(); - } - - document.getElementById('btn-device-locate').style.display = 'none'; + layer.msg('请输入设备编号'); return; } - currentSearchedDevice = deviceId; + // 定位到设备,但不隐藏其他设备 filterByDeviceId(deviceId); - - // 更新过滤器为显示所有设备,因为搜索时需要显示匹配的设备 - document.getElementById('warningFilter').value = 'all'; - - // 显示设备定位信息 - document.getElementById('current-device-id-new').textContent = deviceId; - document.getElementById('toolbar-device-locate').style.display = 'flex'; } function clearDeviceSearch() { - currentSearchedDevice = null; - // document.getElementById('deviceSearch').value = ''; + // 清空搜索框 document.getElementById('deviceSearchNew').value = ''; - document.getElementById('toolbar-device-locate').style.display = 'none'; - - // 根据当前过滤器状态重新显示设备 - var filterValue = document.getElementById('warningFilter').value; - if (filterValue === 'all') { - showAll(); - } else if (filterValue === 'warning1') { - showWarning1(); - } else if (filterValue === 'warning2') { - showWarning2(); - } } function myLocation() { @@ -1141,7 +1257,7 @@ currentSearchedDevice = null; // document.getElementById('deviceSearch').value = ''; document.getElementById('deviceSearchNew').value = ''; - document.getElementById('toolbar-device-locate').style.display = 'none'; + // 已移除toolbar-device-locate元素,不需要再设置其display属性 var savedMyLocationFeature = myLocationFeature; vectorSource.clear(); @@ -1319,55 +1435,33 @@ } function filterByDeviceId(deviceId) { - var savedMyLocationFeature = myLocationFeature; - - vectorSource.clear(); - - if (savedMyLocationFeature) { - vectorSource.addFeature(savedMyLocationFeature); - } - var found = false; + var targetFeature = null; + // 查找匹配的设备 for (var i = 0; i < allFeatures.length; i++) { var feature = allFeatures[i]; var deviceInfo = feature.get('deviceInfo'); if (deviceInfo && deviceInfo.deviceid.includes(deviceId)) { - vectorSource.addFeature(feature); found = true; - - // 将地图中心移动到该设备位置 - var geometry = feature.getGeometry(); - var deviceCoord = geometry.getCoordinates(); - map.getView().setCenter(deviceCoord); - map.getView().setZoom(15); + targetFeature = feature; + break; } } - if (!found) { + if (found && targetFeature) { + // 将地图中心移动到该设备位置 + var geometry = targetFeature.getGeometry(); + var deviceCoord = geometry.getCoordinates(); + map.getView().setCenter(deviceCoord); + map.getView().setZoom(15); + + // 高亮显示该设备(可以在这里添加高亮效果) + layer.msg('已定位到设备: ' + deviceId); + } else { layer.msg('未找到设备: ' + deviceId); - - if (marker_state === 1) { - showAll(); - } else if (marker_state === 2) { - showWarning1(); - } else if (marker_state === 3) { - showWarning2(); - } } - - // 注释掉原有按钮操作 - // document.getElementById('current-device-id').textContent = deviceId; - // document.getElementById('btn-device-locate').style.display = 'block'; - // document.getElementById('btn-device-locate').classList.add('active'); - // document.getElementById('btn-all').classList.remove('active'); - // document.getElementById('btn-warning1').classList.remove('active'); - // document.getElementById('btn-warning2').classList.remove('active'); - - // 更新新工具栏中的设备定位信息 - document.getElementById('current-device-id-new').textContent = deviceId; - document.getElementById('toolbar-device-locate').style.display = 'flex'; } layui.use(['form'], function(){ var form = layui.form; @@ -1405,6 +1499,8 @@ // }); initialize(); + // 默认显示所有设备 + document.getElementById('warningFilter').value = 'all'; showAll(); }); @@ -1437,7 +1533,6 @@ currentSearchedDevice = null; // document.getElementById('deviceSearch').value = ''; document.getElementById('deviceSearchNew').value = ''; - document.getElementById('toolbar-device-locate').style.display = 'none'; if (filterValue === 'all') { showAll(); @@ -1448,29 +1543,40 @@ } } - function onDisplayOptionsChange() { - var optionValue = document.getElementById('displayOptions').value; - - switch(optionValue) { - case 'both': - showDeviceId = true; - showCluster = true; - break; - case 'device': - showDeviceId = true; - showCluster = false; - break; - case 'cluster': - showDeviceId = false; - showCluster = true; - break; - case 'none': - showDeviceId = false; - showCluster = false; - break; + // 下拉菜单控制 + function toggleMapFunctionsMenu() { + document.getElementById('mapFunctionsMenu').classList.toggle('show'); + + // 点击其他地方关闭菜单 + document.addEventListener('click', closeMapFunctionsMenu); + } + + function closeMapFunctionsMenu(event) { + var dropdown = document.getElementById('mapFunctionsMenu'); + var toggleBtn = document.querySelector('.dropdown-toggle'); + + if (dropdown && !dropdown.contains(event.target) && !toggleBtn.contains(event.target)) { + dropdown.classList.remove('show'); + document.removeEventListener('click', closeMapFunctionsMenu); } - - // 更新图层可见性 + } + + // 设备信息显示开关 + function toggleDeviceId() { + showDeviceId = document.getElementById('showDeviceIdSwitch').checked; + updateLayerVisibility(); + layer.msg(showDeviceId ? '已显示设备信息' : '已隐藏设备信息'); + } + + // 集群显示开关 + function toggleCluster() { + showCluster = document.getElementById('showClusterSwitch').checked; + updateLayerVisibility(); + layer.msg(showCluster ? '已启用集群显示' : '已禁用集群显示'); + } + + // 更新图层可见性 + function updateLayerVisibility() { var zoom = map.getView().getZoom(); if (showCluster) { if (zoom >= maxZoomForClustering) { @@ -1484,7 +1590,7 @@ clusterLayer.setVisible(false); vectorLayer.setVisible(true); } - + // 强制更新样式 vectorLayer.changed(); } @@ -1495,20 +1601,24 @@ var measureTooltipElement; var measureTooltip; var measureTooltips = []; // 存储所有测距点的overlay + var measureFeatures = []; // 存储所有测距线段 + var currentMeasureTooltips = []; // 当前测距的临时tooltip function toggleMeasureDistance() { if (measureActive) { deactivateMeasure(); + layer.msg('测距功能已关闭'); } else { activateMeasure(); + layer.msg('测距功能已开启,单击地图添加测量点,双击结束当前测量'); } + // 关闭下拉菜单 + document.getElementById('mapFunctionsMenu').classList.remove('show'); } function activateMeasure() { - measureSource.clear(); - clearAllMeasureTooltips(); measureActive = true; - document.getElementById('measure-distance-btn').style.background = '#ed8936'; + // 创建测距交互 measureDraw = new ol.interaction.Draw({ source: measureSource, @@ -1529,61 +1639,105 @@ var sketch; var listener; + + // 开始绘制 measureDraw.on('drawstart', function(evt) { sketch = evt.feature; - var coords = sketch.getGeometry().getCoordinates(); - // 第一个点 - addMeasureTooltip(coords[0], '0 m'); + + // 清空当前测距的临时tooltip + currentMeasureTooltips = []; + + // 监听几何变化 listener = sketch.getGeometry().on('change', function(e) { var geom = e.target; var coords = geom.getCoordinates(); - clearAllMeasureTooltips(); + + // 清除当前临时tooltip + clearTemporaryTooltips(); + + // 计算总距离 var total = 0; for (var i = 0; i < coords.length; i++) { if (i === 0) { - addMeasureTooltip(coords[0], '0 m'); + // 起点 + var startTooltip = createMeasureTooltip(coords[0], '起点'); + currentMeasureTooltips.push(startTooltip); } else { + // 计算段距离 var seg = new ol.geom.LineString([coords[i-1], coords[i]]); total += ol.sphere.getLength(seg); - var output = (total > 100 ? (Math.round(total / 100) / 10) + ' km' : (Math.round(total * 10) / 10) + ' m'); - addMeasureTooltip(coords[i], output, i === coords.length-1); + var output = (total > 1000 ? + (Math.round(total / 100) / 10) + ' km' : + (Math.round(total * 10) / 10) + ' m'); + + // 如果是最后一个点,显示总距离 + if (i === coords.length - 1) { + var tooltip = createMeasureTooltip(coords[i], output); + currentMeasureTooltips.push(tooltip); + } } } }); }); + + // 结束绘制 measureDraw.on('drawend', function(evt) { - // 终点的tooltip样式特殊 - if (measureTooltips.length > 0) { - var last = measureTooltips[measureTooltips.length-1]; - last.getElement().className = 'ol-tooltip ol-tooltip-static'; + // 获取最终坐标 + var coords = evt.feature.getGeometry().getCoordinates(); + + // 清除临时tooltip + clearTemporaryTooltips(); + + // 计算总距离 + var total = 0; + for (var i = 1; i < coords.length; i++) { + var seg = new ol.geom.LineString([coords[i-1], coords[i]]); + total += ol.sphere.getLength(seg); } + + // 创建起点和终点的永久tooltip + var startTooltip = createMeasureTooltip(coords[0], '起点', true); + measureTooltips.push(startTooltip); + + var output = (total > 1000 ? + (Math.round(total / 100) / 10) + ' km' : + (Math.round(total * 10) / 10) + ' m'); + var endTooltip = createMeasureTooltip(coords[coords.length-1], output, true); + measureTooltips.push(endTooltip); + + // 保存测距线段 + measureFeatures.push(evt.feature); + ol.Observable.unByKey(listener); - measureDraw = null; - measureActive = false; - document.getElementById('measure-distance-btn').style.background = ''; + + // 重新激活测距工具,可以继续测量 + map.removeInteraction(measureDraw); + activateMeasure(); + + // 显示当前测距数量 + updateMeasureCount(); }); } function deactivateMeasure() { measureActive = false; - document.getElementById('measure-distance-btn').style.background = ''; + if (measureDraw) { map.removeInteraction(measureDraw); measureDraw = null; } - if (measureTooltipElement) { - measureTooltipElement.parentNode.removeChild(measureTooltipElement); - measureTooltipElement = null; - } - document.getElementById('measure-result').innerHTML = ''; - measureSource.clear(); - clearAllMeasureTooltips(); + + // 清除临时tooltip + clearTemporaryTooltips(); + + // 不清除已完成的测距结果和永久tooltip + // 用户可以通过clearMeasure函数清除所有测距 } - // 添加测距tooltip - function addMeasureTooltip(coord, text, isLast) { + // 创建测距tooltip + function createMeasureTooltip(coord, text, isStatic) { var elem = document.createElement('div'); - elem.className = isLast ? 'ol-tooltip ol-tooltip-static' : 'ol-tooltip ol-tooltip-measure'; + elem.className = isStatic ? 'ol-tooltip ol-tooltip-static' : 'ol-tooltip ol-tooltip-measure'; elem.innerHTML = text; var overlay = new ol.Overlay({ element: elem, @@ -1592,22 +1746,43 @@ }); overlay.setPosition(coord); map.addOverlay(overlay); - measureTooltips.push(overlay); + return overlay; } // 清除所有测距tooltip function clearAllMeasureTooltips() { + // 清除永久tooltip for (var i = 0; i < measureTooltips.length; i++) { map.removeOverlay(measureTooltips[i]); } measureTooltips = []; + + // 清除临时tooltip + clearTemporaryTooltips(); + } + + // 清除临时tooltip + function clearTemporaryTooltips() { + // 清除当前测量过程中的临时tooltip + for (var i = 0; i < currentMeasureTooltips.length; i++) { + map.removeOverlay(currentMeasureTooltips[i]); + } + currentMeasureTooltips = []; } + // 更新测距数量显示 (不再显示测距段数) + function updateMeasureCount() { + // 不再显示测距段数 + } + // 清除测距按钮 function clearMeasure() { measureSource.clear(); clearAllMeasureTooltips(); - document.getElementById('measure-result').innerHTML = ''; + measureFeatures = []; // 清空测距线段数组 + layer.msg('测距标记已清除'); + // 关闭下拉菜单 + document.getElementById('mapFunctionsMenu').classList.remove('show'); }