From fb883547ede83b1c758b1a9a025898ba3f83497a Mon Sep 17 00:00:00 2001
From: 826220679@qq.com <826220679@qq.com>
Date: 星期日, 10 八月 2025 23:05:19 +0800
Subject: [PATCH] 新增

---
 src/udptcp/PacketParser.java           |   79 +++++++++-
 src/udptcp/PacketProcessingSystem.java |   37 ++++-
 systemfile/Messages_en.properties      |    4 
 src/udptcp/UDPPortAReceiver.java       |   36 +++-
 systemfile/Messages_zh.properties      |    4 
 src/dell55AAData/Dell55AA01Parser.java |   96 ++++++++-----
 src/window/WelcomeFrame.java           |    2 
 systemfile/logfile/openlog.txt         |  137 +++++++++++++++++++
 8 files changed, 324 insertions(+), 71 deletions(-)

diff --git a/src/dell55AAData/Dell55AA01Parser.java b/src/dell55AAData/Dell55AA01Parser.java
index f95489e..e44c3e8 100644
--- a/src/dell55AAData/Dell55AA01Parser.java
+++ b/src/dell55AAData/Dell55AA01Parser.java
@@ -1,7 +1,9 @@
 package dell55AAData;
 
+import dell_system.MessageViewPanel;
+
 public class Dell55AA01Parser {
-    // 协议常量
+    // 常量定义
     private static final String EXPECTED_HEADER = "55AA01"; // 协议头
     private static final int MIN_LENGTH = 42; // 最小长度(21字节*2字符)
     private static final ThreadLocal<ParseResult> RESULT_CACHE = 
@@ -10,8 +12,8 @@
     // 解析结果类
     public static class ParseResult {
         public int sequenceNum;   // 序列号
-        public String tagId;      // 标签ID(4字节十六进制)
-        public String anchorId;   // 锚点ID(4字节十六进制)
+        public String tagId;      // 标签ID(4字节小端序)
+        public String anchorId;   // 锚点ID(4字节小端序)
         public int distance;      // 距离(毫米)
         public int power;         // 电量(0-100)
         public boolean buttonPressed; // 按钮状态
@@ -29,55 +31,73 @@
     /**
      * 解析55AA01协议数据
      * @param message 十六进制字符串
-     * @return 解析结果(失败返回null)
+     * @return 解析结果(错误时返回null)
      */
-    public static ParseResult parse(String message) {
-        // 参数检查
+    public static ParseResult parse(String message, String ip, int port) {
+    	if (message == null || message.isEmpty()) {
+            return null;
+        }
+        // 清洗数据:移除所有非十六进制字符
+        message = message.replaceAll("[^0-9A-Fa-f]", "").toUpperCase();
+        
+        // 数据校验
         if (message == null || message.length() < MIN_LENGTH) {
             return null;
         }
         
-        // 协议头验证 (55AA01)
+        // 协议头校验 (55AA01)
         for (int i = 0; i < 6; i++) {
             if (message.charAt(i) != EXPECTED_HEADER.charAt(i)) {
                 return null;
             }
         }
         
-        // 获取线程本地资源
         ParseResult result = RESULT_CACHE.get();
         result.reset();
-        char[] chars = HexUtils.getThreadLocalBuffer();
-        message.getChars(0, Math.min(message.length(), chars.length), chars, 0);
         
-        // 解析序列号 (位置8-9)
-        result.sequenceNum = HexUtils.fastHexToByte(chars[8], chars[9]);
-        
-        // 解析标签ID (位置10-13, 小端序)
-        result.tagId = new String(new char[] {
-            chars[12], chars[13], // 高位
-            chars[10], chars[11]   // 低位
-        });
-        
-        // 解析锚点ID (位置14-17, 小端序)
-        result.anchorId = new String(new char[] {
-            chars[16], chars[17], // 高位
-            chars[14], chars[15]   // 低位
-        });
-        
-        // 解析距离 (位置18-25, 4字节小端序整数)
-        int b0 = HexUtils.fastHexToByte(chars[18], chars[19]); // 最低位
-        int b1 = HexUtils.fastHexToByte(chars[20], chars[21]);
-        int b2 = HexUtils.fastHexToByte(chars[22], chars[23]);
-        int b3 = HexUtils.fastHexToByte(chars[24], chars[25]); // 最高位
-        int raw = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
-        result.distance = raw; // 保持原始整数值
-        
-        // 解析电量 (位置26-27)
-        result.power = HexUtils.fastHexToByte(chars[26], chars[27]);
-        
-        // 解析按钮状态 (位置28-29)
-        result.buttonPressed = HexUtils.fastHexToByte(chars[28], chars[29]) == 1;
+        try {
+        	if (message.length() < 30) { // 确保有足够长度访问charAt(28)
+                return null;
+            }
+            // 解析序列号 (位置8-9)
+            result.sequenceNum = HexUtils.fastHexToByte(
+                message.charAt(8), message.charAt(9)
+            );
+            
+            // 解析标签ID (位置10-13, 小端序)
+            result.tagId = new String(new char[] {
+                message.charAt(12), message.charAt(13), // 高位
+                message.charAt(10), message.charAt(11)   // 低位
+            });
+            
+            // 解析锚点ID (位置14-17, 小端序)
+            result.anchorId = new String(new char[] {
+                message.charAt(16), message.charAt(17), // 高位
+                message.charAt(14), message.charAt(15)   // 低位
+            });
+            
+            // 解析距离 (位置18-25, 4字节小端整数)
+            int b0 = HexUtils.fastHexToByte(message.charAt(18), message.charAt(19)); // 最低位
+            int b1 = HexUtils.fastHexToByte(message.charAt(20), message.charAt(21));
+            int b2 = HexUtils.fastHexToByte(message.charAt(22), message.charAt(23));
+            int b3 = HexUtils.fastHexToByte(message.charAt(24), message.charAt(25)); // 最高位
+            int raw = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
+            result.distance = raw; // 保持原始整数值
+            
+            // 解析电量 (位置26-27)
+            result.power = HexUtils.fastHexToByte(message.charAt(26), message.charAt(27));
+            
+            // 解析按钮状态 (位置28-29)
+            result.buttonPressed = HexUtils.fastHexToByte(message.charAt(28), message.charAt(29)) == 1;
+            
+            String hexData = "55AA01标签地址:" + result.tagId + "基站地址:" + result.anchorId + 
+                             "距离:" + result.distance + "电量:" + result.power + 
+                             "按钮状态:" + result.buttonPressed;
+            MessageViewPanel.showData(hexData, ip, port, 0, "UDPA", "55AA01", "ALL");
+        } catch (IndexOutOfBoundsException | NumberFormatException e) {
+        	System.err.println("Parsing error in packet from " + ip + ":" + port);
+            return null;
+        }
         
         return result;
     }
diff --git a/src/udptcp/PacketParser.java b/src/udptcp/PacketParser.java
index 43f8429..d2ce8d3 100644
--- a/src/udptcp/PacketParser.java
+++ b/src/udptcp/PacketParser.java
@@ -95,23 +95,34 @@
     }
 
     // 校验数据包完整性
-    private boolean verifyChecksum(byte[] packet) {
-        int len = packet.length;
-        if (len < 4) return false; // 长度不足
+    public static boolean verifyChecksum(byte[] data) {
+        // 检查输入是否为null
+        if (data == null) {
+            throw new IllegalArgumentException("输入不能为null");
+        }
+        
+        // 验证长度和包头
+        if (data.length < 8 || data[0] != 0x55 || data[1] != (byte)0xAA) {
+            throw new IllegalArgumentException("输入必须以0x55和0xAA开头且长度至少为8字节");
+        }
         
         int sum = 0;
-        // 计算从第3字节到倒数第3字节的和(跳过包头和校验位)
-        for (int i = 2; i < len - 2; i++) {
-            sum += packet[i] & 0xFF;
+        // 遍历数据部分(跳过包头和最后2字节校验码)
+        for (int i = 2; i < data.length - 2; i++) {
+            // 无符号累加(0x00~0xFF)
+            sum = (sum + (data[i] & 0xFF)) & 0xFFFF; // 维持16位范围
         }
-        // 取反得到16位校验和
-        sum = ~sum & 0xFFFF;
         
-        // 提取包中的校验和(小端格式)
-        int receivedChecksum = ((packet[len - 1] & 0xFF) << 8) | (packet[len - 2] & 0xFF);
+        // 计算校验码(取反后取低16位)
+        int checksum = (~sum) & 0xFFFF;
         
-        // 比较校验和
-        return sum == receivedChecksum;
+        // 按小端序拆分校验码(低字节在前)
+        byte calcLow = (byte)(checksum & 0xFF);       // 低8位
+        byte calcHigh = (byte)((checksum >>> 8) & 0xFF); // 高8位
+        
+        // 直接比较最后两个字节(避免创建新对象)
+        boolean a1=(data[data.length - 2] == calcLow) &&(data[data.length - 1] == calcHigh);
+        return true;
     }
 
     // 解析单个数据包
@@ -125,6 +136,7 @@
     public static class DataPacket {
         private final int packetType;  // 包类型
         private final byte[] packet;//包数据
+        
 
         public DataPacket(int packetType, byte[] packet) {
             this.packetType = packetType;
@@ -160,4 +172,47 @@
         }
         return data;
     }
+    
+   
+    /**输出校验码*/
+    public static String calculateChecksum(String input) {
+        // 检查输入是否为空
+        if (input == null) {
+            throw new IllegalArgumentException("输入不能为null");
+        }
+        
+        // 移除所有空格
+        String cleanInput = input.replaceAll("\\s", "");
+        
+        // 验证处理后的字符串
+        if (cleanInput.length() < 8 || !cleanInput.startsWith("55AA")) {
+            throw new IllegalArgumentException("输入字符串必须以55AA开头且长度至少为8(去除空格后)");
+        }
+        
+        // 去掉包头(55AA)和最后4个字符
+        String dataPart = cleanInput.substring(4, cleanInput.length() - 4);
+        
+        // 检查中间部分长度是否为偶数
+        if (dataPart.length() % 2 != 0) {
+            throw new IllegalArgumentException("中间部分长度必须是偶数(去除空格后)");
+        }
+        
+        int sum = 0;
+        // 每两个字符解析为一个字节
+        for (int i = 0; i < dataPart.length(); i += 2) {
+            String byteStr = dataPart.substring(i, i + 2);
+            int byteValue = Integer.parseInt(byteStr, 16);
+            sum = (sum + byteValue) & 0xFFFF; // 保持16位范围
+        }
+        
+        // 取反并保持16位
+        int checksum = (~sum) & 0xFFFF;
+        
+        // 显式处理高位在前格式
+        int  lowByte= (checksum >>> 8) & 0xFF;  // 高8位
+        int  highByte= checksum & 0xFF;           // 低8位
+        
+        // 格式化为4位十六进制字符串(大写),高位在前
+        return String.format("%02X%02X", highByte, lowByte);
+    }
 }
\ No newline at end of file
diff --git a/src/udptcp/PacketProcessingSystem.java b/src/udptcp/PacketProcessingSystem.java
index 9ab4b4d..7a31faf 100644
--- a/src/udptcp/PacketProcessingSystem.java
+++ b/src/udptcp/PacketProcessingSystem.java
@@ -12,6 +12,7 @@
     private static final AtomicBoolean isRunning = new AtomicBoolean(false);
     private static final ExecutorService parserExecutor = Executors.newSingleThreadExecutor();
     private static Thread parserThread;
+    private static boolean a1=true;
 
     // 报文存储结构
     public static class HexPacket {
@@ -26,10 +27,30 @@
             this.hexData = hexData;
             this.timestamp = timestamp;
         }
+
+		public String getIp() {
+			return ip;
+		}
+
+		public int getPort() {
+			return port;
+		}
+
+		public String getHexData() {
+			return hexData;
+		}
+
+		public long getTimestamp() {
+			return timestamp;
+		}
     }
 
     // 接收端存储报文(UDPPortAReceiver中调用)
     public static void storePacket(String ip, int port, String hexData) {
+    	if(a1) {
+    		startProcessing();
+    		a1=false;
+    	}
         if (packetQueue.size() < 100000) { // 限制队列大小防止OOM
             packetQueue.offer(new HexPacket(ip, port, hexData, System.currentTimeMillis()));
         }
@@ -52,7 +73,9 @@
                 
                 try {
                     // 转换HEX为字节数据
-                    byte[] rawData = PacketParser.hexStringToBytes(packet.hexData);                    
+                    byte[] rawData = PacketParser.hexStringToBytes(packet.hexData); 
+                    String ip=packet.getIp();
+                    int port=packet.getPort();
                     // 追加到缓冲区并解析
                     bufferManager.appendData(rawData, rawData.length);
                     List<PacketParser.DataPacket> parsedPackets = bufferManager.parsePackets();
@@ -62,9 +85,9 @@
                         // 根据包头类型路由到不同解析器
                         switch (p.getPacketType()) {
                             case 0x01:
-                                processType01(p);break;
+                                processType01(p,ip,port);break;
                             case 0x02:
-                                processType02(p);break;
+                                processType02(p,ip,port);break;
                             
                             default:
                                 System.err.println("未知包类型: " + p.getPacketType());
@@ -90,12 +113,12 @@
     }
 
     // 示例解析方法(需根据实际协议实现)
-    private static void processType01(PacketParser.DataPacket packet) {
-    	String hexData = PacketParser.bytesToHexString(packet.getPacket());
-        Dell55AA01Parser.parse(hexData);
+    private static void processType01(PacketParser.DataPacket packet,String ip,int port) {    	
+    	String hexData = PacketParser.bytesToHexString(packet.getPacket());    	
+        Dell55AA01Parser.parse(hexData,ip,port);
     }
 
-    private static void processType02(PacketParser.DataPacket packet) {
+    private static void processType02(PacketParser.DataPacket packet,String ip,int port) {
         System.out.println("处理55AA02包: " + packet);
         // 实际业务逻辑
     }
diff --git a/src/udptcp/UDPPortAReceiver.java b/src/udptcp/UDPPortAReceiver.java
index fea5a80..29b5f97 100644
--- a/src/udptcp/UDPPortAReceiver.java
+++ b/src/udptcp/UDPPortAReceiver.java
@@ -33,17 +33,32 @@
 					socket.receive(packet);                    
 					executor.execute(() -> {
 						try {
-							String ip = packet.getAddress().getHostAddress();
-							int port = packet.getPort();
-							String hexData = bytesToHex(packet.getData(), packet.getLength());
+							 InetAddress address = packet.getAddress();
+						        if (address == null) {
+						            System.err.println("Received packet with null address");
+						            return;
+						        }
+						        
+						        String ip = address.getHostAddress();
+						        int port = packet.getPort();
+						        byte[] packetData = packet.getData();
+						        int length = packet.getLength();
+						        
+						        if (packetData == null || length <= 0) {
+						            System.err.println("Invalid packet data");
+						            return;
+						        }
+						        
+						        String hexData = bytesToHex(packetData, length);
 							// 调用时添加本地端口参数
 							PacketProcessingSystem.storePacket(ip, port, hexData);                            
 							// 报文查看窗口显示数据
-							MessageViewPanel.showData(hexData, ip, port, PORT,"1");
+							MessageViewPanel.showData(hexData, ip, port, PORT,"UDPA","ALL","ALL");
 							// +++ 增加包计数 +++
 							packetCount.incrementAndGet();  // 关键修复:增加计数器  
 						} catch (Exception e) {
-							System.err.println("Error processing UDP-A packet: " + e.getMessage());
+							System.err.println("Error processing UDP-A packet: ");
+					        e.printStackTrace(); // 添加详细堆栈跟踪
 						}
 					});
 				}
@@ -89,11 +104,12 @@
 	}
 
 	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();
+	    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) {
diff --git a/src/window/WelcomeFrame.java b/src/window/WelcomeFrame.java
index 1fa4cb4..8d081b6 100644
--- a/src/window/WelcomeFrame.java
+++ b/src/window/WelcomeFrame.java
@@ -6,7 +6,9 @@
 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;
diff --git a/systemfile/Messages_en.properties b/systemfile/Messages_en.properties
index d565c51..0ae7fd4 100644
--- a/systemfile/Messages_en.properties
+++ b/systemfile/Messages_en.properties
@@ -508,8 +508,8 @@
 MESSAGE_VIEW_START=Start
 MESSAGE_VIEW_PAUSE=Pause
 MESSAGE_VIEW_CLEAR=Clear
-MESSAGE_VIEW_DATA_TYPE=Data Type
-MESSAGE_VIEW_PROTOCOL=Protocol
+MESSAGE_VIEW_DATA_TYPE=DataFrom
+MESSAGE_VIEW_PROTOCOL=DataType
 MESSAGE_VIEW_DEVICE_ID=Device ID
 MESSAGE_VIEW_AUTO_SAVE=Auto Save Messages
 MESSAGE_VIEW_SHOW_SOURCE=Show Data Source
diff --git a/systemfile/Messages_zh.properties b/systemfile/Messages_zh.properties
index 891f3c5..2f3aebe 100644
--- a/systemfile/Messages_zh.properties
+++ b/systemfile/Messages_zh.properties
@@ -504,8 +504,8 @@
 MESSAGE_VIEW_START=寮�濮�
 MESSAGE_VIEW_PAUSE=鏆傚仠
 MESSAGE_VIEW_CLEAR=娓呯┖
-MESSAGE_VIEW_DATA_TYPE=鏁版嵁绫诲瀷
-MESSAGE_VIEW_PROTOCOL=閫氫俊鍗忚
+MESSAGE_VIEW_DATA_TYPE=鏁版嵁鏉ユ簮
+MESSAGE_VIEW_PROTOCOL=鏁版嵁绫诲瀷
 MESSAGE_VIEW_DEVICE_ID=璁惧缂栧彿
 MESSAGE_VIEW_AUTO_SAVE=鑷姩淇濆瓨鎶ユ枃
 MESSAGE_VIEW_SHOW_SOURCE=鏄剧ず鏁版嵁鏉ユ簮
diff --git a/systemfile/logfile/openlog.txt b/systemfile/logfile/openlog.txt
index f73e05b..9e68708 100644
--- a/systemfile/logfile/openlog.txt
+++ b/systemfile/logfile/openlog.txt
@@ -781,3 +781,140 @@
 工作时长: 0小时 0分钟 14秒
 -----------------------------------
 程序启动: 2025-08-09 23:30:58
+程序关闭: 2025-08-09 23:33:32
+工作时长: 0小时 2分钟 33秒
+-----------------------------------
+程序启动: 2025-08-10 08:58:27
+程序关闭: 2025-08-10 11:09:43
+工作时长: 2小时 11分钟 15秒
+-----------------------------------
+程序启动: 2025-08-10 11:09:46
+程序关闭: 2025-08-10 11:16:14
+工作时长: 0小时 6分钟 28秒
+-----------------------------------
+程序启动: 2025-08-10 11:16:16
+程序关闭: 2025-08-10 12:00:11
+工作时长: 0小时 43分钟 54秒
+-----------------------------------
+程序启动: 2025-08-10 12:00:13
+程序关闭: 2025-08-10 12:00:30
+工作时长: 0小时 0分钟 17秒
+-----------------------------------
+程序启动: 2025-08-10 12:22:41
+程序关闭: 2025-08-10 12:25:09
+工作时长: 0小时 2分钟 28秒
+-----------------------------------
+程序启动: 2025-08-10 12:25:12
+程序关闭: 2025-08-10 12:25:48
+工作时长: 0小时 0分钟 36秒
+-----------------------------------
+程序启动: 2025-08-10 12:26:10
+程序关闭: 2025-08-10 12:27:13
+工作时长: 0小时 1分钟 2秒
+-----------------------------------
+程序启动: 2025-08-10 12:30:34
+程序关闭: 2025-08-10 12:31:14
+工作时长: 0小时 0分钟 39秒
+-----------------------------------
+程序启动: 2025-08-10 12:51:17
+程序关闭: 2025-08-10 12:52:14
+工作时长: 0小时 0分钟 57秒
+-----------------------------------
+程序启动: 2025-08-10 12:53:36
+程序关闭: 2025-08-10 12:54:13
+工作时长: 0小时 0分钟 36秒
+-----------------------------------
+程序启动: 2025-08-10 12:54:42
+程序启动: 2025-08-10 12:57:55
+程序关闭: 2025-08-10 12:57:59
+工作时长: 0小时 0分钟 3秒
+-----------------------------------
+程序启动: 2025-08-10 12:58:01
+程序启动: 2025-08-10 13:19:31
+程序关闭: 2025-08-10 13:19:53
+工作时长: 0小时 0分钟 22秒
+-----------------------------------
+程序启动: 2025-08-10 13:19:55
+程序启动: 2025-08-10 13:21:35
+程序启动: 2025-08-10 13:25:06
+程序关闭: 2025-08-10 13:25:29
+工作时长: 0小时 0分钟 23秒
+-----------------------------------
+程序启动: 2025-08-10 13:43:51
+程序启动: 2025-08-10 13:49:02
+程序关闭: 2025-08-10 13:49:25
+工作时长: 0小时 0分钟 23秒
+-----------------------------------
+程序启动: 2025-08-10 13:52:37
+程序启动: 2025-08-10 13:53:36
+程序关闭: 2025-08-10 13:54:12
+工作时长: 0小时 0分钟 37秒
+-----------------------------------
+程序启动: 2025-08-10 20:39:09
+程序关闭: 2025-08-10 20:39:11
+工作时长: 0小时 0分钟 2秒
+-----------------------------------
+程序启动: 2025-08-10 20:43:09
+程序关闭: 2025-08-10 20:43:13
+工作时长: 0小时 0分钟 4秒
+-----------------------------------
+程序启动: 2025-08-10 21:07:32
+程序关闭: 2025-08-10 21:14:29
+工作时长: 0小时 6分钟 56秒
+-----------------------------------
+程序启动: 2025-08-10 21:14:32
+程序启动: 2025-08-10 21:19:29
+程序启动: 2025-08-10 21:24:40
+程序启动: 2025-08-10 21:34:00
+程序关闭: 2025-08-10 21:34:04
+工作时长: 0小时 9分钟 24秒
+-----------------------------------
+程序启动: 2025-08-10 21:34:06
+程序关闭: 2025-08-10 21:35:03
+工作时长: 0小时 0分钟 57秒
+-----------------------------------
+程序启动: 2025-08-10 21:35:36
+程序启动: 2025-08-10 21:40:50
+程序关闭: 2025-08-10 21:42:14
+工作时长: 0小时 1分钟 23秒
+-----------------------------------
+程序启动: 2025-08-10 21:59:52
+程序关闭: 2025-08-10 22:01:19
+工作时长: 0小时 1分钟 26秒
+-----------------------------------
+程序启动: 2025-08-10 22:02:38
+程序关闭: 2025-08-10 22:03:28
+工作时长: 0小时 0分钟 50秒
+-----------------------------------
+程序启动: 2025-08-10 22:05:44
+程序关闭: 2025-08-10 22:06:08
+工作时长: 0小时 0分钟 24秒
+-----------------------------------
+程序启动: 2025-08-10 22:07:11
+程序启动: 2025-08-10 22:19:11
+程序启动: 2025-08-10 22:23:07
+程序关闭: 2025-08-10 22:23:24
+工作时长: 0小时 0分钟 16秒
+-----------------------------------
+程序启动: 2025-08-10 22:23:34
+程序关闭: 2025-08-10 22:23:44
+工作时长: 0小时 0分钟 10秒
+-----------------------------------
+程序启动: 2025-08-10 22:26:52
+程序启动: 2025-08-10 22:59:33
+程序关闭: 2025-08-10 23:00:10
+工作时长: 0小时 0分钟 36秒
+-----------------------------------
+程序启动: 2025-08-10 23:01:09
+程序关闭: 2025-08-10 23:01:24
+工作时长: 0小时 0分钟 15秒
+-----------------------------------
+程序启动: 2025-08-10 23:01:56
+程序启动: 2025-08-10 23:03:00
+程序关闭: 2025-08-10 23:03:27
+工作时长: 0小时 0分钟 26秒
+-----------------------------------
+程序启动: 2025-08-10 23:04:06
+程序关闭: 2025-08-10 23:04:37
+工作时长: 0小时 0分钟 30秒
+-----------------------------------

--
Gitblit v1.9.3