From 2b9ba6c1d2b21d46f8b83f258af6f34dda5ef6a3 Mon Sep 17 00:00:00 2001 From: fengyarnom Date: Tue, 10 Jun 2025 11:50:46 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E5=AE=9A=E4=BD=8D=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E5=88=B0=E5=9C=B0=E5=9B=BE=20-=20=E5=AE=9A=E4=BD=8D?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=88=B0=E5=9C=B0=E5=9B=BE=20-=20=E5=AE=9A?= =?UTF-8?q?=E6=97=B6=E6=9B=B4=E6=96=B0=E6=88=91=E7=9A=84=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/page/device_overview.html | 258 +++++++++++++----- .../page/table/gnss_status_list.html | 116 ++++++-- 2 files changed, 289 insertions(+), 85 deletions(-) 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 bbbfaac7..e509d545 100644 --- a/sec-beidou/src/main/resources/templates/page/device_overview.html +++ b/sec-beidou/src/main/resources/templates/page/device_overview.html @@ -162,6 +162,7 @@
  • 全部
  • 一般告警
  • 严重告警
  • +
    @@ -202,6 +203,8 @@ var marker_state = 3; // 1:all; 2:orange; 3:red var allFeatures = []; // 存储所有设备标记,用于搜索功能 var currentSearchedDevice = null; // 当前搜索的设备ID + var myLocationFeature = null; // 存储"我的位置"标记 + var myLocationInterval; // 存储定时更新位置的interval对象 // 天地图 API 密钥(fengyarnom@gmail.com) var TIANDITU_KEY = '0c260b8a094a4e0bc507808812cefdac'; @@ -353,16 +356,51 @@ addDeviceMarkers(); myLocation(); + startLocationUpdates(); // 启动位置定时更新 } function switchMapType(mapType) { console.log('切换地图类型到:', mapType); map.removeLayer(currentBaseLayer); currentBaseLayer = mapLayers[mapType]; map.getLayers().insertAt(0, currentBaseLayer); + + // 更新我的位置标记,使用正确的坐标系 + updateMyLocationForMapType(mapType); + + // 更新设备标记 addDeviceMarkers(); } + + // 根据地图类型更新我的位置标记 + function updateMyLocationForMapType(mapType) { + if (myLocationFeature) { + // 获取原始坐标 + var originalCoords = myLocationFeature.get('originalCoords'); + if (originalCoords) { + var lat = originalCoords.lat; + var lon = originalCoords.lon; + var coordinates; + + // 根据地图类型进行坐标转换 + if (mapType === 'amap' || mapType === 'amap_satellite') { + // 高德地图使用GCJ-02坐标系,需要转换 + var gcjCoord = transform(lat, lon); + coordinates = ol.proj.fromLonLat([gcjCoord.lon, gcjCoord.lat]); + } else { + // 天地图使用CGCS2000/WGS84坐标系,直接使用 + coordinates = ol.proj.fromLonLat([lon, lat]); + } + + // 更新位置标记的几何坐标 + myLocationFeature.getGeometry().setCoordinates(coordinates); + } + } + } function addDeviceMarkers() { + // 保存我的位置标记 + var savedMyLocationFeature = myLocationFeature; + // 清除现有标记 vectorSource.clear(); greenFeatures = []; @@ -422,11 +460,13 @@ vectorSource.addFeature(feature); } - // 根据当前搜索状态显示或隐藏设备 + if (savedMyLocationFeature) { + vectorSource.addFeature(savedMyLocationFeature); + } + if (currentSearchedDevice) { filterByDeviceId(currentSearchedDevice); } else { - // 恢复当前过滤状态 if (marker_state === 2) { hideGreen(); hideRed(); @@ -442,10 +482,27 @@ navigator.geolocation.getCurrentPosition(function(position) { var lon = position.coords.longitude; var lat = position.coords.latitude; - var coordinates = ol.proj.fromLonLat([lon, lat]); + var currentMapType = document.getElementById('mapTypeSelect').value; + var coordinates; + + if (currentMapType === 'amap' || currentMapType === 'amap_satellite') { + // 高德地图使用GCJ-02坐标系,需要转换 + var gcjCoord = transform(lat, lon); + coordinates = ol.proj.fromLonLat([gcjCoord.lon, gcjCoord.lat]); + } else { + // 天地图使用CGCS2000/WGS84坐标系,直接使用 + coordinates = ol.proj.fromLonLat([lon, lat]); + } - var feature = new ol.Feature({ - geometry: new ol.geom.Point(coordinates) + // 如果已经存在位置标记,则先移除 + if (myLocationFeature) { + vectorSource.removeFeature(myLocationFeature); + } + + myLocationFeature = new ol.Feature({ + geometry: new ol.geom.Point(coordinates), + isMyLocation: true, + originalCoords: {lat: lat, lon: lon} }); var style = new ol.style.Style({ @@ -456,74 +513,99 @@ }) }); - feature.setStyle(style); - vectorSource.addFeature(feature); + myLocationFeature.setStyle(style); + vectorSource.addFeature(myLocationFeature); map.getView().setCenter(coordinates); }); } } + function startLocationUpdates() { + if (myLocationInterval) { + clearInterval(myLocationInterval); + } + + myLocationInterval = setInterval(function() { + myLocation(); + }, 10 * 60 * 1000); // 10 min = 10 * 60 * 1000ms + } + function showAll() { - // 更新按钮样式 document.getElementById('btn-all').classList.add('active'); document.getElementById('btn-warning1').classList.remove('active'); document.getElementById('btn-warning2').classList.remove('active'); - - if (marker_state == 2) { - showGreen(); - showRed(); - marker_state = 1; - } else if (marker_state == 3) { - showGreen(); - showOrange(); - marker_state = 1; - } - - // 如果有搜索,清除搜索条件 + document.getElementById('btn-device-locate').classList.remove('active'); + document.getElementById('btn-device-locate').style.display = 'none'; + currentSearchedDevice = null; document.getElementById('deviceSearch').value = ''; + var savedMyLocationFeature = myLocationFeature; + + vectorSource.clear(); + + if (savedMyLocationFeature) { + vectorSource.addFeature(savedMyLocationFeature); + } + + for (var i = 0; i < allFeatures.length; i++) { + vectorSource.addFeature(allFeatures[i]); + } + + marker_state = 1; } function showWarning1() { - // 更新按钮样式 document.getElementById('btn-all').classList.remove('active'); document.getElementById('btn-warning1').classList.add('active'); document.getElementById('btn-warning2').classList.remove('active'); - - if (marker_state == 1) { - hideGreen(); - hideRed(); - marker_state = 2; - } else if (marker_state == 3) { - hideRed(); - showOrange(); - marker_state = 2; - } - - // 如果有搜索,清除搜索条件 + document.getElementById('btn-device-locate').classList.remove('active'); + document.getElementById('btn-device-locate').style.display = 'none'; + currentSearchedDevice = null; document.getElementById('deviceSearch').value = ''; + + var savedMyLocationFeature = myLocationFeature; + + vectorSource.clear(); + + if (savedMyLocationFeature) { + vectorSource.addFeature(savedMyLocationFeature); + } + + for (var i = 0; i < allFeatures.length; i++) { + vectorSource.addFeature(allFeatures[i]); + } + + hideGreen(); + hideRed(); + marker_state = 2; } function showWarning2() { - // 更新按钮样式 document.getElementById('btn-all').classList.remove('active'); document.getElementById('btn-warning1').classList.remove('active'); document.getElementById('btn-warning2').classList.add('active'); - - if (marker_state == 1) { - hideGreen(); - hideOrange(); - marker_state = 3; - } else if (marker_state == 2) { - hideOrange(); - showRed(); - marker_state = 3; - } - - // 如果有搜索,清除搜索条件 + document.getElementById('btn-device-locate').classList.remove('active'); + document.getElementById('btn-device-locate').style.display = 'none'; + currentSearchedDevice = null; document.getElementById('deviceSearch').value = ''; + + var savedMyLocationFeature = myLocationFeature; + + vectorSource.clear(); + + if (savedMyLocationFeature) { + vectorSource.addFeature(savedMyLocationFeature); + } + + for (var i = 0; i < allFeatures.length; i++) { + vectorSource.addFeature(allFeatures[i]); + } + + hideGreen(); + hideOrange(); + marker_state = 3; } function showGreen() { @@ -567,21 +649,18 @@ vectorSource.removeFeature(redFeatures[i]); } } - - // 搜索设备函数 + function searchDevice() { var deviceId = document.getElementById('deviceSearch').value.trim(); if (!deviceId) { - // 如果搜索框为空,则显示所有设备(根据当前过滤状态) currentSearchedDevice = null; vectorSource.clear(); for (var i = 0; i < allFeatures.length; i++) { vectorSource.addFeature(allFeatures[i]); } - - // 恢复过滤状态 + if (marker_state === 2) { hideGreen(); hideRed(); @@ -589,6 +668,9 @@ hideGreen(); hideOrange(); } + + document.getElementById('btn-device-locate').style.display = 'none'; + updateFilterButtonsState(marker_state); return; } @@ -596,33 +678,76 @@ currentSearchedDevice = deviceId; filterByDeviceId(deviceId); } - - // 根据设备ID过滤显示 + + function locateDeviceOnMap(deviceId, latitude, longitude) { + currentSearchedDevice = deviceId; + filterByDeviceId(deviceId); + + var layerIndex = layer.index; + layer.close(layerIndex); + + layer.msg('已定位到设备: ' + deviceId); + } + + function updateFilterButtonsState(state) { + document.getElementById('btn-all').classList.remove('active'); + document.getElementById('btn-warning1').classList.remove('active'); + document.getElementById('btn-warning2').classList.remove('active'); + + if (state === 1) { + document.getElementById('btn-all').classList.add('active'); + } else if (state === 2) { + document.getElementById('btn-warning1').classList.add('active'); + } else if (state === 3) { + document.getElementById('btn-warning2').classList.add('active'); + } + } + function filterByDeviceId(deviceId) { + var savedMyLocationFeature = myLocationFeature; + vectorSource.clear(); + + if (savedMyLocationFeature) { + vectorSource.addFeature(savedMyLocationFeature); + } - var foundFeature = null; - - // 查找匹配的设备 + var found = false; + for (var i = 0; i < allFeatures.length; i++) { var feature = allFeatures[i]; - var featureDeviceId = feature.get('deviceInfo').deviceid; + var deviceInfo = feature.get('deviceInfo'); - // 部分匹配,包含搜索字符串即可 - if (featureDeviceId.indexOf(deviceId) !== -1) { + if (deviceInfo && deviceInfo.deviceid.includes(deviceId)) { vectorSource.addFeature(feature); - foundFeature = feature; + found = true; + + // 将地图中心移动到该设备位置 + var geometry = feature.getGeometry(); + var deviceCoord = geometry.getCoordinates(); + map.getView().setCenter(deviceCoord); + map.getView().setZoom(15); } } - // 如果找到设备,则将地图中心设置到该设备位置 - if (foundFeature) { - var geometry = foundFeature.getGeometry(); - var coordinate = geometry.getCoordinates(); + if (!found) { + layer.msg('未找到设备: ' + deviceId); - map.getView().setCenter(coordinate); - map.getView().setZoom(15); // 放大到适当级别 + 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'); } layui.use(['form'], function(){ var form = layui.form; @@ -632,7 +757,6 @@ initialize(); - // 初始化页面时,默认显示"严重告警" showWarning2(); }); diff --git a/sec-beidou/src/main/resources/templates/page/table/gnss_status_list.html b/sec-beidou/src/main/resources/templates/page/table/gnss_status_list.html index 81ea3658..4c3297bf 100644 --- a/sec-beidou/src/main/resources/templates/page/table/gnss_status_list.html +++ b/sec-beidou/src/main/resources/templates/page/table/gnss_status_list.html @@ -12,6 +12,65 @@ body { background-color: #ffffff; } + .layui-btn-normal { + background-color: #1aa094; + } + .icon-btn { + /* width: 30px; */ + height: 26px; + padding: 0; + } + .layui-table-fixed-l .layui-table-body { + box-shadow: none !important; + } + .layui-btn-normal:hover { + background-color: #148e83; + } + .layui-table-fixed-l .layui-table-body { + box-shadow: none !important; + } + .layui-table-cell { + height: auto; + line-height: 28px; + padding: 6px 15px; + position: relative; + box-sizing: border-box; + } + .layui-btn-xs { + padding: 0 8px; + font-size: 12px; + height: 26px; + line-height: 24px; + } + .device-id-btn { + display: flex; + align-items: center; + justify-content: center; + background-color: #4b97d5f5; + color: white; + border-radius: 5px; + padding: 3px 10px; + cursor: pointer; + transition: background-color 0.3s; + width: 100%; + } + .device-id-btn:hover { + background-color: #339af0; + } + .device-id-btn i { + margin-right: 5px; + } + .icon-only-btn { + background: none; + border: none; + padding: 0; + cursor: pointer; + font-size: 16px; + color: #1aa094; + } + .icon-only-btn:hover { + color: #148e83; + } @@ -28,34 +87,49 @@ form = layui.form, table = layui.table; var iframeIndex = parent.layer.getFrameIndex(window.name); - /** - * 初始化表单,要加上,不然刷新部分组件可能会不加载 - */ form.render(); table.render({ elem: '#currentTableId', url: '/gnss/q_status/list', cols: [[ - {field: 'deviceid', title: '设备号', sort: true}, - {field: 'devicetype', title: '设备类型',templet: '#typeTrans'}, - {field: 'project_id', title: '项目号'}, - {field: 'name', title: '工点'}, - {field: 'updatetime', title: '更新时间', templet: "
    {{layui.util.toDateString(d.updatetime, 'yyyy-MM-dd HH:mm:ss')}}
    "}, - {field: 'state', title: '状态',templet: '#stateTrans'}, - {field: 'warning', title: '告警',templet: '#warningTrans'}, - {field: 'voltage', title: '电压'}, - {field: 'temperature', title: '温度'}, - {field: 'humidity', title: '湿度'}, - {field: 'rssi', title: '信号'}, - {field: 'pitch', title: 'x倾角'}, - {field: 'roll', title: 'y倾角'}, - {field: 'satelliteinuse', title: '使用卫星数'} + {field: 'deviceid', title: '设备号', width: 120, templet: '#deviceIdTpl', align: 'center',sort: true}, + {field: 'devicetype', title: '设备类型', templet: '#typeTrans', width: 100}, + {field: 'project_id', title: '项目号', width: 100}, + {field: 'name', title: '工点', width: 150}, + {field: 'updatetime', title: '更新时间', templet: "
    {{layui.util.toDateString(d.updatetime, 'yyyy-MM-dd HH:mm:ss')}}
    ", width: 170}, + {field: 'state', title: '状态', templet: '#stateTrans', width: 80, align: 'center'}, + {field: 'warning', title: '告警', templet: '#warningTrans', width: 80, align: 'center'}, + {field: 'voltage', title: '电压', width: 80}, + {field: 'temperature', title: '温度', width: 80}, + {field: 'humidity', title: '湿度', width: 80}, + {field: 'rssi', title: '信号', width: 80}, + {field: 'pitch', title: 'x倾角', width: 80}, + {field: 'roll', title: 'y倾角', width: 80}, + {field: 'satelliteinuse', title: '使用卫星数', width: 110}, + {field: 'latitude', title: '纬度', hide: true}, + {field: 'longitude', title: '经度', hide: true} ]], limits: [10, 15, 20, 25, 50, 100], limit: 15, page: true, - skin: 'line' + skin: 'line', + even: true, + loading: true, + text: { + none: '暂无符合条件的设备' + } + }); + + table.on('tool(currentTableFilter)', function(obj) { + var data = obj.data; + if (obj.event === 'locate') { + if (data.latitude && data.longitude) { + parent.locateDeviceOnMap(data.deviceid, data.latitude, data.longitude); + } else { + layer.msg('设备无经纬度信息,无法定位'); + } + } }); }); @@ -92,5 +166,11 @@ {{# } }} + + \ No newline at end of file