feat: 优化页面

This commit is contained in:
yarnom 2025-07-04 11:46:02 +08:00
parent 1336bb16e6
commit 5f83223d9a

View File

@ -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);
}
</style>
<script src="../js/ol.js"></script>
@ -477,24 +606,38 @@
<div class="toolbar-divider"></div>
<div class="toolbar-item">
<select id="displayOptions" class="toolbar-select" onchange="onDisplayOptionsChange()">
<option value="both" selected>信息+集群</option>
<option value="device">仅设备信息</option>
<option value="cluster">仅集群显示</option>
<option value="none">隐藏标签</option>
</select>
</div>
<div class="toolbar-item" id="toolbar-device-locate" style="display: none;">
<span id="current-device-id-new" style="background: rgba(26, 160, 148, 0.1); padding: 4px 8px; border-radius: 4px; font-size: 12px; color: #1aa094; font-weight: bold;"></span>
<button class="toolbar-btn" onclick="clearDeviceSearch()" style="padding: 2px 6px; font-size: 11px;">清除</button>
</div>
<div class="toolbar-divider"></div>
<div class="toolbar-item">
<button class="toolbar-btn" id="measure-distance-btn" onclick="toggleMeasureDistance()">测距</button>
<button class="toolbar-btn" id="clear-measure-btn" onclick="clearMeasure()" style="margin-left:4px;">清除测距</button>
<span id="measure-result" style="margin-left:8px;color:#1aa094;font-size:12px;"></span>
<div class="dropdown-container">
<button class="toolbar-btn dropdown-toggle" onclick="toggleMapFunctionsMenu()">地图功能</button>
<div id="mapFunctionsMenu" class="dropdown-menu">
<div class="dropdown-group">
<div class="dropdown-group-title">信息显示</div>
<div class="dropdown-item">
<label class="switch-label">
<span>显示设备信息</span>
<input type="checkbox" id="showDeviceIdSwitch" checked onchange="toggleDeviceId()">
<span class="switch-slider"></span>
</label>
</div>
<div class="dropdown-item">
<label class="switch-label">
<span>显示集群</span>
<input type="checkbox" id="showClusterSwitch" checked onchange="toggleCluster()">
<span class="switch-slider"></span>
</label>
</div>
</div>
<div class="dropdown-divider"></div>
<div class="dropdown-group">
<div class="dropdown-group-title">测量工具</div>
<div class="dropdown-item" onclick="toggleMeasureDistance()">
<i class="fa fa-ruler"></i> 测距
</div>
<div class="dropdown-item" onclick="clearMeasure()">
<i class="fa fa-eraser"></i> 清除测距
</div>
</div>
</div>
</div>
</div>
</div>
@ -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');
}
</script>