feature/ui #5

Merged
admin merged 6 commits from feature/ui into develop 2025-06-10 09:41:12 +00:00
2 changed files with 289 additions and 85 deletions
Showing only changes of commit 2b9ba6c1d2 - Show all commits

View File

@ -162,6 +162,7 @@
<li class="light btn" id="btn-all" onclick="showAll()">全部</li> <li class="light btn" id="btn-all" onclick="showAll()">全部</li>
<li class="night btn" id="btn-warning1" onclick="showWarning1()">一般告警</li> <li class="night btn" id="btn-warning1" onclick="showWarning1()">一般告警</li>
<li class="night btn active" id="btn-warning2" onclick="showWarning2()">严重告警</li> <li class="night btn active" id="btn-warning2" onclick="showWarning2()">严重告警</li>
<li class="night btn" id="btn-device-locate" style="display: none; min-width: 120px;"> 设备定位: <span id="current-device-id"></span> </li>
</ul> </ul>
<div id="map-container" class="layui-card-body"> <div id="map-container" class="layui-card-body">
<div class="map-control-card"> <div class="map-control-card">
@ -202,6 +203,8 @@
var marker_state = 3; // 1:all; 2:orange; 3:red var marker_state = 3; // 1:all; 2:orange; 3:red
var allFeatures = []; // 存储所有设备标记,用于搜索功能 var allFeatures = []; // 存储所有设备标记,用于搜索功能
var currentSearchedDevice = null; // 当前搜索的设备ID var currentSearchedDevice = null; // 当前搜索的设备ID
var myLocationFeature = null; // 存储"我的位置"标记
var myLocationInterval; // 存储定时更新位置的interval对象
// 天地图 API 密钥fengyarnom@gmail.com // 天地图 API 密钥fengyarnom@gmail.com
var TIANDITU_KEY = '0c260b8a094a4e0bc507808812cefdac'; var TIANDITU_KEY = '0c260b8a094a4e0bc507808812cefdac';
@ -353,16 +356,51 @@
addDeviceMarkers(); addDeviceMarkers();
myLocation(); myLocation();
startLocationUpdates(); // 启动位置定时更新
} }
function switchMapType(mapType) { function switchMapType(mapType) {
console.log('切换地图类型到:', mapType); console.log('切换地图类型到:', mapType);
map.removeLayer(currentBaseLayer); map.removeLayer(currentBaseLayer);
currentBaseLayer = mapLayers[mapType]; currentBaseLayer = mapLayers[mapType];
map.getLayers().insertAt(0, currentBaseLayer); map.getLayers().insertAt(0, currentBaseLayer);
// 更新我的位置标记,使用正确的坐标系
updateMyLocationForMapType(mapType);
// 更新设备标记
addDeviceMarkers(); 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() { function addDeviceMarkers() {
// 保存我的位置标记
var savedMyLocationFeature = myLocationFeature;
// 清除现有标记 // 清除现有标记
vectorSource.clear(); vectorSource.clear();
greenFeatures = []; greenFeatures = [];
@ -422,11 +460,13 @@
vectorSource.addFeature(feature); vectorSource.addFeature(feature);
} }
// 根据当前搜索状态显示或隐藏设备 if (savedMyLocationFeature) {
vectorSource.addFeature(savedMyLocationFeature);
}
if (currentSearchedDevice) { if (currentSearchedDevice) {
filterByDeviceId(currentSearchedDevice); filterByDeviceId(currentSearchedDevice);
} else { } else {
// 恢复当前过滤状态
if (marker_state === 2) { if (marker_state === 2) {
hideGreen(); hideGreen();
hideRed(); hideRed();
@ -442,10 +482,27 @@
navigator.geolocation.getCurrentPosition(function(position) { navigator.geolocation.getCurrentPosition(function(position) {
var lon = position.coords.longitude; var lon = position.coords.longitude;
var lat = position.coords.latitude; 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({ var style = new ol.style.Style({
@ -456,74 +513,99 @@
}) })
}); });
feature.setStyle(style); myLocationFeature.setStyle(style);
vectorSource.addFeature(feature); vectorSource.addFeature(myLocationFeature);
map.getView().setCenter(coordinates); map.getView().setCenter(coordinates);
}); });
} }
} }
function startLocationUpdates() {
if (myLocationInterval) {
clearInterval(myLocationInterval);
}
myLocationInterval = setInterval(function() {
myLocation();
}, 10 * 60 * 1000); // 10 min = 10 * 60 * 1000ms
}
function showAll() { function showAll() {
// 更新按钮样式
document.getElementById('btn-all').classList.add('active'); document.getElementById('btn-all').classList.add('active');
document.getElementById('btn-warning1').classList.remove('active'); document.getElementById('btn-warning1').classList.remove('active');
document.getElementById('btn-warning2').classList.remove('active'); document.getElementById('btn-warning2').classList.remove('active');
document.getElementById('btn-device-locate').classList.remove('active');
if (marker_state == 2) { document.getElementById('btn-device-locate').style.display = 'none';
showGreen();
showRed();
marker_state = 1;
} else if (marker_state == 3) {
showGreen();
showOrange();
marker_state = 1;
}
// 如果有搜索,清除搜索条件
currentSearchedDevice = null; currentSearchedDevice = null;
document.getElementById('deviceSearch').value = ''; 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() { function showWarning1() {
// 更新按钮样式
document.getElementById('btn-all').classList.remove('active'); document.getElementById('btn-all').classList.remove('active');
document.getElementById('btn-warning1').classList.add('active'); document.getElementById('btn-warning1').classList.add('active');
document.getElementById('btn-warning2').classList.remove('active'); document.getElementById('btn-warning2').classList.remove('active');
document.getElementById('btn-device-locate').classList.remove('active');
if (marker_state == 1) { document.getElementById('btn-device-locate').style.display = 'none';
hideGreen();
hideRed();
marker_state = 2;
} else if (marker_state == 3) {
hideRed();
showOrange();
marker_state = 2;
}
// 如果有搜索,清除搜索条件
currentSearchedDevice = null; currentSearchedDevice = null;
document.getElementById('deviceSearch').value = ''; 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() { function showWarning2() {
// 更新按钮样式
document.getElementById('btn-all').classList.remove('active'); document.getElementById('btn-all').classList.remove('active');
document.getElementById('btn-warning1').classList.remove('active'); document.getElementById('btn-warning1').classList.remove('active');
document.getElementById('btn-warning2').classList.add('active'); document.getElementById('btn-warning2').classList.add('active');
document.getElementById('btn-device-locate').classList.remove('active');
if (marker_state == 1) { document.getElementById('btn-device-locate').style.display = 'none';
hideGreen();
hideOrange();
marker_state = 3;
} else if (marker_state == 2) {
hideOrange();
showRed();
marker_state = 3;
}
// 如果有搜索,清除搜索条件
currentSearchedDevice = null; currentSearchedDevice = null;
document.getElementById('deviceSearch').value = ''; 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() { function showGreen() {
@ -567,21 +649,18 @@
vectorSource.removeFeature(redFeatures[i]); vectorSource.removeFeature(redFeatures[i]);
} }
} }
// 搜索设备函数
function searchDevice() { function searchDevice() {
var deviceId = document.getElementById('deviceSearch').value.trim(); var deviceId = document.getElementById('deviceSearch').value.trim();
if (!deviceId) { if (!deviceId) {
// 如果搜索框为空,则显示所有设备(根据当前过滤状态)
currentSearchedDevice = null; currentSearchedDevice = null;
vectorSource.clear(); vectorSource.clear();
for (var i = 0; i < allFeatures.length; i++) { for (var i = 0; i < allFeatures.length; i++) {
vectorSource.addFeature(allFeatures[i]); vectorSource.addFeature(allFeatures[i]);
} }
// 恢复过滤状态
if (marker_state === 2) { if (marker_state === 2) {
hideGreen(); hideGreen();
hideRed(); hideRed();
@ -589,6 +668,9 @@
hideGreen(); hideGreen();
hideOrange(); hideOrange();
} }
document.getElementById('btn-device-locate').style.display = 'none';
updateFilterButtonsState(marker_state);
return; return;
} }
@ -596,33 +678,76 @@
currentSearchedDevice = deviceId; currentSearchedDevice = deviceId;
filterByDeviceId(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) { function filterByDeviceId(deviceId) {
var savedMyLocationFeature = myLocationFeature;
vectorSource.clear(); vectorSource.clear();
if (savedMyLocationFeature) {
vectorSource.addFeature(savedMyLocationFeature);
}
var foundFeature = null; var found = false;
// 查找匹配的设备
for (var i = 0; i < allFeatures.length; i++) { for (var i = 0; i < allFeatures.length; i++) {
var feature = allFeatures[i]; var feature = allFeatures[i];
var featureDeviceId = feature.get('deviceInfo').deviceid; var deviceInfo = feature.get('deviceInfo');
// 部分匹配,包含搜索字符串即可 if (deviceInfo && deviceInfo.deviceid.includes(deviceId)) {
if (featureDeviceId.indexOf(deviceId) !== -1) {
vectorSource.addFeature(feature); vectorSource.addFeature(feature);
foundFeature = feature; found = true;
// 将地图中心移动到该设备位置
var geometry = feature.getGeometry();
var deviceCoord = geometry.getCoordinates();
map.getView().setCenter(deviceCoord);
map.getView().setZoom(15);
} }
} }
// 如果找到设备,则将地图中心设置到该设备位置 if (!found) {
if (foundFeature) { layer.msg('未找到设备: ' + deviceId);
var geometry = foundFeature.getGeometry();
var coordinate = geometry.getCoordinates();
map.getView().setCenter(coordinate); if (marker_state === 1) {
map.getView().setZoom(15); // 放大到适当级别 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(){ layui.use(['form'], function(){
var form = layui.form; var form = layui.form;
@ -632,7 +757,6 @@
initialize(); initialize();
// 初始化页面时,默认显示"严重告警"
showWarning2(); showWarning2();
}); });

View File

@ -12,6 +12,65 @@
body { body {
background-color: #ffffff; 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;
}
</style> </style>
</head> </head>
<body> <body>
@ -28,34 +87,49 @@
form = layui.form, form = layui.form,
table = layui.table; table = layui.table;
var iframeIndex = parent.layer.getFrameIndex(window.name); var iframeIndex = parent.layer.getFrameIndex(window.name);
/**
* 初始化表单,要加上,不然刷新部分组件可能会不加载
*/
form.render(); form.render();
table.render({ table.render({
elem: '#currentTableId', elem: '#currentTableId',
url: '/gnss/q_status/list', url: '/gnss/q_status/list',
cols: [[ cols: [[
{field: 'deviceid', title: '设备号', sort: true}, {field: 'deviceid', title: '设备号', width: 120, templet: '#deviceIdTpl', align: 'center',sort: true},
{field: 'devicetype', title: '设备类型',templet: '#typeTrans'}, {field: 'devicetype', title: '设备类型', templet: '#typeTrans', width: 100},
{field: 'project_id', title: '项目号'}, {field: 'project_id', title: '项目号', width: 100},
{field: 'name', title: '工点'}, {field: 'name', title: '工点', width: 150},
{field: 'updatetime', title: '更新时间', templet: "<div>{{layui.util.toDateString(d.updatetime, 'yyyy-MM-dd HH:mm:ss')}}</div>"}, {field: 'updatetime', title: '更新时间', templet: "<div>{{layui.util.toDateString(d.updatetime, 'yyyy-MM-dd HH:mm:ss')}}</div>", width: 170},
{field: 'state', title: '状态',templet: '#stateTrans'}, {field: 'state', title: '状态', templet: '#stateTrans', width: 80, align: 'center'},
{field: 'warning', title: '告警',templet: '#warningTrans'}, {field: 'warning', title: '告警', templet: '#warningTrans', width: 80, align: 'center'},
{field: 'voltage', title: '电压'}, {field: 'voltage', title: '电压', width: 80},
{field: 'temperature', title: '温度'}, {field: 'temperature', title: '温度', width: 80},
{field: 'humidity', title: '湿度'}, {field: 'humidity', title: '湿度', width: 80},
{field: 'rssi', title: '信号'}, {field: 'rssi', title: '信号', width: 80},
{field: 'pitch', title: 'x倾角'}, {field: 'pitch', title: 'x倾角', width: 80},
{field: 'roll', title: 'y倾角'}, {field: 'roll', title: 'y倾角', width: 80},
{field: 'satelliteinuse', title: '使用卫星数'} {field: 'satelliteinuse', title: '使用卫星数', width: 110},
{field: 'latitude', title: '纬度', hide: true},
{field: 'longitude', title: '经度', hide: true}
]], ]],
limits: [10, 15, 20, 25, 50, 100], limits: [10, 15, 20, 25, 50, 100],
limit: 15, limit: 15,
page: true, 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 @@
{{# } }} {{# } }}
</script> </script>
<script type="text/html" id="deviceIdTpl">
<div class="device-id-btn" lay-event="locate">
<i class="layui-icon layui-icon-location"></i>{{d.deviceid}}
</div>
</script>
</body> </body>
</html> </html>