From f8fe5bd1e1afaa17bb43a377ead5040989c00165 Mon Sep 17 00:00:00 2001 From: yarnom Date: Sun, 10 Aug 2025 01:13:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/index.html | 393 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 347 insertions(+), 46 deletions(-) diff --git a/templates/index.html b/templates/index.html index 4f06878..68256dd 100644 --- a/templates/index.html +++ b/templates/index.html @@ -29,8 +29,8 @@ .controls { display: flex; - flex-wrap: wrap; - gap: 10px; + flex-direction: column; + gap: 15px; margin-bottom: 20px; padding: 15px; border: 1px solid #ddd; @@ -38,16 +38,25 @@ background-color: #fff; } + .control-row { + display: flex; + align-items: center; + gap: 15px; + flex-wrap: wrap; + } + .control-group { display: flex; align-items: center; gap: 5px; + flex-shrink: 0; } .station-input-group { display: flex; align-items: center; gap: 5px; + flex-shrink: 0; } #stationInput { @@ -113,12 +122,13 @@ } .map-control-btn { - padding: 5px 10px; + padding: 3px 8px; background-color: rgba(255, 255, 255, 0.9); - border: 1px solid #ccc; - border-radius: 4px; + border: 1px solid #ddd; + border-radius: 3px; cursor: pointer; - font-size: 12px; + font-size: 11px; + color: #666; } .map-control-btn:hover { @@ -195,6 +205,119 @@ font-size: 14px; } + /* 设备列表样式 */ + .device-modal { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.3); + z-index: 2000; + } + + .device-modal-content { + position: fixed; + bottom: 0; + left: 0; + right: 0; + background-color: #fff; + height: 40vh; + width: 100%; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + box-shadow: 0 -2px 10px rgba(0,0,0,0.1); + display: flex; + flex-direction: column; + } + + .device-list-header { + padding: 15px 20px; + border-bottom: 1px solid #eee; + position: relative; + flex-shrink: 0; + } + + .device-list { + flex: 1; + overflow-y: auto; + padding: 8px 0; + position: relative; + } + + .device-list-footer { + padding: 10px; + border-top: 1px solid #eee; + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + } + + .pagination { + display: flex; + align-items: center; + gap: 10px; + font-size: 12px; + color: #666; + } + + .pagination-btn { + padding: 4px 8px; + border: 1px solid #ddd; + border-radius: 3px; + background: #fff; + cursor: pointer; + font-size: 12px; + color: #666; + } + + .pagination-btn:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + .device-item { + padding: 12px 20px; + border-bottom: 1px solid #f5f5f5; + display: flex; + justify-content: space-between; + align-items: center; + cursor: pointer; + } + + .device-item:hover { + background-color: #fafafa; + } + + .device-item:last-child { + border-bottom: none; + } + + .close-modal { + position: absolute; + right: 20px; + top: 50%; + transform: translateY(-50%); + width: 24px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + background-color: #f5f5f5; + cursor: pointer; + color: #666; + font-size: 18px; + line-height: 1; + } + + .close-modal:hover { + background-color: #eee; + color: #333; + } + .error { color: #dc3545; background-color: #f8d7da; @@ -269,50 +392,75 @@

{{.Title}}

+ +
+
+
+ 设备列表 + × +
+
+ +
+ +
+
+
- 在线设备: {{.OnlineDevices}} 个 + 在线设备: {{.OnlineDevices}} 个 | + 总设备: 0
-
- - +
+
+ + +
+ +
+ + +
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- + +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
@@ -448,8 +596,78 @@ // 添加输入框事件监听 const stationInput = document.getElementById('stationInput'); stationInput.addEventListener('input', function(e) { - // 移除非数字字符 - this.value = this.value.replace(/[^0-9]/g, ''); + // 允许输入数字和十六进制字符 + this.value = this.value.toUpperCase().replace(/[^0-9A-F]/g, ''); + }); + + // 设备列表模态框相关事件 + const modal = document.getElementById('deviceModal'); + const showDeviceListBtn = document.getElementById('showDeviceList'); + const closeBtn = document.querySelector('.close-modal'); + const prevPageBtn = document.getElementById('prevPage'); + const nextPageBtn = document.getElementById('nextPage'); + + // 点击显示设备列表 + showDeviceListBtn.addEventListener('click', function(e) { + e.preventDefault(); + modal.style.display = 'block'; + updateDeviceList(1); + }); + + // 分页按钮事件 + prevPageBtn.addEventListener('click', function() { + if (currentPage > 1) { + updateDeviceList(currentPage - 1); + } + }); + + nextPageBtn.addEventListener('click', function() { + const totalPages = Math.ceil(filteredDevices.length / itemsPerPage); + if (currentPage < totalPages) { + updateDeviceList(currentPage + 1); + } + }); + + // 处理ID输入 + stationInput.addEventListener('change', function() { + const value = this.value.trim(); + if (value) { + if (isHexString(value)) { + // 如果是十六进制,转换为十进制 + if (value.length <= 6) { + this.value = hexToDecimal(value); + } + } else { + // 如果是十进制,保持不变 + const num = parseInt(value); + if (!isNaN(num)) { + this.value = num.toString(); + } + } + } + }); + + // 点击关闭按钮 + closeBtn.addEventListener('click', function() { + modal.style.display = 'none'; + }); + + // 点击模态框外部关闭 + window.addEventListener('click', function(e) { + if (e.target === modal) { + modal.style.display = 'none'; + } + }); + + // 点击设备项自动填充并查询 + document.getElementById('deviceList').addEventListener('click', function(e) { + const deviceItem = e.target.closest('.device-item'); + if (deviceItem) { + const decimalId = deviceItem.getAttribute('data-decimal-id'); + document.getElementById('stationInput').value = decimalId; + modal.style.display = 'none'; + queryHistoryData(); + } }); }); @@ -663,12 +881,86 @@ const response = await fetch('/api/stations'); stations = await response.json(); + // 更新WH65LP设备数量 + const wh65lpDevices = stations.filter(station => station.device_type === 'WH65LP'); + document.getElementById('wh65lpCount').textContent = wh65lpDevices.length; + displayStationsOnMap(); } catch (error) { console.error('加载站点失败:', error); } } + // 分页相关变量 + let currentPage = 1; + const itemsPerPage = 10; + let filteredDevices = []; + + // 更新设备列表 + function updateDeviceList(page = 1) { + const deviceListContainer = document.getElementById('deviceList'); + deviceListContainer.innerHTML = ''; + + // 筛选WH65LP设备并按在线状态排序 + filteredDevices = stations + .filter(station => station.device_type === 'WH65LP') + .sort((a, b) => { + const aOnline = new Date(a.last_update) > new Date(Date.now() - 5*60*1000); + const bOnline = new Date(b.last_update) > new Date(Date.now() - 5*60*1000); + if (aOnline === bOnline) return 0; + return aOnline ? -1 : 1; + }); + + // 计算分页 + const totalPages = Math.ceil(filteredDevices.length / itemsPerPage); + currentPage = Math.min(Math.max(1, page), totalPages); + + // 更新分页按钮状态 + document.getElementById('currentPage').textContent = currentPage; + document.getElementById('totalPages').textContent = totalPages; + document.getElementById('prevPage').disabled = currentPage <= 1; + document.getElementById('nextPage').disabled = currentPage >= totalPages; + + // 获取当前页的设备 + const startIndex = (currentPage - 1) * itemsPerPage; + const endIndex = startIndex + itemsPerPage; + const currentDevices = filteredDevices.slice(startIndex, endIndex); + + currentDevices.forEach(device => { + const isOnline = new Date(device.last_update) > new Date(Date.now() - 5*60*1000); + const deviceItem = document.createElement('div'); + deviceItem.className = 'device-item'; + deviceItem.setAttribute('data-decimal-id', device.decimal_id); + + deviceItem.innerHTML = ` +
+ ${device.decimal_id} | ${device.name} | ${device.location || '未知位置'} +
+ ${isOnline ? '在线' : '离线'} + `; + + deviceListContainer.appendChild(deviceItem); + }); + + if (filteredDevices.length === 0) { + deviceListContainer.innerHTML = '
暂无WH65LP设备
'; + } + } + + // 十六进制和十进制转换函数 + function isHexString(str) { + return /^[0-9A-F]+$/i.test(str); + } + + function hexToDecimal(hex) { + return parseInt(hex, 16).toString(); + } + + function decimalToHex(decimal) { + const hex = parseInt(decimal).toString(16).toUpperCase(); + return '0'.repeat(Math.max(0, 6 - hex.length)) + hex; + } + // 更新集群距离 function updateClusterDistance(zoom) { // 动态调整聚合距离,让低缩放更容易聚合 @@ -893,8 +1185,17 @@ displayTable(data); // 显示图表和表格 - document.getElementById('chartContainer').classList.add('show'); - document.getElementById('tableContainer').classList.add('show'); + const chartContainer = document.getElementById('chartContainer'); + const tableContainer = document.getElementById('tableContainer'); + + chartContainer.classList.add('show'); + tableContainer.classList.add('show'); + + // 平滑滚动到图表位置 + chartContainer.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); } catch (error) { console.error('查询历史数据失败:', error);