2025-08-09 | 826220679@qq.com | ![]() |
2025-08-09 | 826220679@qq.com | ![]() |
src/chushihua/Chushihua.java
@@ -1,11 +1,11 @@ package chushihua; import java.sql.SQLException; import dell_Fence.Dell_Fence; import dell_anchor.Dell_BaseStation; import dell_map.Dell_Map; import dell_suanfa.Dell_GroupManagement; import dell_suanfa.Dell_LayerManagement; import dell_system.Dell_company; import dell_targets.Dell_BaseStation; import dell_targets.Dell_SystemConfiguration; import dell_targets.Dell_tag; import udptcp.UDPPortAReceiver; @@ -13,6 +13,7 @@ public class Chushihua { public static void getchushihua() { try { Dell_SystemConfiguration.getSystemConfigurations(); Dell_tag.getlocationTags(); Dell_BaseStation.getBaseStations(); UDPPortAReceiver.startReceiver(); @@ -20,8 +21,7 @@ Dell_Fence.getAllFences(); Dell_company.getAllCompanies(); Dell_LayerManagement.getAllLayers(); Dell_GroupManagement.getAllGroups(); Dell_SystemConfiguration.getSystemConfigurations(); Dell_GroupManagement.getAllGroups(); if(Dell_SystemConfiguration.gnsstoxyOpen) {Dell_Map.get_foor_xycs();} } catch (SQLException e) { // TODO èªå¨çæç catch å src/dell55AAData/Dell55AA02Parser.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,66 @@ package dell55AAData; import dell_targets.Dell_BaseStation; public class Dell55AA02Parser { private static final String EXPECTED_HEADER = "55AA02"; private static final int MIN_LENGTH = 36; // 18åè * 2å符/åè private static final int BASE_ID_START = 8; // åºç«IDèµ·å§ä½ç½®(第4åè) private static final int SYNC_STATUS_START = 12; // åæ¥ç¶æèµ·å§ä½ç½®(第5åè) private static final int PRESSURE_START = 14; // æ°åå¼èµ·å§ä½ç½®(第6åè) /** * è§£æ55AA02æ ¼å¼çåºç«æ°æ® * @param message æ¥æ¶å°çæ°æ®ï¼åå è¿å¶åç¬¦ä¸²ï¼ */ public static void parseAndUpdate(String message) { // 1. åºç¡æ ¡éª if (message == null || message.length() < MIN_LENGTH) { return; } // 2. 头鍿 ¡éªï¼åºå®å¼å¤´åç¬¦ä¸²ï¼ for (int i = 0; i < EXPECTED_HEADER.length(); i++) { if (message.charAt(i) != EXPECTED_HEADER.charAt(i)) { return; } } // 3. è§£æåºç«IDï¼åå§æ°æ®åç¬¦ä¸²ï¼ String baseId = new String(new char[]{ message.charAt(BASE_ID_START), message.charAt(BASE_ID_START + 1), message.charAt(BASE_ID_START + 2), message.charAt(BASE_ID_START + 3) }); // 4. è§£æåæ¥ç¶æï¼1åèï¼ char syncChar = message.charAt(SYNC_STATUS_START + 1); // åç¶æå符 String syncStatus = (syncChar == '0') ? "0" : "1"; // 5. è§£ææ°åå¼ï¼4åèå°ç«¯åºï¼ int pressure = 0; for (int i = 0; i < 8; i += 2) { int idx = PRESSURE_START + i; // 使ç¨HexUtilsçå¿«éè½¬æ¢æ¹æ³ int byteValue = HexUtils.fastHexToByte(message.charAt(idx), message.charAt(idx + 1)); pressure |= (byteValue << (i * 4)); // å°ç«¯åå¹¶ } String pressureStr = String.valueOf(pressure); // 6. æ´æ°åºç«æ°æ® updateBaseStationData(baseId, syncStatus ,pressureStr); } /** * æ´æ°åºç«æ°æ® * @param baseId åºç«ID * @param syncStatus åæ¥ç¶æ * @param pressure æ°åå¼å符串 */ private static void updateBaseStationData(String baseId, String syncStatus, String pressure) { Dell_BaseStation.updateBaseStationProperty(baseId, "syncStatus", syncStatus); Dell_BaseStation.updateBaseStationProperty(baseId, "barometerReading", pressure); } } src/dell_anchor/BaseStationAdjacentConfigPanel.java
@@ -1,6 +1,7 @@ package dell_anchor; import databases.DBConnector; import dell_targets.Dell_BaseStation; import targets.LocationBaseStation; import javax.swing.*; src/dell_anchor/BaseStationManagementPanel.java
@@ -1,6 +1,8 @@ package dell_anchor; import databases.DBConnector; import dell_targets.Dell_BaseStation; import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.table.*; src/dell_anchor/BaseStationSyncConfigPanel.java
@@ -1,5 +1,7 @@ package dell_anchor; import databases.DBConnector; import dell_targets.Dell_BaseStation; import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.table.*; src/dell_anchor/Dell_BaseStation.java
ÎļþÒÑɾ³ý src/dell_system/MessageViewPanel.java
@@ -7,13 +7,11 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.ResourceBundle; import java.util.Set; import dell_targets.Dell_MessageType; import dell_targets.Dell_tag; import publicsWay.Languages; import udptcp.UDPPortAReceiver; import udptcp.UDPPortBReceiver; @@ -28,7 +26,7 @@ // UIç»ä»¶å£°æ private JButton btnStart, btnPause, btnClear, btnSend; // æ§å¶æé®ï¼å¼å§ãæåãæ¸ é¤ãåé private static JComboBox<String> cbDataType; // 䏿æ¡ï¼æ°æ®ç±»åãåè®®ã设å¤ID private JComboBox<String> cbProtocol; private static JComboBox<String> cbProtocol; private static JComboBox<String> cbDeviceId; private static JComboBox<String> cbRemoteDevice; // è¿ç¨è®¾å¤ä¸ææ¡ private static JCheckBox chkAutoSave; // å¤éæ¡ï¼èªå¨ä¿åãæ¾ç¤ºæ¥æºãåå è¿å¶æ¾ç¤ºãASCIIæ¾ç¤º @@ -46,15 +44,16 @@ // ç¶æåé private static boolean isCapturing = false; // æ¯å¦æ£å¨æè·æ°æ®çæ å¿ // å卿æè¿ç¨è®¾å¤(IP:端å£) private static Set<String> remoteDevices = new HashSet<>(); // ä¿®æ¹ä¸ºMapåå¨è®¾å¤åå ¶æ¬å°ç«¯å£ // ä¿®æ¹ä¸ºMapåå¨è®¾å¤åå ¶æ¬å°ç«¯å£ private static Map<String, Integer> remoteDeviceLocalPortMap = new HashMap<>(); // æé 彿° public MessageViewPanel(ResourceBundle messages) { this.messages = messages; // åå§åæ¶æ¯èµæºå initializeUI(); // åå§åç¨æ·çé¢ } public void addNotify() { super.addNotify(); @@ -66,7 +65,7 @@ public void windowClosing(WindowEvent e) { isWindowVisible = false; } @Override public void windowClosed(WindowEvent e) { isWindowVisible = false; @@ -199,22 +198,22 @@ // å建åéé项颿¿ JPanel sendOptionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0)); sendOptionsPanel.setBackground(new Color(240, 245, 249)); // å建åéæé®ç» ButtonGroup sendFormatGroup = new ButtonGroup(); // å建HEXåéåéæé® rdoSendHex = createStyledRadioButton(messages.getString("MESSAGE_VIEW_SEND_HEX")); // å建ASCIIåéåéæé® rdoSendAscii = createStyledRadioButton(messages.getString("MESSAGE_VIEW_SEND_ASCII")); // å°åéæé®æ·»å å°æé®ç» sendFormatGroup.add(rdoSendHex); sendFormatGroup.add(rdoSendAscii); // é»è®¤éä¸ASCIIåé rdoSendAscii.setSelected(true); // å车æ¢è¡å¤éæ¡ chkAppendNewline = createStyledCheckbox(messages.getString("MESSAGE_VIEW_APPEND_NEWLINE")); @@ -266,18 +265,18 @@ checkBox.setForeground(new Color(70, 70, 70)); // è®¾ç½®åæ¯è² return checkBox; } // åå»ºå¸¦æ ·å¼çåéæé® private JRadioButton createStyledRadioButton(String text) { JRadioButton radioButton = new JRadioButton(text); // å建åéæé® radioButton.setFont(new Font("微软é é»", Font.PLAIN, 12)); // 设置åä½ radioButton.setBackground(new Color(240, 245, 249)); // è®¾ç½®èæ¯è² radioButton.setForeground(new Color(70, 70, 70)); // è®¾ç½®åæ¯è² // ç¾åé䏿æ radioButton.setIcon(new RadioButtonIcon(false)); radioButton.setSelectedIcon(new RadioButtonIcon(true)); // æ·»å é¼ æ æ¬åææ radioButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseEntered(java.awt.event.MouseEvent evt) { @@ -287,7 +286,7 @@ radioButton.setForeground(new Color(70, 70, 70)); } }); return radioButton; } @@ -295,21 +294,21 @@ private static class RadioButtonIcon implements Icon { private static final int SIZE = 14; private final boolean selected; public RadioButtonIcon(boolean selected) { this.selected = selected; } @Override public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2d = (Graphics2D) g.create(); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (selected) { // éä¸ç¶æ - èè²å¡«å g2d.setColor(new Color(70, 130, 180)); g2d.fillOval(x, y, SIZE, SIZE); // å å - ç½è² g2d.setColor(Color.WHITE); g2d.fillOval(x + SIZE/4, y + SIZE/4, SIZE/2, SIZE/2); @@ -318,39 +317,31 @@ g2d.setColor(new Color(150, 150, 150)); g2d.drawOval(x, y, SIZE-1, SIZE-1); } g2d.dispose(); } @Override public int getIconWidth() { return SIZE; } @Override public int getIconHeight() { return SIZE; } } // å 载设å¤IDå表 private void loadDeviceIds() { // ä»Dell_tagç±»è·åææè®¾å¤ID List<String> tags = Dell_tag.getAlldeviceIds(); // éå设å¤IDå表并添å å°ä¸ææ¡ for (String tag : tags) { cbDeviceId.addItem(tag); } } // å è½½æ°æ®ç±»å private void loadtyps() { // ä»Dell_tagç±»è·åææè®¾å¤ID List<String> typs = Dell_MessageType.getAllMessageTypes(); // éå设å¤IDå表并添å å°ä¸ææ¡ for (String typ : typs) { cbDataType.addItem(typ); } cbDataType.removeAllItems(); // æ·»å å½é åé项 cbDataType.addItem(messages.getString("MESSAGE_VIEW_ALL_TYPES")); cbDataType.addItem(messages.getString("MESSAGE_VIEW_UDP_PORT_A")); cbDataType.addItem(messages.getString("MESSAGE_VIEW_UDP_PORT_B")); cbDataType.addItem(messages.getString("MESSAGE_VIEW_TCP_PORT")); cbDataType.addItem(messages.getString("MESSAGE_VIEW_MQTT_PORT")); } // 设置æé®å¨ä½ @@ -385,21 +376,23 @@ // åéæ°æ®å°è¿ç¨è®¾å¤ private void sendData() { // ä½¿ç¨æ°æ¹æ³è·åå½åèµæºå ResourceBundle currentMessages = Languages.getCurrentMessages(); String selectedDevice = (String) cbRemoteDevice.getSelectedItem(); if (selectedDevice == null || selectedDevice.equals(messages.getString("MESSAGE_VIEW_ALL_DEVICES"))) { if (selectedDevice == null || selectedDevice.equals(currentMessages.getString("MESSAGE_VIEW_ALL_DEVICES"))) { JOptionPane.showMessageDialog(this, messages.getString("MESSAGE_VIEW_SELECT_DEVICE"), messages.getString("WARNING"), currentMessages.getString("MESSAGE_VIEW_SELECT_DEVICE"), currentMessages.getString("WARNING"), JOptionPane.WARNING_MESSAGE); return; } // è·åæ¬å°ç«¯å£ Integer localPort = remoteDeviceLocalPortMap.get(selectedDevice); if (localPort == null) { JOptionPane.showMessageDialog(this, "æ æ³ç¡®å®è®¾å¤çæ¥æ¶ç«¯å£", messages.getString("ERROR"), currentMessages.getString("ERROR"), JOptionPane.ERROR_MESSAGE); return; } @@ -408,8 +401,8 @@ String[] parts = selectedDevice.split(":"); if (parts.length != 2) { JOptionPane.showMessageDialog(this, messages.getString("MESSAGE_VIEW_INVALID_DEVICE"), messages.getString("ERROR"), currentMessages.getString("MESSAGE_VIEW_INVALID_DEVICE"), currentMessages.getString("ERROR"), JOptionPane.ERROR_MESSAGE); return; } @@ -420,8 +413,8 @@ port = Integer.parseInt(parts[1]); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(this, messages.getString("MESSAGE_VIEW_INVALID_PORT"), messages.getString("ERROR"), currentMessages.getString("MESSAGE_VIEW_INVALID_PORT"), currentMessages.getString("ERROR"), JOptionPane.ERROR_MESSAGE); return; } @@ -429,8 +422,8 @@ String dataToSend = txtSendData.getText(); if (dataToSend.isEmpty()) { JOptionPane.showMessageDialog(this, messages.getString("MESSAGE_VIEW_EMPTY_DATA"), messages.getString("WARNING"), currentMessages.getString("MESSAGE_VIEW_EMPTY_DATA"), currentMessages.getString("WARNING"), JOptionPane.WARNING_MESSAGE); return; } @@ -458,7 +451,7 @@ // ä¼ å ¥æ¯å¦HEXåéçæ å¿ UDPPortBReceiver.sendData(ip, port, dataToSend, true); } } else { // ASCIIæ ¼å¼åé displayData.append(dataToSend); @@ -477,7 +470,7 @@ txtDataView.setCaretPosition(txtDataView.getDocument().getLength()); }); } // ä¿®æ¹æ·»å è¿ç¨è®¾å¤æ¹æ³ // å¨MessageViewPanelç±»ä¸ä¿®æ¹addRemoteDeviceæ¹æ³ public static void addRemoteDevice(String ip, int port, int localPort) { @@ -494,65 +487,133 @@ break; } } if (!exists) { cbRemoteDevice.addItem(device); } }); } } // æè·æ°æ®çæ ¸å¿æ¹æ³ public static void captureData(String rawData, String ip, int port, int localPort, String timestamp) { // æ£æ¥çªå£æ¯å¦å¯è§ // ä¿®æ¹éç¨æ°æ®æ¾ç¤ºæ¹æ³ public static void showData(String rawData, String ip, int port, int localPort, String deviceId) { if (!isWindowVisible) { return; } String formattedData = formatData(rawData,ip,port,timestamp); // æ ¼å¼åæ°æ® if(isCapturing) { // è·åå½åéæ© String selectedDataType = (String) cbDataType.getSelectedItem(); String selectedProtocol = (String) cbProtocol.getSelectedItem(); String selectedDeviceId = (String) cbDeviceId.getSelectedItem(); // ä½¿ç¨æ°æ¹æ³è·åå½åèµæºå ResourceBundle messages = Languages.getCurrentMessages(); String allTypes = messages.getString("MESSAGE_VIEW_ALL_TYPES"); String allProtocols = messages.getString("MESSAGE_VIEW_ALL_PROTOCOLS"); String allDevices = messages.getString("MESSAGE_VIEW_ALL_DEVICES"); String udpPortA = messages.getString("MESSAGE_VIEW_UDP_PORT_A"); String udpPortB = messages.getString("MESSAGE_VIEW_UDP_PORT_B"); String udpProtocol = "UDP"; // ç´æ¥ä½¿ç¨åè®®åç§° // æ£æ¥æ°æ®ç±»åè¿æ»¤ boolean dataTypeMatch = selectedDataType.equals(allTypes) || (localPort == UDPPortAReceiver.PORT && selectedDataType.equals(udpPortA)) || (localPort == UDPPortBReceiver.PORT && selectedDataType.equals(udpPortB)); // æ£æ¥åè®®è¿æ»¤ boolean protocolMatch = selectedProtocol.equals(allProtocols) || (localPort == UDPPortAReceiver.PORT && selectedProtocol.equals(udpProtocol)) || (localPort == UDPPortBReceiver.PORT && selectedProtocol.equals(udpProtocol)); // æ£æ¥è®¾å¤IDè¿æ»¤ boolean deviceIdMatch=false; if("1".equals(deviceId)) { deviceIdMatch=true; }else { deviceIdMatch = selectedDeviceId.equals(allDevices) || (deviceId != null && deviceId.equals(selectedDeviceId)); } // åªæå½æææ¡ä»¶é½å¹é æ¶ææ¾ç¤º if (!(dataTypeMatch && protocolMatch && deviceIdMatch)) { return; } // çææ¯«ç§çº§æ¶é´æ³ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS"); String timestamp = sdf.format(new Date()); String formattedData = formatData(rawData, ip, port, timestamp); if (isCapturing) { // æ·»å è¿ç¨è®¾å¤å°ä¸ææ¡ addRemoteDevice(ip, port, localPort); // ç¡®ä¿è°ç¨å¸¦ç«¯å£åæ°çæ¹æ³ // è·åå½åéæ©ç设å¤IDåæ°æ®ç±»å String deviceId = cbDeviceId.getSelectedItem().toString(); String dataType = cbDataType.getSelectedItem().toString(); addRemoteDevice(ip, port, localPort); // å¨EDT线ç¨ä¸æ´æ°UI SwingUtilities.invokeLater(() -> { txtDataView.append(formattedData + "\n"); // æ·»å æ°æ®å°ææ¬åºå // èªå¨æ»å¨å°åºé¨ txtDataView.append(formattedData + "\n"); txtDataView.setCaretPosition(txtDataView.getDocument().getLength()); }); } // 妿å¯ç¨äºèªå¨ä¿åï¼åä¿åå°æä»¶ if (chkAutoSave.isSelected()) { saveToFile(formattedData); } } } // æ ¼å¼åæ°æ®æ¾ç¤º private static String formatData(String rawData, String ip, int port,String timestamp) { StringBuilder formatted = new StringBuilder(); // 使ç¨StringBuilderæå»ºæ ¼å¼åå符串 // 妿å¯ç¨äºæ¾ç¤ºæ¥æºï¼æ·»å æ¶é´æ³åæºå°å // ä¿®æ¹æ ¼å¼æ¾ç¤ºæ¹æ³ï¼æ¯ææ··åæ ¼å¼ private static String formatData(String rawData, String ip, int port, String timestamp) { StringBuilder formatted = new StringBuilder(); // ä½¿ç¨æ°æ¹æ³è·åå½åèµæºå ResourceBundle messages = Languages.getCurrentMessages(); // æ¾ç¤ºæ¥æºä¿¡æ¯ if (chkShowSource.isSelected()) { formatted.append("["+timestamp+";"+ip+":"+port+"]"); // æ·»å æ¨¡ææºå°å formatted.append("[") .append(timestamp) .append("][") .append(ip) .append(":") .append(port) .append("] "); } // æ ¹æ®æ¾ç¤ºéé¡¹æ ¼å¼åæ°æ® if (chkHexDisplay.isSelected() && chkAsciiDisplay.isSelected()) { // åæ¶æ¾ç¤ºåå è¿å¶åASCII formatted.append(toHexString(rawData)) // æ·»å åå è¿å¶è¡¨ç¤º .append(" | ") // æ·»å åé符 .append(rawData); // æ·»å åå§ASCIIæ°æ® formatted.append(formatHexString(rawData)) .append(" | ") .append(hexToAscii(rawData)) .append(" [") .append(messages.getString("MESSAGE_VIEW_MIXED_FORMAT")) .append("]"); } else if (chkHexDisplay.isSelected()) { // ä» æ¾ç¤ºåå è¿å¶ formatted.append(toHexString(rawData)); formatted.append(formatHexString(rawData)) .append(" [") .append(messages.getString("MESSAGE_VIEW_HEX_FORMAT")) .append("]"); } else if (chkAsciiDisplay.isSelected()) { formatted.append(hexToAscii(rawData)) .append(" [") .append(messages.getString("MESSAGE_VIEW_ASCII_FORMAT")) .append("]"); } else { // é»è®¤æ¾ç¤ºåå§ASCIIæ°æ® formatted.append(rawData); formatted.append(hexToAscii(rawData)); } return formatted.toString(); // è¿åæ ¼å¼ååçå符串 return formatted.toString(); } // ä¿®æ¹è®¾å¤IDå è½½æ¹æ³ private void loadDeviceIds() { cbDeviceId.removeAllItems(); cbDeviceId.addItem(messages.getString("MESSAGE_VIEW_ALL_DEVICES")); List<String> tags = Dell_tag.getAlldeviceIds(); for (String tag : tags) { cbDeviceId.addItem(tag); } } // å°å符串转æ¢ä¸ºåå è¿å¶è¡¨ç¤º @@ -563,7 +624,25 @@ } return hex.toString().trim(); // è¿åå¹¶å»é¤æ«å°¾ç©ºæ ¼ } // æ ¼å¼ååå è¿å¶åç¬¦ä¸²ï¼æ¯ä¸¤ä¸ªå符å ç©ºæ ¼ï¼ private static String formatHexString(String hex) { StringBuilder formatted = new StringBuilder(); for (int i = 0; i < hex.length(); i += 2) { if (i > 0) formatted.append(" "); formatted.append(hex.substring(i, Math.min(i + 2, hex.length()))); } return formatted.toString(); } // å°åå è¿å¶å符串转æ¢ä¸ºASCII private static String hexToAscii(String hexStr) { StringBuilder output = new StringBuilder(); for (int i = 0; i < hexStr.length(); i += 2) { String str = hexStr.substring(i, i + 2); output.append((char) Integer.parseInt(str, 16)); } return output.toString(); } // ä¿åæ°æ®å°æä»¶ private static void saveToFile(String data) { SimpleDateFormat fileFormat = new SimpleDateFormat("yyyyMMdd"); // æä»¶æ¥ææ ¼å¼ src/dell_targets/Dell_BaseStation.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,180 @@ package dell_targets; import databases.DBConnector; import targets.LocationBaseStation; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.ConcurrentHashMap; public class Dell_BaseStation { public static List<LocationBaseStation> baseStations; private static ConcurrentHashMap<String, LocationBaseStation> baseStationMap; // 以åºç«ID为é®çæ å° public static List<LocationBaseStation> getBaseStations() throws SQLException { baseStations = new ArrayList<>(); baseStationMap = new ConcurrentHashMap<>(); // ä¿®å¤ï¼åå§åæ å° ResultSet rs = DBConnector.queryTableData("location_base_station"); if (rs == null) { // 说æåºå±æ¿ä¸å°æ°æ®ï¼ç´æ¥æå¼å¸¸ææå°æ¥å¿ throw new SQLException("DBConnector.queryTableData returned null, " + "please check database connection & SQL."); } while (rs.next()) { LocationBaseStation baseStation = new LocationBaseStation(); baseStation.setId((int) rs.getLong("id")); baseStation.setCode(rs.getString("base_station_id")); baseStation.setStatus(rs.getString("statuss")); baseStation.setXCoordinate(rs.getString("x_coordinate")); baseStation.setYCoordinate(rs.getString("y_coordinate")); baseStation.setZCoordinate(rs.getString("z_coordinate")); baseStation.setLongitude(rs.getString("longitude")); baseStation.setLatitude(rs.getString("latitude")); baseStation.setElevation(rs.getString("elevation")); baseStation.setHorizontalAngle(rs.getString("horizontal_angle")); baseStation.setPitchAngle(rs.getString("pitch_angle")); baseStation.setFloor(rs.getString("located_layer")); baseStation.setGroup(rs.getString("located_group")); baseStation.setRange(rs.getString("range")); baseStation.setSyncStatus(rs.getString("sync_status")); baseStation.setSyncType(rs.getString("sync_type")); baseStation.setSyncBaseStation(rs.getString("sync_base_station")); baseStation.setIpAddress(rs.getString("ip_address")); baseStation.setPort(rs.getString("ports")); baseStation.setFirmwareVersion(rs.getString("firmware_version")); baseStation.setJudgmentDistance(rs.getString("judgment_distance")); baseStation.setBattery(rs.getString("battery")); baseStation.setCalibrationDistance(rs.getString("calibration_distance")); baseStation.setSignalSendTime(rs.getString("signal_transmission_time")); baseStation.setCommunicationGroup(rs.getString("communication_group")); baseStation.setIconAddress(rs.getString("icon_url")); baseStation.setOnlineTime(rs.getString("online_time")); baseStation.setOfflineTime(rs.getString("offline_time")); baseStation.setOfflineDuration(rs.getString("offline_duration")); baseStation.setAlgorithmDimension(rs.getString("algorithm_dimension")); baseStation.setBottomHeight(rs.getString("located_bottom_height")); baseStation.setTopHeight(rs.getString("located_top_height")); baseStation.setIsBarometricStation(rs.getString("barometric_base_station")); baseStation.setSwitchDistance(rs.getString("handover_distance")); baseStation.setMaxDistance(rs.getString("maximum_distance")); baseStation.setOutputAllRanging(rs.getString("output_all_base_station_ranging")); baseStation.setCompany(rs.getString("company")); baseStation.setCrossLayerHeight(rs.getString("cross_layer_height")); baseStation.setCrossLayerGroup(rs.getString("cross_layer_group")); baseStation.setRequiredDistance(rs.getString("must_pass_distance")); baseStation.setAdjacent1(rs.getString("adjacent1")); baseStation.setAdjacent2(rs.getString("adjacent2")); baseStation.setAdjacent3(rs.getString("adjacent3")); baseStation.setAdjacent4(rs.getString("adjacent4")); baseStation.setAdjacent5(rs.getString("adjacent5")); baseStation.setAdjacent6(rs.getString("adjacent6")); baseStation.setAdjacent7(rs.getString("adjacent7")); baseStation.setAdjacent8(rs.getString("adjacent8")); baseStation.setAdjacent9(rs.getString("adjacent9")); baseStation.setAdjacent10(rs.getString("adjacent10")); baseStation.setReserved1(rs.getString("reserved1")); baseStation.setReserved2(rs.getString("reserved2")); baseStation.setReserved3(rs.getString("reserved3")); baseStation.setReserved4(rs.getString("reserved4")); baseStation.setReserved5(rs.getString("reserved5")); baseStation.setReserved6(rs.getString("reserved6")); baseStation.setReserved7(rs.getString("reserved7")); baseStation.setReserved8(rs.getString("reserved8")); baseStation.setReserved9(rs.getString("reserved9")); baseStation.setReserved10(rs.getString("reserved10")); baseStation.setReserved11(rs.getString("reserved11")); baseStation.setReserved12(rs.getString("reserved12")); baseStation.setReserved13(rs.getString("reserved13")); baseStation.setReserved14(rs.getString("reserved14")); baseStation.setReserved15(rs.getString("reserved15")); baseStation.setReserved16(rs.getString("reserved16")); baseStations.add(baseStation); baseStationMap.put(baseStation.getCode(), baseStation); // 以åºç«ID为é®åå ¥æ å° } return baseStations; } /** * æ ¹æ®åºç«IDé«æä¿®æ¹å±æ§å¼ * @param baseStationId åºç«IDï¼base_station_idï¼ * @param propertyName 屿§åï¼éä¸setteræ¹æ³å¹é ï¼ * @param value æ°å±æ§å¼ */ public static void updateBaseStationProperty(String baseStationId, String propertyName, String value) { LocationBaseStation station = baseStationMap.get(baseStationId); if (station == null) return; // åºç«ä¸åå¨åå¿½ç¥ // æ ¹æ®å±æ§åè°ç¨å¯¹åºsetterï¼é«æå¹é é«é¢å±æ§ï¼ switch (propertyName) { case "status": station.setStatus(value); break; // æ´æ°ç¶æ case "battery": station.setBattery(value); break; // æ´æ°çµé case "ipAddress": station.setIpAddress(value); break; // æ´æ°IPå°å case "onlineTime": station.setOnlineTime(value); break; // æ´æ°ä¸çº¿æ¶é´ case "offlineTime": station.setOfflineTime(value); break; // æ´æ°ç¦»çº¿æ¶é´ case "offlineDuration": station.setOfflineDuration(value); break; // æ´æ°ç¦»çº¿æ¶é¿ case "syncStatus": station.setSyncStatus(value); break; //åæ¥ç¶æ case "barometerReading": station.setBarometerReading(value); break; //åæ¥ç¶æ // æ·»å å ¶ä»é«é¢å±æ§... default: throw new IllegalArgumentException("䏿¯æå±æ§: " + propertyName); } } /** * æ ¹æ®åºç«IDè·ååºç«å¯¹è±¡ï¼é«æè®¿é®ï¼ * @param baseStationId åºç«ID * @return åºç«å¯¹è±¡ï¼ä¸åå¨åè¿ånullï¼ */ public static LocationBaseStation getBaseStationById(String baseStationId) { return baseStationMap.get(baseStationId); // O(1)å¤æåº¦ç´æ¥è·å } /** * è·åææå¨çº¿ç¶æ(onlineStatus=1)ç设å¤ï¼é«æå åæä½ï¼ * @return ä¸å¯ä¿®æ¹çbaseStationMapéåï¼é¿å å¤é¨ä¿®æ¹ç¼åï¼ */ public static List<LocationBaseStation> getOnlineBaseStations() { if (baseStationMap == null || baseStationMap.isEmpty()) { return Collections.emptyList(); // ç¼å为空æ¶è¿å空éå } List<LocationBaseStation> BaseStation = new ArrayList<>(); for (LocationBaseStation base : baseStationMap.values()) { if ("1".equals(base.getStatus())) { // å符串æ¯è¾é¿å NPE BaseStation.add(base); } } return Collections.unmodifiableList(BaseStation); // è¿åä¸å¯åéå } /** * å¿«éè·åLocationTagå¯¹è±¡çæ»æ°ï¼ä½¿ç¨å åç¼åæé«æ§è½ï¼ * @return LocationTagå¯¹è±¡çæ»æ° */ public static int getLocationBaseCount() { if (baseStationMap == null) { synchronized (LocationBaseStation.class) { if (baseStationMap == null) { try { getBaseStations(); // åå§åç¼å } catch (SQLException e) { e.printStackTrace(); return 0; // åå§å失败è¿å0 } } } } return baseStationMap.size(); } } src/dell_targets/Dell_SystemConfiguration.java
@@ -14,6 +14,9 @@ static List<SystemConfiguration> configs; public static boolean xytognssOpen=false; public static boolean gnsstoxyOpen=false; public static String language="0"; public static int hexport=8234; public static int ascallport=7000; // è·åç³»ç»é ç½®å表 public static List<SystemConfiguration> getSystemConfigurations() { // å建é 置对象å表 @@ -39,9 +42,14 @@ // æ°æ®åºå¯ç config.setDatabasePassword(rs.getString("database_password")); // HEXæ°æ®UDPæ¥æ¶ç«¯å£ config.setHexDataUdpReceivePort(rs.getString("hex_data_udp_receive_port")); String hexp=rs.getString("hex_data_udp_receive_port"); hexport=Integer.parseInt(hexp); config.setHexDataUdpReceivePort(hexp); String ascll=rs.getString("ascii_data_udp_receive_port"); ascallport=Integer.parseInt(ascll);; // ASCIIæ°æ®UDPæ¥æ¶ç«¯å£ config.setAsciiDataUdpReceivePort(rs.getString("ascii_data_udp_receive_port")); config.setAsciiDataUdpReceivePort(ascll); // TCPæ°æ®æ¥æ¶ç«¯å£1 config.setTcpDataReceivePort1(rs.getString("tcp_data_receive_port1")); // TCPæ°æ®æ¥æ¶ç«¯å£2 @@ -158,8 +166,10 @@ config.setRealTimeTrajectoryDuration(rs.getString("real_time_trajectory_duration")); // 宿¶è½¨è¿¹é¢è² config.setRealTimeTrajectoryColor(rs.getString("real_time_trajectory_color")); String langua=rs.getString("system_language"); language=langua; // ç³»ç»è¯è¨ config.setSystemLanguage(rs.getString("system_language")); config.setSystemLanguage(langua); // JNAæ¥å¿å¼å ³ config.setJnaLogSwitch(rs.getString("jna_log_switch")); // æ¶é´çåé æ¹å¼ src/dell_targets/Dell_tag.java
@@ -4,12 +4,21 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.ConcurrentHashMap; public class Dell_tag { static List<LocationTag> locationTags; public static List<LocationTag> locationTags; private static ConcurrentHashMap<String, LocationTag> tagMap; // 设å¤ID->æ ç¾å¯¹è±¡çæ å° public static List<LocationTag> getlocationTags() throws SQLException{ List<LocationTag> locationTags = new ArrayList<>(); List<LocationTag> locationTags = new ArrayList<>(); tagMap = new ConcurrentHashMap<>(); // åå§åæ å° ResultSet rs =DBConnector.queryTableData("location_tag"); if (rs == null) { // 说æåºå±æ¿ä¸å°æ°æ®ï¼ç´æ¥æå¼å¸¸ææå°æ¥å¿ throw new SQLException("DBConnector.queryTableData returned null, " + "please check database connection & SQL."); } while (rs.next()) { LocationTag locationTag = new LocationTag(); locationTag.setId((int) rs.getLong("id")); @@ -98,6 +107,7 @@ locationTag.setIpAddress(rs.getString("ipAddress")); locationTag.setIpPort(rs.getString("Interaction_Type")); locationTags.add(locationTag); tagMap.put(locationTag.getDeviceNumber(), locationTag); // æ·»å å°æ å° } return locationTags; } @@ -119,6 +129,117 @@ DBConnector.executeUpdate(sql, deviceId); } /** * æ ¹æ®è®¾å¤IDé«æä¿®æ¹å±æ§å¼ * @param deviceId 设å¤IDï¼device_idï¼ * @param propertyName 屿§åï¼éä¸setteræ¹æ³å¹é ï¼ * @param value æ°å±æ§å¼ */ public static void updateLocationTagProperty(String deviceId, String propertyName, String value) { LocationTag tag = tagMap.get(deviceId); if (tag == null) return; // æ ç¾ä¸åå¨åå¿½ç¥ // æ ¹æ®å±æ§åè°ç¨å¯¹åºsetter switch (propertyName) { case "id": tag.setId(Integer.parseInt(value)); break; case "deviceNumber": tag.setDeviceNumber(value); break; case "deviceName": tag.setDeviceName(value); break; case "deviceVersion": tag.setDeviceVersion(value); break; case "deviceCardNumber": tag.setDeviceCardNumber(value); break; case "deviceType": tag.setDeviceType(value); break; case "team": tag.setTeam(value); break; case "group": tag.setGroup(value); break; case "department": tag.setDepartment(value); break; case "iconAddress": tag.setIconAddress(value); break; case "gender": tag.setGender(value); break; case "ethnicity": tag.setEthnicity(value); break; case "communicationAddress": tag.setCommunicationAddress(value); break; case "boundPhone": tag.setBoundPhone(value); break; case "idNumber": tag.setIdNumber(value); break; case "position": tag.setPosition(value); break; case "boundPlateNumber": tag.setBoundPlateNumber(value); break; case "faceAddress": tag.setFaceAddress(value); break; case "heartRate": tag.setHeartRate(value); break; case "bloodPressure": tag.setBloodPressure(value); break; case "bloodOxygen": tag.setBloodOxygen(value); break; case "temperature": tag.setTemperature(value); break; case "sosStatus": tag.setSosStatus(value); break; case "motionStatus": tag.setMotionStatus(value); break; case "onlineStatus": tag.setOnlineStatus(value); break; case "searchStatus": tag.setSearchStatus(value); break; case "batteryStatus": tag.setBatteryStatus(value); break; case "deviceBattery": tag.setDeviceBattery(value); break; case "removalStatus": tag.setRemovalStatus(value); break; case "collisionStatus": tag.setCollisionStatus(value); break; case "elevationStatus": tag.setElevationStatus(value); break; case "gatheringCount": tag.setGatheringCount(value); break; case "proximityAlarm": tag.setProximityAlarm(value); break; case "area": tag.setArea(value); break; case "xCoordinate": tag.setXCoordinate(value); break; case "yCoordinate": tag.setYCoordinate(value); break; case "zCoordinate": tag.setZCoordinate(value); break; case "floor": tag.setFloor(value); break; case "speed": tag.setSpeed(value); break; case "locationSource": tag.setLocationSource(value); break; case "lastUwbSignalTime": tag.setLastUwbSignalTime(value); break; case "lastSatelliteSignalTime": tag.setLastSatelliteSignalTime(value); break; case "uwbTimeSlot": tag.setUwbTimeSlot(value); break; case "latestRangingSeq": tag.setLatestRangingSeq(value); break; case "latestRangingBaseId": tag.setLatestRangingBaseId(value); break; case "latestRangingDistance": tag.setLatestRangingDistance(value); break; case "latestRangingBaseCount": tag.setLatestRangingBaseCount(value); break; case "latestRangingSignalStrength": tag.setLatestRangingSignalStrength(value); break; case "utcTime": tag.setUtcTime(value); break; case "latitude": tag.setLatitude(value); break; case "longitude": tag.setLongitude(value); break; case "satelliteQuality": tag.setSatelliteQuality(value); break; case "hdop": tag.setHdop(value); break; case "satelliteCount": tag.setSatelliteCount(value); break; case "altitude": tag.setAltitude(value); break; case "differentialTime": tag.setDifferentialTime(value); break; case "geoidHeight": tag.setGeoidHeight(value); break; case "satelliteSpeed": tag.setSatelliteSpeed(value); break; case "lastBarometricValue": tag.setLastBarometricValue(value); break; case "recentCoordinates": tag.setRecentCoordinates(value); break; case "recentBarometricValues": tag.setRecentBarometricValues(value); break; case "offlineTime": tag.setOfflineTime(value); break; case "onlineTime": tag.setOnlineTime(value); break; case "offlineDuration": tag.setOfflineDuration(value); break; case "onlineDuration": tag.setOnlineDuration(value); break; case "motionlessStartTime": tag.setMotionlessStartTime(value); break; case "motionlessEndTime": tag.setMotionlessEndTime(value); break; case "motionlessDuration": tag.setMotionlessDuration(value); break; case "validSatelliteSignal": tag.setValidSatelliteSignal(value); break; case "company": tag.setCompany(value); break; case "sleepTime": tag.setSleepTime(value); break; case "vibrationTime": tag.setVibrationTime(value); break; case "frequency": tag.setFrequency(value); break; case "motionlessTime": tag.setMotionlessTime(value); break; case "accelerationValue": tag.setAccelerationValue(value); break; case "imuTime": tag.setImuTime(value); break; case "reserved1": tag.setReserved1(value); break; case "reserved2": tag.setReserved2(value); break; case "reserved3": tag.setReserved3(value); break; case "reserved4": tag.setReserved4(value); break; case "reserved5": tag.setReserved5(value); break; case "ipAndPort": tag.setIpAndPort(value); break; case "interactionType": tag.setInteractionType(value); break; case "ipAddress": tag.setIpAddress(value); break; case "ipPort": tag.setIpPort(value); break; default: throw new IllegalArgumentException("æ æå±æ§: " + propertyName); } } /** * æ ¹æ®è®¾å¤IDè·åæ ç¾å¯¹è±¡ï¼é«æè®¿é®ï¼ * @param deviceId 设å¤ID * @return æ ç¾å¯¹è±¡ï¼ä¸åå¨è¿ånullï¼ */ public static LocationTag getTagByDeviceId(String deviceId) { return tagMap.get(deviceId); } //è·åææçtagid public static List<String> getAlldeviceIds() { List<String> types = new ArrayList<>(); @@ -134,4 +255,42 @@ } return types; } /** * è·åææå¨çº¿ç¶æ(onlineStatus=1)ç设å¤ï¼é«æå åæä½ï¼ * @return ä¸å¯ä¿®æ¹çLocationTagéåï¼é¿å å¤é¨ä¿®æ¹ç¼åï¼ */ public static List<LocationTag> getOnlineLocationTags() { if (tagMap == null || tagMap.isEmpty()) { return Collections.emptyList(); // ç¼å为空æ¶è¿å空éå } List<LocationTag> onlineTags = new ArrayList<>(); for (LocationTag tag : tagMap.values()) { if ("1".equals(tag.getOnlineStatus())) { // å符串æ¯è¾é¿å NPE onlineTags.add(tag); } } return Collections.unmodifiableList(onlineTags); // è¿åä¸å¯åéå } /** * å¿«éè·åLocationTagå¯¹è±¡çæ»æ°ï¼ä½¿ç¨å åç¼åæé«æ§è½ï¼ * @return LocationTagå¯¹è±¡çæ»æ° */ public static int getLocationTagCount() { if (tagMap == null) { synchronized (Dell_tag.class) { if (tagMap == null) { try { getlocationTags(); // åå§åç¼å } catch (SQLException e) { e.printStackTrace(); return 0; // åå§å失败è¿å0 } } } } return tagMap.size(); } } src/publicsWay/Languages.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,53 @@ package publicsWay; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.Locale; import java.util.PropertyResourceBundle; import java.util.ResourceBundle; import dell_targets.Dell_SystemConfiguration; public class Languages { // ä¿®æ¹åçèµæºå è½½æ¹æ³ public static ResourceBundle getCurrentMessages() { // æ ¹æ®ç³»ç»é ç½®å³å®è¯è¨ Locale locale = "1".equals(Dell_SystemConfiguration.language) ? Locale.ENGLISH : Locale.SIMPLIFIED_CHINESE; // 使ç¨ä¸Windows.javaç¸åçå è½½é»è¾ String fileName = locale.equals(Locale.ENGLISH) ? "Messages_en.properties" : "Messages_zh.properties"; File langFile = new File("systemfile/" + fileName); if (!langFile.exists()) { System.err.println("é»è®¤èµæºæä»¶æªæ¾å°: " + langFile.getAbsolutePath()); try { return ResourceBundle.getBundle("systemfile.Messages", locale); } catch (Exception e) { System.err.println("åå¤èµæºå 载失败: " + e.getMessage()); // è¿å空å é¿å å´©æº return new ResourceBundle() { @Override protected Object handleGetObject(String key) { return "!" + key + "!"; } @Override public Enumeration<String> getKeys() { return java.util.Collections.emptyEnumeration(); } }; } } try (InputStream inputStream = new FileInputStream(langFile)) { return new PropertyResourceBundle(inputStream); } catch (IOException e) { System.err.println("æ æ³å è½½èµæºæä»¶: " + e.getMessage()); return ResourceBundle.getBundle("systemfile.Messages", locale); } } } src/publicsWay/UwbDataParser.java
@@ -130,11 +130,6 @@ this.battery = battery; this.buttonStatus = buttonStatus; } @Override public String toString() { return String.format("å åº: %d, æ ç¾: %s, åºç«: %s, è·ç¦»: %d mm, çµé: %d%%, æé®: %d", sequence, tagId, baseId, distance, battery, buttonStatus); } } } src/targets/LocationBaseStation.java
@@ -66,6 +66,7 @@ private String reserved14; // å¤ç¨ 14 private String reserved15; // å¤ç¨ 15 private String reserved16; // å¤ç¨ 16 private String barometerReading;//æ°åè®¡å¼ // Getter and Setter methods public int getId() { @@ -595,4 +596,36 @@ public void setReserved16(String reserved16) { this.reserved16 = reserved16; } public String getxCoordinate() { return xCoordinate; } public String getyCoordinate() { return yCoordinate; } public String getzCoordinate() { return zCoordinate; } public String getBarometerReading() { return barometerReading; } public void setxCoordinate(String xCoordinate) { this.xCoordinate = xCoordinate; } public void setyCoordinate(String yCoordinate) { this.yCoordinate = yCoordinate; } public void setzCoordinate(String zCoordinate) { this.zCoordinate = zCoordinate; } public void setBarometerReading(String barometerReading) { this.barometerReading = barometerReading; } } src/udptcp/DellHexBaowen.java
ÎļþÒÑɾ³ý src/udptcp/HexBaowen.java
ÎļþÒÑɾ³ý src/udptcp/PacketParser.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,163 @@ package udptcp; import java.util.ArrayList; import java.util.List; // éå½å为PacketParserï¼è¡¨ç¤ºæ°æ®å è§£æå¨ public class PacketParser { // æ·»å åå è¿å¶å符æ°ç»å¸¸é private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); // ç¼å²åºåèæ°ç» private byte[] buffer = new byte[4096]; // å½åç¼å²åºæææ°æ®é¿åº¦ private int bufferLength = 0; // è¿½å æ°æ°æ®å°ç¼å²åº public void appendData(byte[] newData, int length) { // æ£æ¥ç¼å²åºæ¯å¦è¶³å¤ if (bufferLength + length > buffer.length) { // å建æ°çæ´å¤§ç¼å²åº byte[] newBuffer = new byte[bufferLength + length]; // å¤å¶åææ°æ® System.arraycopy(buffer, 0, newBuffer, 0, bufferLength); buffer = newBuffer; } // è¿½å æ°æ°æ® System.arraycopy(newData, 0, buffer, bufferLength, length); // æ´æ°ç¼å²åºé¿åº¦ bufferLength += length; } // æ°å¢æ¹æ³ï¼åèæ°ç»è½¬åå è¿å¶å符串 public static String bytesToHexString(byte[] bytes) { if (bytes == null) return ""; char[] hexChars = new char[bytes.length * 2]; for (int j = 0; j < bytes.length; j++) { int v = bytes[j] & 0xFF; hexChars[j * 2] = HEX_ARRAY[v >>> 4]; hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; } return new String(hexChars); } // è§£æç¼å²åºä¸çææå®æ´æ°æ®å public List<DataPacket> parsePackets() { List<DataPacket> packets = new ArrayList<>(); int index = 0; // å½åè§£æä½ç½®ç´¢å¼ // éåç¼å²åºæ¥æ¾å®æ´æ°æ®å while (index <= bufferLength - 4) { // ç¡®ä¿æè¶³å¤æ°æ®æ£æ¥å 头 // æ£æ¥å 头æ è¯ 0x55 0xAA if (buffer[index] == 0x55 && (buffer[index + 1] & 0xFF) == 0xAA) { // è·åå ç±»åï¼ç¬¬3åèï¼ int packetType = buffer[index + 2] & 0xFF; // è·åæ°æ®é¿åº¦ï¼ç¬¬4åèï¼ int dataLenField = buffer[index + 3] & 0xFF; // 计ç®å®æ´å é¿åº¦ï¼å 头+æ°æ®+æ ¡éªï¼ int totalPacketLen = 4 + dataLenField + 2; // å¢å 2åèæ ¡éªä½ // æ£æ¥æ¯å¦æè¶³å¤æ°æ®ææå®æ´å if (index + totalPacketLen > bufferLength) { break; // æ°æ®ä¸è¶³ï¼çå¾ æ´å¤æ°æ® } // æå宿´æ°æ®å byte[] packetData = new byte[totalPacketLen]; System.arraycopy(buffer, index, packetData, 0, totalPacketLen); // éªè¯æ ¡éªå if (verifyChecksum(packetData)) { // è§£æåä¸ªæ°æ®å DataPacket packet = parseSinglePacket(packetType, packetData); if (packet != null) { packets.add(packet); // æ·»å å°ç»æå表 } index += totalPacketLen; // ç§»å¨å°ä¸ä¸ä¸ªå } else { index++; // æ ¡éªå¤±è´¥ï¼è·³è¿å½ååè } } else { index++; // éå 头æ è¯ï¼ç»§ç»æ¥æ¾ } } // æ¸ çå·²å¤çæ°æ® if (index > 0) { int remaining = bufferLength - index; if (remaining > 0) { // ç§»å¨å©ä½æ°æ®å°ç¼å²åºå¼å¤´ System.arraycopy(buffer, index, buffer, 0, remaining); } bufferLength = remaining; // æ´æ°ç¼å²åºé¿åº¦ } return packets; } // æ ¡éªæ°æ®å 宿´æ§ private boolean verifyChecksum(byte[] packet) { int len = packet.length; if (len < 4) return false; // é¿åº¦ä¸è¶³ int sum = 0; // 计ç®ä»ç¬¬3åèå°åæ°ç¬¬3åèçåï¼è·³è¿å å¤´åæ ¡éªä½ï¼ for (int i = 2; i < len - 2; i++) { sum += packet[i] & 0xFF; } // ååå¾å°16使 ¡éªå sum = ~sum & 0xFFFF; // æåå ä¸çæ ¡éªåï¼å°ç«¯æ ¼å¼ï¼ int receivedChecksum = ((packet[len - 1] & 0xFF) << 8) | (packet[len - 2] & 0xFF); // æ¯è¾æ ¡éªå return sum == receivedChecksum; } // è§£æåä¸ªæ°æ®å private DataPacket parseSinglePacket(int packetType, byte[] packet) { // åå»ºæ°æ®å 对象ï¼å å«å ç±»åï¼ return new DataPacket(packetType, packet); } // æ°æ®å å é¨ç±» public static class DataPacket { private final int packetType; // å ç±»å private final byte[] packet;//å æ°æ® public DataPacket(int packetType, byte[] packet) { this.packetType = packetType; this.packet = packet; } // è·åå ç±»å public int getPacketType() { return packetType; } // å æ°æ® public byte[] getPacket() { return packet; } } // HEXå符串转åèæ°ç» public static byte[] hexStringToBytes(String hex) { // ç§»é¤ç©ºæ ¼ hex = hex.replaceAll("\\s", ""); int len = hex.length(); // åå»ºç»ææ°ç» byte[] data = new byte[len / 2]; // æ¯ä¸¤ä¸ªå符转æ¢ä¸ä¸ªåè for (int i = 0; i < len; i += 2) { // é«ä½è½¬æ¢ int high = Character.digit(hex.charAt(i), 16) << 4; // ä½ä½è½¬æ¢ int low = Character.digit(hex.charAt(i + 1), 16); data[i / 2] = (byte) (high | low); } return data; } } src/udptcp/PacketProcessingSystem.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,104 @@ package udptcp; import java.util.List; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicBoolean; import dell55AAData.Dell55AA01Parser; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class PacketProcessingSystem { // 线ç¨å®å ¨çæ¥æåå¨éåï¼éåAï¼ private static final ConcurrentLinkedQueue<HexPacket> packetQueue = new ConcurrentLinkedQueue<>(); private static final AtomicBoolean isRunning = new AtomicBoolean(false); private static final ExecutorService parserExecutor = Executors.newSingleThreadExecutor(); private static Thread parserThread; // æ¥æåå¨ç»æ public static class HexPacket { public final String ip; public final int port; public final String hexData; public final long timestamp; public HexPacket(String ip, int port, String hexData, long timestamp) { this.ip = ip; this.port = port; this.hexData = hexData; this.timestamp = timestamp; } } // æ¥æ¶ç«¯å卿¥æï¼UDPPortAReceiverä¸è°ç¨ï¼ public static void storePacket(String ip, int port, String hexData) { if (packetQueue.size() < 100000) { // éå¶éå大å°é²æ¢OOM packetQueue.offer(new HexPacket(ip, port, hexData, System.currentTimeMillis())); } } // å¯å¨è§£æç³»ç» public static void startProcessing() { if (isRunning.get()) return; isRunning.set(true); parserThread = new Thread(() -> { PacketParser bufferManager = new PacketParser(); while (isRunning.get()) { HexPacket packet = packetQueue.poll(); if (packet == null) { Thread.yield(); // éå为空æ¶è®©åºCPU continue; } try { // 转æ¢HEX为åèæ°æ® byte[] rawData = PacketParser.hexStringToBytes(packet.hexData); // 追å å°ç¼å²åºå¹¶è§£æ bufferManager.appendData(rawData, rawData.length); List<PacketParser.DataPacket> parsedPackets = bufferManager.parsePackets(); // å¤çè§£æåçæ°æ®å for (PacketParser.DataPacket p : parsedPackets) { // æ ¹æ®å 头类åè·¯ç±å°ä¸åè§£æå¨ switch (p.getPacketType()) { case 0x01: processType01(p);break; case 0x02: processType02(p);break; default: System.err.println("æªç¥å ç±»å: " + p.getPacketType()); } } } catch (Exception e) { System.err.println("è§£æé误: " + e.getMessage()); } } }); parserThread.setDaemon(true); parserThread.start(); } // åæ¢è§£æç³»ç» public static void stopProcessing() { isRunning.set(false); parserExecutor.shutdownNow(); if (parserThread != null) { parserThread.interrupt(); } } // 示ä¾è§£ææ¹æ³ï¼éæ ¹æ®å®é åè®®å®ç°ï¼ private static void processType01(PacketParser.DataPacket packet) { String hexData = PacketParser.bytesToHexString(packet.getPacket()); Dell55AA01Parser.parse(hexData); } private static void processType02(PacketParser.DataPacket packet) { System.out.println("å¤ç55AA02å : " + packet); // å®é ä¸å¡é»è¾ } // å ¶ä»ç±»åå¤çæ¹æ³... } src/udptcp/TCPDiffDataReceiver.java
ÎļþÒÑɾ³ý src/udptcp/UDPPortAReceiver.java
@@ -2,119 +2,115 @@ import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong; import dell_system.MessageViewPanel; import dell_targets.Dell_SystemConfiguration; public class UDPPortAReceiver { public static final int PORT = 8234; private static final int MAX_DEVICES = 50000; private static final AtomicLong packetCount = new AtomicLong(0); private static final ExecutorService executor = Executors.newFixedThreadPool(10); private static DatagramSocket socket; private static volatile boolean isRunning = false; private static Thread receiverThread; private static final int LOCAL_PORT = PORT; // å®ä¹æ¬å°ç«¯å£ // å¯å¨æ¥æ¶å¨çéææ¹æ³ public static void startReceiver() { if (isRunning) return; isRunning = true; receiverThread = new Thread(() -> { try { socket = new DatagramSocket(PORT); byte[] buffer = new byte[2048]; while (isRunning) { DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); executor.execute(() -> { try { String ip = packet.getAddress().getHostAddress(); int port = packet.getPort(); String hexData = bytesToHex(packet.getData(), packet.getLength()); packetCount.incrementAndGet(); // è·åå½åæ¶é´åæ¶é´æ³ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String time = sdf.format(new Date()); int timestamp = (int)(System.currentTimeMillis() / 1000); // ä¿åå°HexBaowenéå // è°ç¨æ¶æ·»å æ¬å°ç«¯å£åæ° HexBaowen.intsert(ip, hexData, time, port, LOCAL_PORT, timestamp); } catch (Exception e) { System.err.println("Error processing UDP-A packet: " + e.getMessage()); } }); } } catch (Exception e) { System.err.println("UDP-A Server crashed: " + e.getMessage()); } finally { if (socket != null && !socket.isClosed()) { socket.close(); } } }); receiverThread.setDaemon(true); receiverThread.start(); } // åæ¢æ¥æ¶å¨ public static void stopReceiver() { isRunning = false; if (socket != null && !socket.isClosed()) { socket.close(); } executor.shutdown(); } // åéæ°æ®å°æå®è®¾å¤ public static void sendData(String ip, int port, String data, boolean isHex) { try { byte[] sendBytes; if (isHex) { // HEXæ ¼å¼åéï¼å°åå è¿å¶å符串转æ¢ä¸ºåèæ°ç» sendBytes = hexStringToByteArray(data); } else { // ASCIIæ ¼å¼åéï¼ç´æ¥è·ååèæ°ç» sendBytes = data.getBytes(); } InetAddress address = InetAddress.getByName(ip); DatagramPacket packet = new DatagramPacket(sendBytes, sendBytes.length, address, port); socket.send(packet); } catch (Exception e) { System.err.println("Error sending UDP data: " + e.getMessage()); } } private static String bytesToHex(byte[] bytes, int length) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < length; i++) { sb.append(String.format("%02X", bytes[i])); } return sb.toString(); } private static byte[] hexStringToByteArray(String hex) { hex = hex.replaceAll("\\s", ""); // ç§»é¤ææç©ºæ ¼ int len = hex.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { // å¤çæ¯ä¸¤ä¸ªå符ä½ä¸ºä¸ä¸ªåè data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i+1), 16)); } return data; } public static final int PORT =Dell_SystemConfiguration.hexport; @SuppressWarnings("unused") private static final int MAX_DEVICES = 50000; private static final AtomicLong packetCount = new AtomicLong(0); private static final ExecutorService executor = Executors.newFixedThreadPool(10); private static DatagramSocket socket; private static volatile boolean isRunning = false; private static Thread receiverThread; @SuppressWarnings("unused") private static final int LOCAL_PORT = PORT; // å®ä¹æ¬å°ç«¯å£ // å¯å¨æ¥æ¶å¨çéææ¹æ³ public static void startReceiver() { if (isRunning) return; isRunning = true; receiverThread = new Thread(() -> { try { socket = new DatagramSocket(PORT); byte[] buffer = new byte[2048]; while (isRunning) { DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); executor.execute(() -> { try { String ip = packet.getAddress().getHostAddress(); int port = packet.getPort(); String hexData = bytesToHex(packet.getData(), packet.getLength()); // è°ç¨æ¶æ·»å æ¬å°ç«¯å£åæ° PacketProcessingSystem.storePacket(ip, port, hexData); // æ¥ææ¥ççªå£æ¾ç¤ºæ°æ® MessageViewPanel.showData(hexData, ip, port, PORT,"1"); // +++ å¢å å è®¡æ° +++ packetCount.incrementAndGet(); // å ³é®ä¿®å¤ï¼å¢å 计æ°å¨ } catch (Exception e) { System.err.println("Error processing UDP-A packet: " + e.getMessage()); } }); } } catch (Exception e) { System.err.println("UDP-A Server crashed: " + e.getMessage()); } finally { if (socket != null && !socket.isClosed()) { socket.close(); } } }); receiverThread.setDaemon(true); receiverThread.start(); } public static long getPacketCount() { return packetCount.get(); } // åæ¢æ¥æ¶å¨ public static void stopReceiver() { isRunning = false; if (socket != null && !socket.isClosed()) { socket.close(); } executor.shutdown(); } // åéæ°æ®å°æå®è®¾å¤ public static void sendData(String ip, int port, String data, boolean isHex) { try { byte[] sendBytes; if (isHex) { // HEXæ ¼å¼åéï¼å°åå è¿å¶å符串转æ¢ä¸ºåèæ°ç» sendBytes = hexStringToByteArray(data); } else { // ASCIIæ ¼å¼åéï¼ç´æ¥è·ååèæ°ç» sendBytes = data.getBytes(); } InetAddress address = InetAddress.getByName(ip); DatagramPacket packet = new DatagramPacket(sendBytes, sendBytes.length, address, port); socket.send(packet); } catch (Exception e) { System.err.println("Error sending UDP data: " + e.getMessage()); } } private static String bytesToHex(byte[] bytes, int length) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < length; i++) { sb.append(String.format("%02X", bytes[i])); } return sb.toString(); } private static byte[] hexStringToByteArray(String hex) { hex = hex.replaceAll("\\s", ""); // ç§»é¤ææç©ºæ ¼ int len = hex.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { // å¤çæ¯ä¸¤ä¸ªå符ä½ä¸ºä¸ä¸ªåè data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i+1), 16)); } return data; } // è·åæ¥æ¶å°çæ°æ®å æ»æ° public static long getPacketCount() { return packetCount.get(); } } src/udptcp/UDPPortBReceiver.java
@@ -2,22 +2,21 @@ import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong; import dell_system.MessageViewPanel; public class UDPPortBReceiver { public static final int PORT = 7000; private static final int MAX_DEVICES = 50000; @SuppressWarnings("unused") private static final int MAX_DEVICES = 50000; private static final AtomicLong packetCount = new AtomicLong(0); private static final ExecutorService executor = Executors.newFixedThreadPool(10); private static DatagramSocket socket; private static volatile boolean isRunning = false; private static Thread receiverThread; private static final int LOCAL_PORT = PORT; // å®ä¹æ¬å°ç«¯å£ @SuppressWarnings("unused") private static final int LOCAL_PORT = PORT; // å®ä¹æ¬å°ç«¯å£ // å¯å¨æ¥æ¶å¨çéææ¹æ³ public static void startReceiver() { if (isRunning) return; @@ -37,15 +36,8 @@ String ip = packet.getAddress().getHostAddress(); int port = packet.getPort(); String hexData = bytesToHex(packet.getData(), packet.getLength()); packetCount.incrementAndGet(); // è·åå½åæ¶é´åæ¶é´æ³ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String time = sdf.format(new Date()); int timestamp = (int)(System.currentTimeMillis() / 1000); // ä¿åå°HexBaowenéå // è°ç¨æ¶æ·»å æ¬å°ç«¯å£åæ° HexBaowen.intsert(ip, hexData, time, port, LOCAL_PORT, timestamp); // è°ç¨æ¶æ·»å æ¬å°ç«¯å£åæ° PacketProcessingSystem.storePacket(ip, port, hexData); } catch (Exception e) { System.err.println("Error processing UDP-A packet: " + e.getMessage()); @@ -74,7 +66,6 @@ } // åéæ°æ®å°æå®è®¾å¤ // åéæ°æ®å°æå®è®¾å¤ public static void sendData(String ip, int port, String data, boolean isHex) { try { byte[] sendBytes; src/window/WelcomeFrame.java
@@ -1,213 +1,237 @@ package window; // å 声æ import java.awt.*; // å¯¼å ¥AWTå import java.sql.Connection; // å¯¼å ¥æ°æ®åºè¿æ¥ç±» import java.sql.ResultSet; // å¯¼å ¥ç»æéç±» import java.sql.Statement; // å¯¼å ¥SQLè¯å¥ç±» import javax.swing.*; // å¯¼å ¥Swingå import javax.swing.border.EmptyBorder; // å¯¼å ¥ç©ºè¾¹æ¡ç±» import java.util.ResourceBundle; // å¯¼å ¥èµæºæç±» import udptcp.UDPPortAReceiver; // å¯¼å ¥UDP端å£Aæ¥æ¶å¨ import udptcp.UDPPortBReceiver; // å¯¼å ¥UDP端å£Bæ¥æ¶å¨ import javax.swing.plaf.basic.BasicInternalFrameUI; // å¯¼å ¥åºç¡å 鍿¡æ¶UI package window; public class WelcomeFrame extends JInternalFrame { // æ¬¢è¿æ¡æ¶ç±» private static final long serialVersionUID = 1L; // åºååçæ¬ID private ResourceBundle messages; // æ¶æ¯èµæºæ private Connection conn; // æ°æ®åºè¿æ¥ private Timer statsTimer; // ç»è®¡å®æ¶å¨ private JLabel udpAPacketCountLabel; // UDP端å£Aå è®¡æ°æ ç¾ private JLabel udpBPacketCountLabel; // UDP端å£Bå è®¡æ°æ ç¾ private JLabel memoryUsageLabel; // å åä½¿ç¨æ ç¾ private JLabel threadCountLabel; // 线ç¨è®¡æ°æ ç¾ import java.awt.*; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.util.ResourceBundle; import udptcp.UDPPortAReceiver; import udptcp.UDPPortBReceiver; import dell_targets.Dell_BaseStation; import dell_targets.Dell_tag; import dell_targets.Dell_SystemConfiguration; public WelcomeFrame(ResourceBundle messages, Connection conn) { // æé 彿° super("", true, true, true, true); // è°ç¨ç¶ç±»æé 彿°ï¼è®¾ç½®æ é¢ä¸ºç©º this.messages = messages; // åå§åæ¶æ¯èµæºæ this.conn = conn; // åå§åæ°æ®åºè¿æ¥ public class WelcomeFrame extends JInternalFrame { private static final long serialVersionUID = 1L; private final ResourceBundle messages; private final Connection conn; private Timer statsTimer; private JLabel memoryUsageLabel; private JLabel threadCountLabel; private JLabel tagStatsLabel; private JLabel baseStationStatsLabel; private JLabel dbVersionLabel; private JLabel udpAInfoLabel; private JLabel udpBInfoLabel; public WelcomeFrame(ResourceBundle messages, Connection conn) { super("", true, true, true, true); this.messages = messages; this.conn = conn; initializeFrame(); // åå§åæ¡æ¶ setContentPane(createWelcomePanel()); // 设置å 容颿¿ startStatsTimer(); // å¯å¨ç»è®¡å®æ¶å¨ initializeFrame(); setContentPane(createWelcomePanel()); startStatsTimer(); } private void initializeFrame() { // åå§åæ¡æ¶æ¹æ³ setSize(900, 700); // è®¾ç½®æ¡æ¶å¤§å° setLocation(100, 100); // è®¾ç½®æ¡æ¶ä½ç½® setMaximizable(true); // è®¾ç½®å¯æå¤§å setIconifiable(true); // 设置å¯å¾æ å setClosable(true); // 设置å¯å ³é setBorder(null); // ç§»é¤è¾¹æ¡ setVisible(true); // 设置å¯è§ private void initializeFrame() { setSize(900, 700); setLocation(100, 100); setMaximizable(true); setIconifiable(true); setClosable(true); setBorder(null); // ç§»é¤æ 颿 BasicInternalFrameUI ui = (BasicInternalFrameUI) this.getUI(); // è·åUIç»ä»¶ ui.setNorthPane(null); // ç§»é¤æ 颿 ((javax.swing.plaf.basic.BasicInternalFrameUI)this.getUI()).setNorthPane(null); try { setMaximum(true); // å°è¯æå¤§åçªå£ setMaximum(true); } catch (java.beans.PropertyVetoException e) { e.printStackTrace(); // æå°å¼å¸¸å æ e.printStackTrace(); } setVisible(true); // ç¡®ä¿æ¡æ¶å¯è§ } private JPanel createWelcomePanel() { // å建欢è¿é¢æ¿æ¹æ³ JPanel panel = new BackgroundPanel(); // åå»ºèæ¯é¢æ¿ panel.setLayout(new BorderLayout()); // 设置边çå¸å± panel.setBorder(new EmptyBorder(30, 30, 30, 30)); // è®¾ç½®ç©ºè¾¹æ¡ private JPanel createWelcomePanel() { JPanel panel = new JPanel(new BorderLayout()); panel.setBorder(new EmptyBorder(30, 30, 30, 30)); panel.setBackground(new Color(245, 248, 255)); // å建æ é¢é¢æ¿ JPanel titlePanel = new JPanel(new BorderLayout()); // å建边çå¸å±é¢æ¿ titlePanel.setOpaque(false); // è®¾ç½®éæ // æ é¢é¢æ¿ JPanel titlePanel = new JPanel(new BorderLayout()); titlePanel.setOpaque(false); titlePanel.setBorder(new EmptyBorder(0, 0, 30, 0)); JLabel titleLabel = new JLabel(messages.getString("APP_NAME"), SwingConstants.CENTER); // å建åºç¨åç§°æ ç¾ titleLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 42)); // 设置åä½ titleLabel.setForeground(new Color(25, 25, 112)); // è®¾ç½®åæ¯è² titleLabel.setBorder(new EmptyBorder(20, 0, 20, 0)); // è®¾ç½®ç©ºè¾¹æ¡ titleLabel.setOpaque(false); // è®¾ç½®éæ JLabel titleLabel = new JLabel(messages.getString("APP_NAME"), SwingConstants.CENTER); titleLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 42)); titleLabel.setForeground(new Color(25, 25, 112)); JLabel subtitleLabel = new JLabel(messages.getString("WELCOME_MSG"), SwingConstants.CENTER); // åå»ºæ¬¢è¿æ¶æ¯æ ç¾ subtitleLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.ITALIC, 22)); // 设置åä½ subtitleLabel.setForeground(new Color(70, 130, 180)); // è®¾ç½®åæ¯è² subtitleLabel.setOpaque(false); // è®¾ç½®éæ JLabel subtitleLabel = new JLabel(messages.getString("WELCOME_MSG"), SwingConstants.CENTER); subtitleLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.ITALIC, 22)); subtitleLabel.setForeground(new Color(70, 130, 180)); subtitleLabel.setBorder(new EmptyBorder(10, 0, 20, 0)); titlePanel.add(titleLabel, BorderLayout.NORTH); // æ·»å æ é¢å°åé¨ titlePanel.add(subtitleLabel, BorderLayout.CENTER); // æ·»å 坿 é¢å°ä¸é¨ titlePanel.add(titleLabel, BorderLayout.NORTH); titlePanel.add(subtitleLabel, BorderLayout.CENTER); // å建信æ¯é¢æ¿ JPanel infoPanel = new JPanel(new GridLayout(0, 2, 20, 20)); // åå»ºç½æ ¼å¸å±é¢æ¿ infoPanel.setBorder(new EmptyBorder(30, 50, 30, 50)); // è®¾ç½®ç©ºè¾¹æ¡ infoPanel.setBackground(new Color(255, 255, 255, 180)); // 设置åéæç½è²èæ¯ infoPanel.setOpaque(true); // 设置ä¸éæ // 主信æ¯é¢æ¿ JPanel infoPanel = new JPanel(new GridBagLayout()); infoPanel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(new Color(200, 220, 240), 2), new EmptyBorder(30, 40, 30, 40) )); infoPanel.setBackground(new Color(255, 255, 255, 255)); infoPanel.setOpaque(true); // æ·»å ç³»ç»ç¶æä¿¡æ¯ infoPanel.add(createInfoLabel(messages.getString("SYSTEM_STATUS"), messages.getString("RUNNING_NORMAL"), new Color(0, 100, 0))); // æ·±ç»¿è² GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(15, 15, 15, 15); gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.HORIZONTAL; // æ·»å æ°æ®åºè¿æ¥ä¿¡æ¯ infoPanel.add(createInfoLabel(messages.getString("DB_CONNECTION"), conn != null ? messages.getString("CONNECTED") : messages.getString("DISCONNECTED"), conn != null ? new Color(0, 100, 0) : Color.RED)); // è¿æ¥æå绿è²/å¤±è´¥çº¢è² // 第ä¸å gbc.gridx = 0; gbc.gridy = 0; try { if (conn != null) { // æ£æ¥æ°æ®åºè¿æ¥ try (Statement stmt = conn.createStatement(); // å建è¯å¥ ResultSet rs = stmt.executeQuery("SELECT VERSION()")) { // æ§è¡çæ¬æ¥è¯¢ if (rs.next()) { // 妿æç»æ infoPanel.add(createInfoLabel(messages.getString("DB_VERSION"), rs.getString(1), new Color(25, 25, 112))); // æ·»å æ°æ®åºçæ¬ } } } } catch (Exception e) { e.printStackTrace(); // æå°å¼å¸¸ // ä¿®å¤1: åå§åæ ç¾å¹¶è®¾ç½®åå§ææ¬ tagStatsLabel = new JLabel("0 / 0"); tagStatsLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("TAG_STATS"), tagStatsLabel, new Color(0, 100, 0)), gbc); gbc.gridy++; baseStationStatsLabel = new JLabel("0 / 0"); baseStationStatsLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("BASE_STATION_STATS"), baseStationStatsLabel, new Color(0, 100, 0)), gbc); gbc.gridy++; udpAInfoLabel = new JLabel(Dell_SystemConfiguration.hexport + " - " + messages.getString("RECEIVED_PACKETS") + ": 0"); udpAInfoLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("UDP_PORT_A"), udpAInfoLabel, new Color(178, 34, 34)), gbc); gbc.gridy++; udpBInfoLabel = new JLabel(Dell_SystemConfiguration.ascallport + " - " + messages.getString("RECEIVED_PACKETS") + ": 0"); udpBInfoLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("UDP_PORT_B"), udpBInfoLabel, new Color(178, 34, 34)), gbc); gbc.gridy++; memoryUsageLabel = new JLabel("0 MB / 0 MB"); memoryUsageLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("MEMORY_USAGE"), memoryUsageLabel, new Color(148, 0, 211)), gbc); // 第äºå gbc.gridx = 1; gbc.gridy = 0; threadCountLabel = new JLabel("0"); threadCountLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("THREAD_COUNT"), threadCountLabel, new Color(148, 0, 211)), gbc); gbc.gridy++; dbVersionLabel = new JLabel(""); // åå§ä¸ºç©ºï¼ç¨å设置 dbVersionLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("DB_VERSION"), dbVersionLabel, new Color(25, 25, 112)), gbc); gbc.gridy++; JLabel dbStatusLabel = new JLabel(conn != null ? messages.getString("CONNECTED") : messages.getString("DISCONNECTED")); dbStatusLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); dbStatusLabel.setForeground(conn != null ? new Color(0, 100, 0) : Color.RED); infoPanel.add(createInfoRow(messages.getString("DB_STATUS"), dbStatusLabel, new Color(25, 25, 112)), gbc); gbc.gridy++; JLabel softwareVersionLabel = new JLabel(messages.getString("APP_VERSION")); softwareVersionLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("SOFTWARE_VERSION"), softwareVersionLabel, new Color(25, 25, 112)), gbc); // åå§åæ°æ®åºçæ¬ if (conn != null && dbVersionLabel.getText().isEmpty()) { updateDbVersion(); } // æ·»å å½åç¨æ·ä¿¡æ¯ infoPanel.add(createInfoLabel(messages.getString("CURRENT_USER"), messages.getString("ADMIN"), new Color(25, 25, 112))); // æ·±èè² // æ·»å ç³»ç»æ¶é´ä¿¡æ¯ infoPanel.add(createInfoLabel(messages.getString("SYSTEM_TIME"), new java.util.Date().toString(), new Color(25, 25, 112))); // æ·±èè² // æ·»å UDP端å£Aç»è®¡ infoPanel.add(createInfoLabel(messages.getString("UDP_PORT_A"), "0", new Color(178, 34, 34))); // ç çº¢è² udpAPacketCountLabel = createInfoLabel("", "", new Color(178, 34, 34)); // åå»ºè®¡æ°æ ç¾ infoPanel.add(udpAPacketCountLabel); // æ·»å è®¡æ°æ ç¾ // æ·»å UDP端å£Bç»è®¡ infoPanel.add(createInfoLabel(messages.getString("UDP_PORT_B"), "0", new Color(178, 34, 34))); // ç çº¢è² udpBPacketCountLabel = createInfoLabel("", "", new Color(178, 34, 34)); // åå»ºè®¡æ°æ ç¾ infoPanel.add(udpBPacketCountLabel); // æ·»å è®¡æ°æ ç¾ // æ·»å å å使ç¨ç»è®¡ infoPanel.add(createInfoLabel(messages.getString("MEMORY_USAGE"), "", new Color(148, 0, 211))); // ç´«ç½å °è² memoryUsageLabel = createInfoLabel("", "", new Color(148, 0, 211)); // å建å åæ ç¾ infoPanel.add(memoryUsageLabel); // æ·»å å åæ ç¾ // æ·»å 线ç¨è®¡æ°ç»è®¡ infoPanel.add(createInfoLabel(messages.getString("THREAD_COUNT"), "", new Color(148, 0, 211))); // ç´«ç½å °è² threadCountLabel = createInfoLabel("", "", new Color(148, 0, 211)); // åå»ºçº¿ç¨æ ç¾ infoPanel.add(threadCountLabel); // æ·»å çº¿ç¨æ ç¾ // åå»ºç¶æé¢æ¿ JPanel statsPanel = new JPanel(new GridLayout(1, 4, 15, 15)); // åå»ºç½æ ¼å¸å±é¢æ¿ statsPanel.setBorder(new EmptyBorder(20, 50, 10, 50)); // è®¾ç½®ç©ºè¾¹æ¡ statsPanel.setOpaque(false); // è®¾ç½®éæ // æ·»å ç»è®¡çå statsPanel.add(createStatBox(messages.getString("UDP_PORT_A_STAT"), udpAPacketCountLabel)); // UDP端å£Aç»è®¡ statsPanel.add(createStatBox(messages.getString("UDP_PORT_B_STAT"), udpBPacketCountLabel)); // UDP端å£Bç»è®¡ statsPanel.add(createStatBox(messages.getString("MEMORY_USAGE_STAT"), memoryUsageLabel)); // å å使ç¨ç»è®¡ statsPanel.add(createStatBox(messages.getString("THREAD_COUNT_STAT"), threadCountLabel)); // 线ç¨è®¡æ°ç»è®¡ // ç»è£ 䏻颿¿ panel.add(titlePanel, BorderLayout.NORTH); // æ·»å æ é¢é¢æ¿å°åé¨ panel.add(infoPanel, BorderLayout.CENTER); // æ·»å ä¿¡æ¯é¢æ¿å°ä¸é¨ panel.add(statsPanel, BorderLayout.SOUTH); // æ·»å ç¶æé¢æ¿å°åé¨ panel.add(titlePanel, BorderLayout.NORTH); panel.add(infoPanel, BorderLayout.CENTER); return panel; // è¿å颿¿ return panel; } private JLabel createInfoLabel(String title, String value, Color color) { // åå»ºä¿¡æ¯æ ç¾æ¹æ³ JLabel label = new JLabel("<html><div style='text-align:center;'><b>" + title + "</b><br>" + value + "</div></html>"); // å建带HTMLæ ¼å¼çæ ç¾ label.setFont(new Font(messages.getString("FONT_NAME"), Font.PLAIN, 16)); // 设置åä½ label.setForeground(color); // è®¾ç½®åæ¯è² label.setHorizontalAlignment(SwingConstants.CENTER); // è®¾ç½®æ°´å¹³å± ä¸ label.setVerticalAlignment(SwingConstants.CENTER); // 设置åç´å± ä¸ label.setOpaque(false); // è®¾ç½®éæ return label; // è¿åæ ç¾ private JPanel createInfoRow(String title, JLabel valueLabel, Color color) { JPanel rowPanel = new JPanel(new BorderLayout(10, 0)); rowPanel.setOpaque(false); JLabel titleLabel = new JLabel(title + ":"); titleLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); titleLabel.setForeground(color.darker()); valueLabel.setForeground(color); rowPanel.add(titleLabel, BorderLayout.WEST); rowPanel.add(valueLabel, BorderLayout.CENTER); // æ·»å è£ é¥°å¨ JPanel decorator = new JPanel(); decorator.setPreferredSize(new Dimension(5, 5)); decorator.setBackground(color); decorator.setOpaque(true); rowPanel.add(decorator, BorderLayout.EAST); return rowPanel; } private JPanel createStatBox(String title, JLabel valueLabel) { // å建ç»è®¡çåæ¹æ³ JPanel boxPanel = new JPanel(new BorderLayout()); // å建边çå¸å±é¢æ¿ boxPanel.setBorder(BorderFactory.createCompoundBorder( // 设置å¤åè¾¹æ¡ BorderFactory.createLineBorder(new Color(70, 130, 180), 2), // èè²è¾¹æ¡ new EmptyBorder(15, 10, 15, 10) // å è¾¹è· )); boxPanel.setBackground(new Color(240, 248, 255, 220)); // 设置åéæèæ¯ boxPanel.setOpaque(true); // 设置ä¸éæ JLabel titleLabel = new JLabel(title, SwingConstants.CENTER); // å建æ 颿 ç¾ titleLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); // 设置ç²ä½ titleLabel.setForeground(new Color(25, 25, 112)); // 设置深èè² valueLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 24)); // 设置ç²ä½å¤§åå· valueLabel.setHorizontalAlignment(SwingConstants.CENTER); // è®¾ç½®å± ä¸ boxPanel.add(titleLabel, BorderLayout.NORTH); // æ·»å æ é¢å°åé¨ boxPanel.add(valueLabel, BorderLayout.CENTER); // æ·»å 弿 ç¾å°ä¸é¨ return boxPanel; // è¿å颿¿ private void updateDbVersion() { if (conn != null) { try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT VERSION()")) { if (rs.next()) { dbVersionLabel.setText(rs.getString(1)); } } catch (Exception ex) { dbVersionLabel.setText("N/A"); } } } private void startStatsTimer() { // å¯å¨ç»è®¡å®æ¶å¨æ¹æ³ statsTimer = new Timer(1000, e -> { // å建1ç§é´éç宿¶å¨ // æ´æ°UDPæ°æ®å è®¡æ° udpAPacketCountLabel.setText(String.valueOf(UDPPortAReceiver.getPacketCount())); // æ´æ°ç«¯å£Aè®¡æ° udpBPacketCountLabel.setText(String.valueOf(UDPPortBReceiver.getPacketCount())); // æ´æ°ç«¯å£Bè®¡æ° private void startStatsTimer() { statsTimer = new Timer(1000, e -> { // æ´æ°UDP端å£Aä¿¡æ¯ int packetCountA = (int) UDPPortAReceiver.getPacketCount(); udpAInfoLabel.setText(Dell_SystemConfiguration.hexport + " - " + messages.getString("RECEIVED_PACKETS") + ": " + packetCountA); // æ´æ°UDP端å£Bä¿¡æ¯ int packetCountB = (int) UDPPortBReceiver.getPacketCount(); udpBInfoLabel.setText(Dell_SystemConfiguration.ascallport + " - " + messages.getString("RECEIVED_PACKETS") + ": " + packetCountB); // æ´æ°å åä½¿ç¨æ åµ Runtime runtime = Runtime.getRuntime(); // è·åè¿è¡æ¶å®ä¾ long usedMemory = (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024); // 计ç®å·²ç¨å å(MB) long maxMemory = runtime.maxMemory() / (1024 * 1024); // è®¡ç®æå¤§å å(MB) memoryUsageLabel.setText(usedMemory + " " + messages.getString("MB") + " / " + maxMemory + " " + messages.getString("MB")); // 设置å åææ¬ Runtime runtime = Runtime.getRuntime(); long usedMemory = (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024); long maxMemory = runtime.maxMemory() / (1024 * 1024); memoryUsageLabel.setText(usedMemory + " " + messages.getString("MB") + " / " + maxMemory + " " + messages.getString("MB")); // æ´æ°çº¿ç¨æ°é threadCountLabel.setText(String.valueOf(Thread.activeCount())); // 设置活å¨çº¿ç¨æ° // æ´æ°çº¿ç¨æ° threadCountLabel.setText(String.valueOf(Thread.activeCount())); // æ´æ°æ ç¾ç¶æ int onlineTags = Dell_tag.getOnlineLocationTags().size(); int totalTags = Dell_tag.getLocationTagCount(); tagStatsLabel.setText(onlineTags + " / " + totalTags); // æ´æ°åºç«ç¶æ int onlineStations = Dell_BaseStation.getOnlineBaseStations().size(); int totalStations = Dell_BaseStation.getLocationBaseCount(); baseStationStatsLabel.setText(onlineStations + " / " + totalStations); }); statsTimer.start(); // å¯å¨å®æ¶å¨ statsTimer.start(); } @Override public void dispose() { // éæ¯æ¹æ³ super.dispose(); // è°ç¨ç¶ç±»éæ¯ if (statsTimer != null) { // æ£æ¥å®æ¶å¨ statsTimer.stop(); // 忢宿¶å¨ public void dispose() { super.dispose(); if (statsTimer != null) { statsTimer.stop(); } } } src/window/Windows.java
@@ -17,6 +17,7 @@ import dell_map.Dell_Map; import dell_map.MapViewer; import dell_targets.Dell_SystemConfiguration; import targets.Mapdata; public class Windows extends JFrame { @@ -82,6 +83,16 @@ createLanguageMenu(); } // æ°å¢æ¹æ³ï¼æ ¹æ®ç³»ç»é ç½®è·åå½åè¯è¨ç¯å¢ public Locale getSystemLocale() { return "1".equals(Dell_SystemConfiguration.language) ? Locale.ENGLISH : Locale.SIMPLIFIED_CHINESE; } // æ°å¢æ¹æ³ï¼ä¾å ¶ä»ç±»è·åå½åè¯è¨ç¯å¢ public Locale getCurrentLocale() { return this.currentLocale; } private ResourceBundle loadResourceBundle(Locale locale) { String fileName = locale.equals(Locale.ENGLISH) ? systemfile/Messages_en.properties
@@ -1,3 +1,26 @@ TAG_STATS = Tag Statistics BASE_STATION_STATS = Base Station Statistics SOFTWARE_VERSION = Software Version APP_VERSION = 1.0.0 UDP_PORT_A = UDP Receive Port A UDP_PORT_B = UDP Receive Port B DB_VERSION = Database Version DB_STATUS = Database Status RECEIVED_PACKETS=Received # New message viewing related resources MESSAGE_VIEW_ALL_TYPES=All Types MESSAGE_VIEW_UDP_PORT_A=UDP Port A MESSAGE_VIEW_UDP_PORT_B=UDP Port B MESSAGE_VIEW_TCP_PORT=TCP Port MESSAGE_VIEW_MQTT_PORT=MQTT Port MESSAGE_VIEW_ALL_DEVICES=All Devices MESSAGE_VIEW_ALL_PROTOCOLS=All Protocols MESSAGE_VIEW_SHOW_DATA=Show Data MESSAGE_VIEW_DATA_SOURCE=Data Source MESSAGE_VIEW_FILTERED_DATA=Filtered Data MESSAGE_VIEW_HEX_FORMAT=HEX Format MESSAGE_VIEW_ASCII_FORMAT=ASCII Format MESSAGE_VIEW_MIXED_FORMAT=Mixed Format # New Resource Key-Value Pairs packet.count.format=Packets Received: %d label.id=Label ID systemfile/Messages_zh.properties
@@ -1,3 +1,26 @@ TAG_STATS=æ ç¾ç»è®¡ BASE_STATION_STATS=åºç«ç»è®¡ SOFTWARE_VERSION=è½¯ä»¶çæ¬ APP_VERSION=1.0.0 UDP_PORT_A=æ°æ®æ¥æ¶ç«¯å£ UDP_PORT_B=æ°æ®æ¥æ¶ç«¯å£ DB_VERSION=æ°æ®åºçæ¬ DB_STATUS=æ°æ®åºç¶æ RECEIVED_PACKETS=æ¥æ¶ # æ°å¢çæ¥ææ¥çç¸å ³èµæº MESSAGE_VIEW_ALL_TYPES=ææç±»å MESSAGE_VIEW_UDP_PORT_A=UDP端å£A MESSAGE_VIEW_UDP_PORT_B=UDP端å£B MESSAGE_VIEW_TCP_PORT=TCPç«¯å£ MESSAGE_VIEW_MQTT_PORT=MQTTç«¯å£ MESSAGE_VIEW_ALL_DEVICES=ææè®¾å¤ MESSAGE_VIEW_ALL_PROTOCOLS=ææåè®® MESSAGE_VIEW_SHOW_DATA=æ¾ç¤ºæ°æ® MESSAGE_VIEW_DATA_SOURCE=æ°æ®æ¥æº MESSAGE_VIEW_FILTERED_DATA=å·²è¿æ»¤æ°æ® MESSAGE_VIEW_HEX_FORMAT=HEXæ ¼å¼ MESSAGE_VIEW_ASCII_FORMAT=ASCIIæ ¼å¼ MESSAGE_VIEW_MIXED_FORMAT=æ··åæ ¼å¼ # æ°å¢èµæºé®å¼å¯¹ packet.count.format=æ¶å°æ°æ®:%dæ¡ label.id=æ ç¾ç¼å· @@ -469,8 +492,6 @@ MESSAGE_VIEW_EMPTY_DATA=åéå 容ä¸è½ä¸ºç©º ERROR=é误 # 欢è¿çé¢çæ§ UDP_PORT_A=UDP端å£A (8234) UDP_PORT_B=UDP端å£B (7000) MEMORY_USAGE=å åä½¿ç¨ THREAD_COUNT=çº¿ç¨æ°é MB=MB systemfile/logfile/openlog.txt
@@ -634,3 +634,150 @@ ç¨åºå ³é: 2025-08-08 23:06:23 工使¶é¿: 0å°æ¶ 0åé 41ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 10:43:53 ç¨åºå ³é: 2025-08-09 15:09:35 工使¶é¿: 4å°æ¶ 25åé 41ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 15:09:38 ç¨åºå ³é: 2025-08-09 15:09:41 工使¶é¿: 0å°æ¶ 0åé 2ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 15:21:34 ç¨åºå¯å¨: 2025-08-09 15:26:45 ç¨åºå ³é: 2025-08-09 15:26:49 工使¶é¿: 0å°æ¶ 5åé 15ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 15:26:51 ç¨åºå¯å¨: 2025-08-09 15:28:12 ç¨åºå ³é: 2025-08-09 15:29:23 工使¶é¿: 0å°æ¶ 1åé 10ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 15:29:25 ç¨åºå ³é: 2025-08-09 15:30:53 工使¶é¿: 0å°æ¶ 1åé 27ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 15:30:55 ç¨åºå ³é: 2025-08-09 15:31:19 工使¶é¿: 0å°æ¶ 0åé 23ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 15:31:22 ç¨åºå ³é: 2025-08-09 15:36:19 工使¶é¿: 0å°æ¶ 4åé 57ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 15:36:21 ç¨åºå ³é: 2025-08-09 15:38:36 工使¶é¿: 0å°æ¶ 2åé 15ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 15:38:39 ç¨åºå ³é: 2025-08-09 16:03:25 工使¶é¿: 0å°æ¶ 24åé 46ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 16:03:28 ç¨åºå ³é: 2025-08-09 16:03:42 工使¶é¿: 0å°æ¶ 0åé 14ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 16:13:27 ç¨åºå ³é: 2025-08-09 16:16:14 工使¶é¿: 0å°æ¶ 2åé 46ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 16:16:17 ç¨åºå ³é: 2025-08-09 16:16:37 工使¶é¿: 0å°æ¶ 0åé 19ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 16:19:34 ç¨åºå ³é: 2025-08-09 16:21:03 工使¶é¿: 0å°æ¶ 1åé 29ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 16:21:05 ç¨åºå ³é: 2025-08-09 16:22:09 工使¶é¿: 0å°æ¶ 1åé 3ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 16:22:10 ç¨åºå ³é: 2025-08-09 16:28:22 工使¶é¿: 0å°æ¶ 6åé 11ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 16:28:24 ç¨åºå ³é: 2025-08-09 16:32:37 工使¶é¿: 0å°æ¶ 4åé 12ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 16:32:39 ç¨åºå ³é: 2025-08-09 20:05:40 工使¶é¿: 3å°æ¶ 33åé 1ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 20:07:08 ç¨åºå ³é: 2025-08-09 20:11:43 工使¶é¿: 0å°æ¶ 4åé 35ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 20:11:46 ç¨åºå ³é: 2025-08-09 21:57:03 工使¶é¿: 1å°æ¶ 45åé 17ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 21:57:05 ç¨åºå ³é: 2025-08-09 22:02:50 工使¶é¿: 0å°æ¶ 5åé 44ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 22:12:39 ç¨åºå ³é: 2025-08-09 22:21:24 工使¶é¿: 0å°æ¶ 8åé 45ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 22:21:26 ç¨åºå ³é: 2025-08-09 22:31:29 工使¶é¿: 0å°æ¶ 10åé 2ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 22:31:30 ç¨åºå ³é: 2025-08-09 22:31:44 工使¶é¿: 0å°æ¶ 0åé 13ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 22:31:59 ç¨åºå ³é: 2025-08-09 22:44:51 工使¶é¿: 0å°æ¶ 12åé 52ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 22:44:53 ç¨åºå ³é: 2025-08-09 22:44:55 工使¶é¿: 0å°æ¶ 0åé 1ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 22:45:33 ç¨åºå ³é: 2025-08-09 22:45:35 工使¶é¿: 0å°æ¶ 0åé 1ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 22:46:58 ç¨åºå ³é: 2025-08-09 22:49:10 工使¶é¿: 0å°æ¶ 2åé 12ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 22:49:12 ç¨åºå ³é: 2025-08-09 22:58:17 工使¶é¿: 0å°æ¶ 9åé 4ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 22:58:19 ç¨åºå ³é: 2025-08-09 23:09:45 工使¶é¿: 0å°æ¶ 11åé 25ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 23:09:47 ç¨åºå ³é: 2025-08-09 23:19:34 工使¶é¿: 0å°æ¶ 9åé 46ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 23:19:36 ç¨åºå ³é: 2025-08-09 23:19:51 工使¶é¿: 0å°æ¶ 0åé 14ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 23:20:10 ç¨åºå ³é: 2025-08-09 23:20:15 工使¶é¿: 0å°æ¶ 0åé 5ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 23:21:01 ç¨åºå ³é: 2025-08-09 23:21:05 工使¶é¿: 0å°æ¶ 0åé 4ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 23:24:49 ç¨åºå ³é: 2025-08-09 23:29:56 工使¶é¿: 0å°æ¶ 5åé 6ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 23:29:58 ç¨åºå ³é: 2025-08-09 23:30:36 工使¶é¿: 0å°æ¶ 0åé 38ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 23:30:38 ç¨åºå ³é: 2025-08-09 23:30:52 工使¶é¿: 0å°æ¶ 0åé 14ç§ ----------------------------------- ç¨åºå¯å¨: 2025-08-09 23:30:58